[
  {
    "path": ".envrc",
    "content": "use_flake\n\n# Remove git-minimal from PATH to keep system git\nPATH_rm '/nix/store/*git-minimal*/bin'\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "content": "# Scala Steward: Reformat with scalafmt 3.7.2\nedcec351367976c77a5a5ce2842804232e6f7ca5\n\n# Scala Steward: Reformat with scalafmt 3.7.3\nd300efb67187b7bfbd1c6f0f04fe181d4373c749\n\n# Scala Steward: Reformat with scalafmt 3.7.4\n99666671f20427ffb9b330a3a7ef3d7941d10ad5\n\n# Scala Steward: Reformat with scalafmt 3.8.6\n18b438352adfcb8c4aba3cac4c74b783ba28c775\n\n# Scala Steward: Reformat with scalafmt 3.9.1\n2150c0a1bfc30f7b4f587a58e74cf92f30d894ac\n\n# Scala Steward: Reformat with scalafmt 3.9.4\nfe9b58b7ac2be9ea7dc14c7e1b1b025679b728f4\n"
  },
  {
    "path": ".gitattributes",
    "content": "*                           text=auto\n.git*                       text export-ignore\n\n*.sbt                       text\n*.scala                     text\n*.java                      text\n*.txt                       text\n\n.classpath                 -text whitespace=cr-at-eol merge=union\n*.md                        text conflict-marker-size=200\n*.xml                      -text whitespace=cr-at-eol\n\n*.sh        text eol=lf\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "* @pshirshov @neko-kai\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: 7mind # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: 7mind # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: ['https://www.buymeacoffee.com/7mind'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\n\non:\n  workflow_dispatch:\n    inputs: {}\n  push:\n    branches: [ \"develop\" ]\n    tags: [ \"v**\" ]\n  pull_request:\n    branches: [ \"develop\" ]\n\njobs:\n  checksecret:\n    runs-on: ubuntu-latest\n    outputs:\n      HAVE_SECRETS: ${{ steps.checksecret_job.outputs.HAVE_SECRETS }}\n    steps:\n      - id: checksecret_job\n        env:\n          OPENSSL_IV: ${{ secrets.OPENSSL_IV }}\n          OPENSSL_KEY: ${{ secrets.OPENSSL_KEY }}\n        run: |\n          echo \"HAVE_SECRETS=${{ env.OPENSSL_IV != '' && env.OPENSSL_KEY != '' }}\" >> $GITHUB_OUTPUT\n\n  build:\n    runs-on: ubuntu-latest\n    needs: [ 'checksecret' ]\n    permissions:\n      checks: write\n      contents: write\n    strategy:\n      fail-fast: false\n      matrix:\n        java: [ '11', '17', '21' ]\n        scala: [ '2.11', '2.12', '2.13', '3' ]\n    steps:\n      - uses: 7mind/github-env@minimal\n      - name: Build and Test\n        env:\n          CI_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}\n          CI_BRANCH: ${{ github.ref_name }}\n          CI_BRANCH_TAG: ${{ github.ref_name }}\n        run: nix develop --command mdl -u java_version:${{ matrix.java }} -u scala_version:${{ matrix.scala }} --github-actions :gen :test\n      - uses: dorny/test-reporter@v1\n        if: (needs.checksecret.outputs.HAVE_SECRETS == 'true') && (success() || failure())\n        with:\n          name: Test reports (JDK ${{ matrix.java }}, Scala ${{ matrix.scala }})\n          path: '**/target/test-reports/TEST-*.xml'\n          reporter: java-junit\n      - uses: sbt/setup-sbt@v1 # setup sbt\n      - name: Upload dependency graph\n        if: needs.checksecret.outputs.HAVE_SECRETS == 'true'\n        uses: scalacenter/sbt-dependency-submission@53544c3e7bf54b0cb7f375f016e5b7446b96b706\n\n  publish-artifacts:\n    runs-on: ubuntu-latest\n    needs: [ 'build', 'checksecret' ]\n    if: needs.checksecret.outputs.HAVE_SECRETS == 'true'\n    strategy:\n      matrix:\n        java: [ '17' ]\n        scala: [ '2.13' ]\n    steps:\n      - uses: 7mind/github-env@minimal\n      - name: Build and Publish to Sonatype\n        env:\n          OPENSSL_IV: ${{ secrets.OPENSSL_IV }}\n          OPENSSL_KEY: ${{ secrets.OPENSSL_KEY }}\n          SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}\n          SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}\n          CI_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}\n          CI_BRANCH: ${{ github.ref_name }}\n          CI_BRANCH_TAG: ${{ github.ref_name }}\n        run: |\n          openssl aes-256-cbc -K ${OPENSSL_KEY} -iv ${OPENSSL_IV} -in secrets.tar.enc -out secrets.tar -d\n          tar xvf secrets.tar\n          ln -s .secrets/local.sbt local.sbt\n          rm ./.secrets/credentials.sonatype-nexus.properties\n          printf \"%s\\n\" \"realm=Sonatype Nexus Repository Manager\" \"host=central.sonatype.com\" \"user=${SONATYPE_USERNAME}\" \"password=${SONATYPE_PASSWORD}\" > ./.secrets/credentials.sonatype-nexus.properties\n          nix develop --command mdl -u java_version:${{ matrix.java }} -u scala_version:${{ matrix.scala }} --github-actions :gen :publish-scala\n\n  release-and-notify-docs:\n    name: Release and Notify Docs\n    runs-on: ubuntu-latest\n    continue-on-error: false\n    needs: [ 'build', 'checksecret' ]\n    if: needs.checksecret.outputs.HAVE_SECRETS == 'true'\n    #if: ${{ ((github.event_name == 'release') && (github.event.action == 'published')) || (github.event_name == 'workflow_dispatch') }}\n    strategy:\n      matrix:\n        java: [ '17' ]\n        scala: [ '2.13' ]\n    steps:\n      - uses: 7mind/github-env@minimal\n      - name: Publish Docs to NPM Registry\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          CI_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}\n          CI_BRANCH: ${{ github.ref_name }}\n          CI_BRANCH_TAG: ${{ github.ref_name }}\n        run: nix develop --command mdl -u java_version:${{ matrix.java }} -u scala_version:${{ matrix.scala }} --github-actions :gen :publish-ziodocs\n      - name: Notify the main repo about the new release of docs package\n        run: |\n          PACKAGE_NAME=$(cat docs/package.json | grep '\"name\"' | awk -F'\"' '{print $4}')\n          PACKAGE_VERSION=$(npm view $PACKAGE_NAME version)\n          curl -L \\\n            -X POST \\\n            -H \"Accept: application/vnd.github+json\" \\\n            -H \"Authorization: token ${{ secrets.PAT_TOKEN }}\"\\\n              https://api.github.com/repos/zio/zio/dispatches \\\n              -d '{\n                    \"event_type\":\"update-docs\",\n                    \"client_payload\":{\n                      \"package_name\":\"'\"${PACKAGE_NAME}\"'\",\n                      \"package_version\": \"'\"${PACKAGE_VERSION}\"'\"\n                    }\n                  }'\n\n  all-good:\n    if: always()\n    runs-on: ubuntu-latest\n    needs: [ 'build' ]\n    steps:\n      - name: Decide whether the needed jobs succeeded or failed\n        uses: re-actors/alls-green@release/v1\n        with:\n          jobs: ${{ toJSON(needs) }}\n"
  },
  {
    "path": ".gitignore",
    "content": ".mdl/runs/\n.env\n.direnv\n.hydra\n.idea\n*.jps\n/local.sbt\n.secrets*\n/config\n.agg\n.bsp\nproject/project/project\nproject/project/metals.sbt\n\n# we cannot exclude build.sbt - scala steward wouldn't work without it\n#build.sbt\n#project/plugins.sbt\n#project/build.properties\n\nsecrets.tar\nbuild/project\n.DS_Store\n.metals\nproject/metals.sbt\n.bloop\n.java-version\n\n# Created by .ignore support plugin (hsz.mobi)\n### Scala template\n*.class\n*.log\n### JetBrains template\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff:\n.idea/**/workspace.xml\n.idea/**/tasks.xml\n.idea/dictionaries\n\n# Sensitive or high-churn files:\n.idea/**/dataSources/\n.idea/**/dataSources.ids\n.idea/**/dataSources.xml\n.idea/**/dataSources.local.xml\n.idea/**/sqlDataSources.xml\n.idea/**/dynamic.xml\n.idea/**/uiDesigner.xml\n\n# Gradle:\n.idea/**/gradle.xml\n.idea/**/libraries\n\n# CMake\ncmake-build-debug/\n\n# Mongo Explorer plugin:\n.idea/**/mongoSettings.xml\n\n## File-based project format:\n*.iws\n\n## Plugin-specific files:\n\n# IntelliJ\nout/\n*.iml\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n### SBT template\n# Simple Build Tool\n# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control\n\ndist/*\ntarget/\nlib_managed/\nsrc_managed/\nproject/boot/\nproject/plugins/project/\n.history\n.cache\n.lib/\n### Java template\n# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n.vscode\n"
  },
  {
    "path": ".jvmopts",
    "content": "\n# toggle debug output\n#-Dizumi.reflect.debug.macro.rtti=true\n#-Dizumi.reflect.debug.macro.rtti=false\n\n# toggle debug assertions\n#-Dizumi.reflect.debug.macro.rtti.assertions=true\n#-Dizumi.reflect.debug.macro.rtti.assertions=false\n\n-Xmx8G\n-XX:ReservedCodeCacheSize=256m\n-XX:MaxMetaspaceSize=3G\n\n-XX:+OmitStackTraceInFastThrow\n-XX:SoftRefLRUPolicyMSPerMB=50\n-Dsun.io.useCanonCaches=false\n-server\n\n#-Xshare:on\n\n#-Xshare:dump\n#-Xlog:class+load=info\n\n-XX:+UseG1GC\n\n# Enable ZGC\n#-XX:+UnlockExperimentalVMOptions\n#-XX:+UseZGC\n\n# Enable Graal JIT\n#-XX:+UnlockExperimentalVMOptions\n#-XX:+EnableJVMCI\n#-XX:+UseJVMCICompiler\n\n# Bumping JIT inline-level increases performance of Scala code\n#   https://www.reddit.com/r/scala/comments/cigh0t/these_go_to_eighteen_c_jon_pretty/\n#   https://scalacenter.github.io/bloop/docs/performance-guide#tweak-the-java-jit\n#   https://twitter.com/leifwickland/status/1179419045055086595\n-XX:MaxInlineLevel=18\n# These seem to cause sbt import slowdown :\\\n#-XX:MaxInlineSize=270\n#-XX:MaxTrivialSize=12\n"
  },
  {
    "path": ".mdl/defs/actions.md",
    "content": "# Build Actions\n\n## Environment\n\n- `LANG=C.UTF-8`\n\n## passthrough\n- `HOME`\n- `USER`\n- `OPENSSL_IV`\n- `OPENSSL_KEY`\n- `SONATYPE_USERNAME`\n- `SONATYPE_PASSWORD`\n- `NODE_AUTH_TOKEN`\n- `CI_BRANCH_TAG`\n- `CI_BUILD_UNIQ_SUFFIX`\n- `CI_PULL_REQUEST`\n- `CI_BRANCH`\n\n# Axis\n\n- `java_version`=`{11|17*|21}`\n- `scala_version`=`{2.12|2.13*|3}`\n\n# action: setup-jdk\n\nSetup JDK path based on JAVA_VERSION\n\n```bash\nJAVA_VERSION_VAL=${sys.axis.java_version}\n\n# Determine JAVA_HOME based on JDK version from nix flake environment\n# These are set by flake.nix shellHook\ncase \"$JAVA_VERSION_VAL\" in\n  11)\n    if [[ -n \"${JDK11:-}\" ]]; then\n      JAVA_HOME=\"$JDK11\"\n    else\n      echo \"Error: JDK11 not set in environment\" && exit 1\n    fi\n    ;;\n  17)\n    if [[ -n \"${JDK17:-}\" ]]; then\n      JAVA_HOME=\"$JDK17\"\n    else\n      echo \"Error: JDK17 not set in environment\" && exit 1\n    fi\n    ;;\n  21)\n    if [[ -n \"${JDK21:-}\" ]]; then\n      JAVA_HOME=\"$JDK21\"\n    else\n      echo \"Error: JDK21 not set in environment\" && exit 1\n    fi\n    ;;\n  *)\n    echo \"Unsupported JAVA_VERSION: $JAVA_VERSION_VAL\" && exit 1\n    ;;\nesac\n\nJAVA_BIN=\"$JAVA_HOME/bin\"\nPATH=\"$JAVA_BIN:$PATH\"\n\nret java-home:String=\"$JAVA_HOME\"\nret path:String=\"$PATH\"\n```\n\n# action: setup-jvm-options\n\nSetup JVM options and optimizations\n\n```bash\nJAVA_OPTIONS=\"${_JAVA_OPTIONS:-}\"\n\n# Add user.home for nix environments\nUSER_HOME=\"${env.HOME}\"\nJAVA_OPTIONS+=\" -Duser.home=$USER_HOME\"\n\n# Append any custom tail options (optional)\nif [[ -n \"${JAVA_OPTIONS_TAIL:-}\" ]]; then\n  JAVA_OPTIONS+=\" $JAVA_OPTIONS_TAIL\"\nfi\n\n# Add optimizations\nJAVA_OPTIONS+=\" -Xmx4000M\"\nJAVA_OPTIONS+=\" -XX:ReservedCodeCacheSize=384M\"\nJAVA_OPTIONS+=\" -XX:NonProfiledCodeHeapSize=256M\"\nJAVA_OPTIONS+=\" -XX:MaxMetaspaceSize=1024M\"\n\n# Normalize whitespace\nJAVA_OPTIONS=$(echo \"$JAVA_OPTIONS\" | tr '\\n' ' ' | tr -s ' ')\n\nret java-options:String=\"$JAVA_OPTIONS\"\n```\n\n# action: setup-scala\n\nSetup Scala version variables\n\n```bash\nSCALA_VERSION_VAL=${sys.axis.scala_version}\n\nVERSION_COMMAND=\"++ $SCALA_VERSION_VAL\"\n\nret version-command:String=\"$VERSION_COMMAND\"\n```\n\n# action: check-sbtgen-staleness\n\nDecide whether sbt build files need regeneration\n\n```bash\nPROJECT_ROOT=\"${sys.project-root}\"\n\nreadonly SBTGEN_INPUTS=(\n  \"$PROJECT_ROOT/sbtgen.sc\"\n  \"$PROJECT_ROOT/project/Deps.sc\"\n  \"$PROJECT_ROOT/project/Settings.scala\"\n  \"$PROJECT_ROOT/project/Versions.scala\"\n  \"$PROJECT_ROOT/project/project/PluginVersions.scala\"\n)\n\nreadonly GENERATED_SBT_FILES=(\n  \"$PROJECT_ROOT/build.sbt\"\n  \"$PROJECT_ROOT/project/plugins.sbt\"\n)\n\nreadonly EPOCH_START=0\n\nfor input_file in \"${SBTGEN_INPUTS[@]}\"; do\n  if [[ ! -f \"$input_file\" ]]; then\n    echo \"Missing sbtgen input: $input_file\"\n    exit 1\n  fi\ndone\n\nfor generated_file in \"${GENERATED_SBT_FILES[@]}\"; do\n  if [[ ! -f \"$generated_file\" ]]; then\n    retain\n    exit 0\n  fi\ndone\n\nnewest_input_mtime=\"$EPOCH_START\"\nfor input_file in \"${SBTGEN_INPUTS[@]}\"; do\n  modified_at=$(stat -c %Y \"$input_file\")\n  if (( modified_at > newest_input_mtime )); then\n    newest_input_mtime=\"$modified_at\"\n  fi\ndone\n\noldest_generated_mtime=$(stat -c %Y \"${GENERATED_SBT_FILES[0]}\")\nfor generated_file in \"${GENERATED_SBT_FILES[@]:1}\"; do\n  modified_at=$(stat -c %Y \"$generated_file\")\n  if (( modified_at < oldest_generated_mtime )); then\n    oldest_generated_mtime=\"$modified_at\"\n  fi\ndone\n\nif (( newest_input_mtime > oldest_generated_mtime )); then\n  retain\nfi\n```\n\n# action: gen\n\nGenerate build files using sbtgen\n\n```bash\n# Depend on all setup actions\nJAVA_HOME=\"${action.setup-jdk.java-home}\"\nPATH=\"${action.setup-jdk.path}\"\nJAVA_OPTIONS=\"${action.setup-jvm-options.java-options}\"\n_JAVA_OPTIONS=\"$JAVA_OPTIONS\"\n\nbash sbtgen.sc --js --native\n```\n\n# action: test\n\nRun tests and binary compatibility checks\n\n```bash\n# Declare dependencies and use their outputs\nsoft action.gen retain.action.check-sbtgen-staleness\n\nJAVA_HOME=\"${action.setup-jdk.java-home}\"\nPATH=\"${action.setup-jdk.path}\"\nJAVA_OPTIONS=\"${action.setup-jvm-options.java-options}\"\n_JAVA_OPTIONS=\"$JAVA_OPTIONS\"\nVERSION_COMMAND=\"${action.setup-scala.version-command}\"\n\nsbt -batch -no-colors -v \\\n  --java-home \"$JAVA_HOME\" \\\n  \"$VERSION_COMMAND clean\" \\\n  \"$VERSION_COMMAND Test/compile\" \\\n  \"$VERSION_COMMAND test\" \\\n  \"$VERSION_COMMAND mimaReportBinaryIssues\"\n```\n\n# action: publish-scala\n\nPublish Scala artifacts to Sonatype (only on release branches/tags)\n\n## vars\n- `CI_PULL_REQUEST`\n- `CI_BRANCH`\n\n```bash\n# Declare dependencies and use their outputs\nsoft action.gen\n\nJAVA_HOME=\"${action.setup-jdk.java-home}\"\nPATH=\"${action.setup-jdk.path}\"\nJAVA_OPTIONS=\"${action.setup-jvm-options.java-options}\"\n_JAVA_OPTIONS=\"$JAVA_OPTIONS\"\n\n# Get environment variables from mudyla substitution\nSONATYPE_USERNAME_VAL=\"${env.SONATYPE_USERNAME}\"\nSONATYPE_PASSWORD_VAL=\"${env.SONATYPE_PASSWORD}\"\nCI_PULL_REQUEST_VAL=\"${env.CI_PULL_REQUEST}\"\nCI_BRANCH_VAL=\"${env.CI_BRANCH}\"\nCI_BRANCH_TAG_VAL=\"${env.CI_BRANCH_TAG}\"\n\n# Apply bash defaults\nSONATYPE_USERNAME=\"${SONATYPE_USERNAME_VAL}\"\nSONATYPE_PASSWORD=\"${SONATYPE_PASSWORD_VAL}\"\nCI_PULL_REQUEST=\"${CI_PULL_REQUEST_VAL:-false}\"\nCI_BRANCH=\"${CI_BRANCH_VAL}\"\nCI_BRANCH_TAG=\"${CI_BRANCH_TAG_VAL}\"\n\nif [[ -z \"$SONATYPE_USERNAME\" ]]; then\n    echo \"Missing SONATYPE_USERNAME, skipping publish\"\n    exit 0\nfi\n\nif [[ -z \"$SONATYPE_PASSWORD\" ]]; then\n    echo \"Missing SONATYPE_PASSWORD, skipping publish\"\n    exit 0\nfi\n\nif [[ \"$CI_PULL_REQUEST\" == \"true\" ]]; then\n    echo \"Publishing not allowed on P/Rs\"\n    exit 0\nfi\n\nif [[ \"$CI_BRANCH\" != \"develop\" && ! \"$CI_BRANCH_TAG\" =~ ^v ]]; then\n    echo \"Publishing not allowed (CI_BRANCH=$CI_BRANCH, CI_BRANCH_TAG=$CI_BRANCH_TAG)\"\n    exit 0\nfi\n\nif [[ \"$CI_BRANCH_TAG\" =~ ^v.*$ ]]; then\n    # Full release with sonaRelease\n    sbt -batch -no-colors -v \\\n        --java-home \"$JAVA_HOME\" \\\n        \"show credentials\" \\\n        \"+clean\" \\\n        \"+test:compile\" \\\n        \"+publishSigned\" \\\n        \"sonaRelease\"\nelse\n    # Snapshot publish without release\n    sbt -batch -no-colors -v \\\n        --java-home \"$JAVA_HOME\" \\\n        \"show credentials\" \\\n        \"+clean\" \\\n        \"+test:compile\" \\\n        \"+publishSigned\"\nfi\n```\n\n# action: publish-ziodocs\n\nPublish documentation to NPM\n\n## vars\n- `CI_PULL_REQUEST`\n- `CI_BRANCH`\n\n```bash\n# Declare dependencies and use their outputs\nsoft action.gen\n\nJAVA_HOME=\"${action.setup-jdk.java-home}\"\nPATH=\"${action.setup-jdk.path}\"\nJAVA_OPTIONS=\"${action.setup-jvm-options.java-options}\"\n_JAVA_OPTIONS=\"$JAVA_OPTIONS\"\n\n# Get environment variables from mudyla substitution\nNODE_AUTH_TOKEN_VAL=\"${env.NODE_AUTH_TOKEN}\"\nCI_PULL_REQUEST_VAL=\"${env.CI_PULL_REQUEST}\"\nCI_BRANCH_VAL=\"${env.CI_BRANCH}\"\nCI_BRANCH_TAG_VAL=\"${env.CI_BRANCH_TAG}\"\n\n# Apply bash defaults\nNODE_AUTH_TOKEN=\"${NODE_AUTH_TOKEN_VAL}\"\nCI_PULL_REQUEST=\"${CI_PULL_REQUEST_VAL:-false}\"\nCI_BRANCH=\"${CI_BRANCH_VAL}\"\nCI_BRANCH_TAG=\"${CI_BRANCH_TAG_VAL}\"\n\nif [[ -z \"$NODE_AUTH_TOKEN\" ]]; then\n    echo \"Missing NODE_AUTH_TOKEN, skipping docs publish\"\n    exit 0\nfi\n\nif [[ \"$CI_PULL_REQUEST\" == \"true\" ]]; then\n    echo \"Publishing not allowed on P/Rs\"\n    exit 0\nfi\n\nif [[ \"$CI_BRANCH\" != \"develop\" && ! \"$CI_BRANCH_TAG\" =~ ^v ]]; then\n    echo \"Publishing not allowed (CI_BRANCH=$CI_BRANCH, CI_BRANCH_TAG=$CI_BRANCH_TAG)\"\n    exit 0\nfi\n\n# Copy zio-docs.sbt\ncp ${sys.project-root}/.mdl/resources/zio-docs.sbt ${sys.project-root}/zio-docs.sbt\n\n# Extract docs section from README and append to docs/index.md\nawk '/<!--- docs:start --->/,/<!--- docs:end --->/' ${sys.project-root}/README.md >> ${sys.project-root}/docs/index.md\nsed -i '/<!--- docs:start --->/d' ${sys.project-root}/docs/index.md\nsed -i '/<!--- docs:end --->/d' ${sys.project-root}/docs/index.md\n\n# Setup npm auth\necho \"//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN\" > ~/.npmrc\n\n# Verify npm authentication\nnpm whoami\n\n# Publish to npm\nsbt -batch -no-colors -v \\\n    --java-home \"$JAVA_HOME\" \\\n    docs/publishToNpm\n```\n\n# action: build\n\nFull build pipeline - generate and test\n\n```bash\nsoft action.gen retain.action.check-sbtgen-staleness\ndep action.test\nexit 0\n```\n"
  },
  {
    "path": ".mdl/resources/zio-docs.sbt",
    "content": "lazy val docs = project\n  .in(file(\"izumi-reflect-docs\"))\n  .settings(\n    publish / skip := true,\n    moduleName := \"izumi-reflect-docs\",\n    scalacOptions -= \"-Yno-imports\",\n    scalacOptions -= \"-Xfatal-warnings\",\n    projectName := \"izumi-reflect\",\n    mainModuleName                             := \"izumi-reflect\",\n    projectStage                               := ProjectStage.ProductionReady,\n  )\n  .enablePlugins(WebsitePlugin)"
  },
  {
    "path": ".scala-steward.conf",
    "content": "updates.pin  = [\n  # do not update Scala 2.13 because of revoked forward compatibility\n  { groupId = \"org.scala-lang\", artifactId=\"scala-compiler\", version = \"2.13.14\" },\n  { groupId = \"org.scala-lang\", artifactId=\"scala-library\", version = \"2.13.14\" },\n  { groupId = \"org.scala-lang\", artifactId=\"scala-reflect\", version = \"2.13.14\" },\n  # use only Scala3 3.3 LTS\n  { groupId = \"org.scala-lang\", artifactId=\"scala3-compiler\", version = \"3.3.\" },\n  { groupId = \"org.scala-lang\", artifactId=\"scala3-library\", version = \"3.3.\" },\n  { groupId = \"org.scala-lang\", artifactId=\"scala3-library_sjs1\", version = \"3.3.\" }\n]\n\npullRequests.frequency = \"@monthly\"\n\npullRequests.grouping = [\n  # group scala updates & scoverage\n  { name=\"scala-versions\", \"title\"=\"Scala compiler updates\", \"filter\"=[{\"group\" = \"org.scala-lang\"}, {\"group\" = \"org.scoverage\"}] },\n  # group everything else\n  { name = \"all\", \"title\" = \"Dependency updates\", \"filter\" = [{\"group\" = \"*\"}] }\n]\n\nupdatePullRequests = \"always\"\n"
  },
  {
    "path": ".scalafmt.conf",
    "content": "version = \"3.9.4\"\nrunner.dialect = scala3\nproject.git = true\nproject.excludePaths = [\"glob:**.sbt\", \"glob:**sbtgen.sc\"]\n\nmaxColumn = 170\n\nimportSelectors = singleLine\nspaces.inImportCurlyBraces = false\n\nliterals.hexDigits = \"Upper\"\n\nalign.preset = none\nalign.stripMargin = true\nalign.inInterpolation = false\n\nnewlines.beforeCurlyLambdaParams = multiline\nnewlines.afterCurlyLambdaParams = never\nnewlines.implicitParamListModifierPrefer = after\nnewlines.avoidAfterYield = true\nnewlines.alwaysBeforeMultilineDef = false\nnewlines.inInterpolation = allow\n\nindent.defnSite = 2\nindent.callSite = 2\nindent.extendSite = 2\n\nassumeStandardLibraryStripMargin = true\ndocstrings = ScalaDoc\ndocstrings.wrap = false\ndocstrings.blankFirstLine = keep\ndocstrings.forceBlankLineBefore = false\nlineEndings = unix\n\ndanglingParentheses.callSite = true\ndanglingParentheses.defnSite = true\ndanglingParentheses.ctrlSite = false\ndanglingParentheses.exclude = []\nverticalAlignMultilineOperators = true\n\nincludeCurlyBraceInSelectChains = true\nincludeNoParensInSelectChains = true\n\nverticalMultiline.atDefnSite = true\nverticalMultiline.arityThreshold = 100\nverticalMultiline.newlineAfterOpenParen = false\n\noptIn.configStyleArguments = true\noptIn.breaksInsideChains = true\noptIn.breakChainOnFirstMethodDot = true\noptIn.selfAnnotationNewline = true\noptIn.annotationNewlines = true\n\nrewrite.rules = [AsciiSortImports, RedundantBraces, RedundantParens]\nrewrite.redundantBraces.methodBodies = false // remove braces only in interpolations\nrewrite.redundantBraces.maxLines = -1 // remove braces only in interpolations\nrewrite.redundantBraces.generalExpressions = false // remove braces only in interpolations\nrewrite.redundantBraces.includeUnitMethods = false\nrewrite.redundantBraces.stringInterpolation = true\nrewrite.redundantBraces.parensForOneLineApply = true\n\n//rewrite.trailingCommas.trailingCommas = multiple\nrewrite.trailingCommas.style = never // Scala 2.11\n"
  },
  {
    "path": "CLA.md",
    "content": "# ZIO Contributor License Agreement\n\nThank you for your interest in contributing to the ZIO open source project.\n\nThis contributor agreement (\"Agreement\") describes the terms and conditions under which you may Submit a Contribution to Us. By Submitting a Contribution to Us, you accept the terms and conditions in the Agreement. If you do not accept the terms and conditions in the Agreement, you must not Submit any Contribution to Us.\n\nThis is a legally binding document, so please read it carefully before accepting the terms and conditions. If you accept this Agreement, the then-current version of this Agreement shall apply each time you Submit a Contribution. The Agreement may cover more than one software project managed by Us.\n\n## 1. Definitions\n\n\"We\" or \"Us\" means Ziverge, Inc., and its duly appointed and authorized representatives.\n\n\"You\" means the individual or entity who Submits a Contribution to Us.\n\n\"Contribution\" means any work of authorship that is Submitted by You to Us in which You own or assert ownership of the Copyright. You may not Submit a Contribution if you do not own the Copyright in the entire work of authorship.\n\n\"Copyright\" means all rights protecting works of authorship owned or controlled by You, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence including any extensions by You.\n\n\"Material\" means the work of authorship which is made available by Us to third parties. When this Agreement covers more than one software project, the Material means the work of authorship to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material.\n\n\"Submit\" means any form of electronic, verbal, or written communication sent to Us or our representatives, including but not limited to electronic mailing lists, electronic mail, source code control systems, pull requests, and issue tracking systems that are managed by, or on behalf of, Us for the purpose of discussing and improving the Material, but excluding communication that is conspicuously marked or otherwise designated in writing by You as \"Not a Contribution.\"\n\n\"Submission Date\" means the date on which You Submit a Contribution to Us.\n\n\"Effective Date\" means the earliest date You execute this Agreement by Submitting a Contribution to Us.\n\n## 2. Grant of Rights\n\n### 2.1 Copyright License\n\n2.1.1. You retain ownership of the Copyright in Your Contribution and have the same rights to use or license the Contribution which You would have had without entering into the Agreement.\n\n2.1.2. To the maximum extent permitted by the relevant law, You grant to Us a perpetual, worldwide, non-exclusive, transferable, royalty-free, irrevocable license under the Copyright covering the Contribution, with the right to sublicense such rights through multiple tiers of sublicensees, to reproduce, modify, display, perform and distribute the Contribution as part of the Material; provided that this license is conditioned upon compliance with Section 2.3.\n\n### 2.2 Patent License\n\nFor patent claims including, without limitation, method, process, and apparatus claims which You own, control or have the right to grant, now or in the future, You grant to Us a perpetual, worldwide, non-exclusive, transferable, royalty-free, irrevocable patent license, with the right to sublicense these rights to multiple tiers of sublicensees, to make, have made, use, sell, offer for sale, import and otherwise transfer the Contribution and the Contribution in combination with the Material (and portions of such combination). This license is granted only to the extent that the exercise of the licensed rights infringes such patent claims; and provided that this license is conditioned upon compliance with Section 2.3.\n\n### 2.3 Outbound License\n\nBased on the grant of rights in Sections 2.1 and 2.2, if We include Your Contribution in a Material, We may license the Contribution under any license, including copyleft, permissive, commercial, or proprietary licenses. As a condition on the exercise of this right, We agree to also license the Contribution under the terms of the license or licenses which We are using for the Material on the Submission Date.\n\n### 2.4 Moral Rights\n\nIf moral rights apply to the Contribution, to the maximum extent permitted by law, You waive and agree not to assert such moral rights against Us or our successors in interest, or any of our licensees, either direct or indirect.\n\n### 2.5 Our Rights\n\nYou acknowledge that We are not obligated to use Your Contribution as part of the Material and may decide to include any Contribution We consider appropriate.\n\n### 2.6 Reservation of Rights\n\nAny rights not expressly licensed under this section are expressly reserved by You.\n\n## 3. Agreement\n\nYou confirm that:\n\na. You have the legal authority to enter into this Agreement.\n\nb. You own the Copyright and patent claims covering the Contribution which are required to grant the rights under Section 2.\n\nc. The grant of rights under Section 2 does not violate any grant of rights which You have made to third parties, including Your employer. If You are an employee, You have had Your employer approve this Agreement or sign the Entity version of this document. If You are less than eighteen years old, please have Your parents or guardian sign the Agreement.\n\nd. You have followed the instructions in, if You do not own the Copyright in the entire work of authorship Submitted.\n\n## 4. Disclaimer\n\nEXCEPT FOR THE EXPRESS WARRANTIES IN SECTION 3, THE CONTRIBUTION IS PROVIDED \"AS IS\". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD PERMITTED BY LAW.\n\n## 5. Consequential Damage Waiver\n\nTO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED.\n\n## 6. Miscellaneous\n\n6.1. This Agreement will be governed by and construed in accordance with the laws of the state of Maryland, in the United States of America, excluding its conflicts of law provisions. Under certain circumstances, the governing law in this section might be superseded by the United Nations Convention on Contracts for the International Sale of Goods (\"UN Convention\") and the parties intend to avoid the application of the UN Convention to this Agreement and, thus, exclude the application of the UN Convention in its entirety to this Agreement.\n\n6.2. This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings.\n\n6.3. If You or We assign the rights or obligations received through this Agreement to a third party, as a condition of the assignment, that third party must agree in writing to abide by all the rights and obligations in the Agreement.\n\n6.4. The failure of either party to require performance by the other party of any provision of this Agreement in one situation shall not affect the right of a party to require such performance at any time in the future. A waiver of performance under a provision in one situation shall not be considered a waiver of the performance of the provision in the future or a waiver of the provision in its entirety.\n\n6.5. If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and which is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law.\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "**IMPORTANT** All the conversations must be done in Irish.\nThey will be reviewed by Irish speakers who doesn't speak English very well!\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at pshirshov@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "LICENSE",
    "content": "Licensed under the Apache License, Version 2.0 (the \"License\");\nYou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
  },
  {
    "path": "README.md",
    "content": "[![Project stage][Stage]][Stage-Page]\n[![Build](https://github.com/zio/izumi-reflect/workflows/Build/badge.svg)](https://github.com/zio/izumi-reflect/actions/workflows/build.yml)\n[![javadoc](https://javadoc.io/badge2/dev.zio/izumi-reflect_2.13/javadoc.svg)](https://javadoc.io/doc/dev.zio/izumi-reflect_2.13)\n[![Latest Release](https://img.shields.io/github/tag/zio/izumi-reflect.svg)](https://github.com/zio/izumi-reflect/releases)\n[![Maven Central](https://img.shields.io/maven-central/v/dev.zio/izumi-reflect_2.13.svg)](https://search.maven.org/search?q=g%3Adev.zio+a%3Aizumi-reflect)\n[![Latest version](https://index.scala-lang.org/zio/izumi-reflect/latest.svg?color=orange)](https://index.scala-lang.org/zio/izumi-reflect)\n\n---\n\n<p align=\"center\">\n  Please consider supporting our work through <a href=\"https://github.com/sponsors/7mind\">GitHub Sponsors</a>.\n</p>\n<p align=\"center\">\n  <a href=\"https://www.buymeacoffee.com/7mind\"><img src=\"https://bmc-cdn.nyc3.digitaloceanspaces.com/BMC-button-images/custom_images/orange_img.png\" alt=\"Izumi\"/></a>\n</p>\n\n---\n\n<!--- docs:start --->\n\n# izumi-reflect\n\n> @quote: Looks a bit similar to TypeTag\n\n`izumi-reflect` is a fast, lightweight, portable and efficient alternative for `TypeTag` from `scala-reflect`.\n\n`izumi-reflect` is a lightweight model of Scala type system and provides a simulator of the important parts of the Scala typechecker.\n\n## Why `izumi-reflect`\n\n1. `izumi-reflect` compiles faster, runs a lot faster than `scala-reflect` and is fully immutable and [thread-safe](https://github.com/scala/bug/issues/10766),\n2. `izumi-reflect` supports Scala 2.11, 2.12, 2.13 and **Scala 3**,\n3. `izumi-reflect` supports Scala.js and Scala Native,\n4. `izumi-reflect` works well with [GraalVM Native Image](https://www.graalvm.org/reference-manual/native-image/),\n5. `izumi-reflect` allows you to obtain tags for unapplied type constructors (`F[_]`) and combine them at runtime.\n\n## Credits\n\n`izumi-reflect` has been created by [Septimal Mind](https://7mind.io) to power [Izumi Project](https://github.com/7mind/izumi),\nas a replacement for `TypeTag` in reaction to a lack of confirmed information about the future of `scala-reflect`/`TypeTag` in Scala 3 ([Motivation](https://blog.7mind.io/lightweight-reflection.html)), and donated to ZIO.\n\n<p align=\"center\">\n  <a href=\"https://izumi.7mind.io/\">\n  <img width=\"40%\" src=\"https://github.com/7mind/izumi/blob/develop/doc/microsite/src/main/tut/media/izumi-logo-full-purple.png?raw=true\" alt=\"Izumi\"/>\n  </a>\n</p>\n\n\n## Limitations\n\n`izumi-reflect` model of the Scala type system is not 100% precise, but \"good enough\" for the vast majority of the usecases.\n\nKnown limitations are:\n\n1. Recursive type bounds (F-bounded types) are not preserved and may produce false positives,\n2. Existential types, both written with wildcards and `forSome` may produce unexpected results, the support is limited,\n3. Path-Dependent Types are based on variable names and may cause unexpected results when variables with different names have the same type or vice-versa (vs. Scala compiler)\n4. This-Types such as `X.this.type` are ignored and identical to `X`\n5. `izumi-reflect` is less powerful than `scala-reflect`: it does not preserve fields and methods when it's not necessary for equality and subtype checks, it does not preserve code trees, internal compiler data structures, etc.\n6. There are some optimizations in place which reduce correctness, namely: subtype check for `scala.Matchable` will always return true, no distinction is made between `scala.Any` and `scala.AnyRef`,  no distinction is made between `scala.Nothing` and `scala.Null`. In other words, the library does not recognize that `Null` is not a subtype of `AnyVal`s.\n7. Lower bounds are not preserved in abstract higher-kinded type members which may produce false comparisons.\n8. Type and value members are not preserved in concrete types which may produce false comparisons with refined/structural types. (https://github.com/zio/izumi-reflect/issues/481)\n\n## Debugging\n\nSet [`-Dizumi.reflect.debug.macro.rtti=true`](https://javadoc.io/doc/dev.zio/izumi-reflect_2.13/latest/izumi/reflect/DebugProperties$.html#izumi.reflect.debug.macro.rtti:String(%22izumi.reflect.debug.macro.rtti%22)) to enable debug output during compilation when tags are constructed and at runtime when they are compared.\n\n```shell\nsbt -Dizumi.reflect.debug.macro.rtti=true\n```\n\nTo see debug output when compiling in Intellij, add the above flag to `VM options` in [Preferences -> Build, Execution, Deployment -> Compiler -> Scala Compiler -> Scala Compile Server](jetbrains://idea/settings?name=Build%2C+Execution%2C+Deployment--Compiler--Scala+Compiler--Scala+Compile+Server)\n\nYou may also set it in `.jvmopts` file during development. (`.jvmopts` properties will not apply to Intellij compile server, only to sbt)\n\nSet `-Dizumi.reflect.debug.macro.rtti.assertions=true` to enable additional assertions.\n\nOther useful system properties are:\n\n- [`izumi.reflect.rtti.optimized.equals`](https://javadoc.io/doc/dev.zio/izumi-reflect_2.13/latest/izumi/reflect/DebugProperties$.html#izumi.reflect.rtti.optimized.equals:String(%22izumi.reflect.rtti.optimized.equals%22))\n- [`izumi.reflect.rtti.cache.compile`](https://javadoc.io/doc/dev.zio/izumi-reflect_2.13/latest/izumi/reflect/DebugProperties$.html#izumi.reflect.rtti.cache.compile:String(%22izumi.reflect.rtti.cache.compile%22))\n\n<!--- docs:end --->\n\n## Build\n\n`build.sbt` is generated by [sbtgen](https://github.com/7mind/sbtgen). During development you may not want to mess with ScalaJS and ScalaNative, you may generate a pure-JVM Scala project:\n\n```bash\n./sbtgen.sc\n```\n\nOnce you finished tinkering with the code you may want to generate full project and test it for all the platforms:\n\n```bash\n./sbtgen.sc --js --native\nsbt +test\n```\n\nTo develop using Scala 2 invoke sbtgen with a scala version argument:\n\n```bash\n./sbtgen.sc 2 // 2.13\n./sbtgen.sc 2.12 // 2.12\n```\n\nLikewise with Scala 3:\n\n```bash\n./sbtgen.sc 3\n```\n\nIn Intellij, you may also set Scala version by changing the option `sbt -> sbt settings -> Open cross-compiled projects Scala 3 / Scala 2 projects as:`\n\nProvided `flake.nix` can be used to set up the external dependencies necessary to build the project, such as sbt, JDK, coursier, etc:\n\n```bash\nnix develop\n```\n\nThe project's CI is built with [mudyla](https://github.com/7mind/mudyla), you may reproduce CI build locally with:\n\n```bash\nnix develop --command mdl --github-actions :gen :test\n```\n\nAvailable mudyla actions are defined in [.mdl/defs/*.md](.mdl/defs/)\n\n<!--- docs:start --->\n\n# Talks\n\n* [Kit Langton — Scala 3 Macro Fun (Open Source Hackery)](https://www.youtube.com/watch?v=wsLhjqCKZuU)\n* [Pavel Shirshov — Izumi Reflect: Scala Type System Model](https://www.youtube.com/watch?v=ShRfzVz58OY)\n\n# See also\n\n## [`gzoller/scala-reflection`](https://github.com/gzoller/scala-reflection)\n\n* Scala 3 only\n* No support for subtype checks\n* Type lambdas are not supported\n* _Preserves field information_\n\n## [`airframe-surface`](https://wvlet.org/airframe/docs/airframe-surface)\n\n* Scala 2 and Scala 3\n* No support for subtype checks\n* _Preserves field information_\n\n## And even more\n\n1. https://github.com/gaeljw/typetrees - a very basic type tag substitute for Scala 3\n2. https://stackoverflow.com/questions/75752812/is-there-a-simple-scala-3-example-of-how-to-use-quoted-type-as-replacement-for - discussion on StackOverflow\n3. https://contributors.scala-lang.org/t/scala-3-and-reflection/3627 - original discussion on Scala Contributors forum\n\n[Stage]: https://img.shields.io/badge/Project%20Stage-Production%20Ready-brightgreen.svg\n[Stage-Page]: https://github.com/zio/zio/wiki/Project-Stages\n\n<!--- docs:end --->\n"
  },
  {
    "path": "build.sbt",
    "content": "// DO NOT EDIT THIS FILE\n// IT IS AUTOGENERATED BY `sbtgen.sc` SCRIPT\n// ALL CHANGES WILL BE LOST\n\n\nimport sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}\n\nimport com.typesafe.tools.mima.core._\n\nenablePlugins(SbtgenVerificationPlugin)\n\nlazy val `izumi-reflect-thirdparty-boopickle-shaded` = crossProject(JVMPlatform, JSPlatform, NativePlatform).crossType(CrossType.Pure).in(file(\"izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded\"))\n  .settings(\n    libraryDependencies ++= Seq(\n      \"org.scalatest\" %%% \"scalatest\" % V.scalatest % Test\n    ),\n    libraryDependencies ++= { if (scalaVersion.value.startsWith(\"2.\")) Seq(\n      compilerPlugin(\"org.typelevel\" % \"kind-projector\" % V.kind_projector cross CrossVersion.full),\n      \"org.scala-lang\" % \"scala-reflect\" % scalaVersion.value % Provided\n    ) else Seq.empty },\n    libraryDependencies ++= {\n      val version = scalaVersion.value\n      if (version.startsWith(\"0.\") || version.startsWith(\"3.\")) {\n        Seq(\n          \"org.scala-lang\" %% \"scala3-compiler\" % scalaVersion.value % Provided\n        )\n      } else Seq.empty\n    }\n  )\n  .settings(\n    organization := \"dev.zio\",\n    Compile / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ <= CrossVersion.partialVersion(version)).flatten\n      (Compile / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => ltEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n+\") }\n        case _ => Seq.empty\n      }\n    },\n    Test / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ <= CrossVersion.partialVersion(version)).flatten\n      (Test / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => ltEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n+\") }\n        case _ => Seq.empty\n      }\n    },\n    Compile / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val gtEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ >= CrossVersion.partialVersion(version)).flatten\n      (Compile / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => gtEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n-\") }\n        case _ => Seq.empty\n      }\n    },\n    Test / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val gtEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ >= CrossVersion.partialVersion(version)).flatten\n      (Test / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => gtEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n-\") }\n        case _ => Seq.empty\n      }\n    },\n    Compile / unmanagedSourceDirectories ++= {\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).sorted.flatten\n      def joinV = (_: Product).productIterator.mkString(\".\")\n      val allRangeVersions = (2 to math.max(2, ltEqVersions.size))\n        .flatMap(i => ltEqVersions.sliding(i).filter(_.size == i))\n        .map(l => (l.head, l.last))\n        .distinct\n      CrossVersion.partialVersion(scalaVersion.value).toList.flatMap {\n        version =>\n          val rangeVersions = allRangeVersions\n            .filter { case (l, r) => l <= version && version <= r }\n            .map { case (l, r) => s\"-${joinV(l)}-${joinV(r)}\" }\n          (Compile / unmanagedSourceDirectories).value.flatMap {\n            case dir if dir.getPath.endsWith(\"scala\") => rangeVersions.map { vStr => file(dir.getPath + vStr) }\n            case _ => Seq.empty\n          }\n      }\n    },\n    Test / unmanagedSourceDirectories ++= {\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).sorted.flatten\n      def joinV = (_: Product).productIterator.mkString(\".\")\n      val allRangeVersions = (2 to math.max(2, ltEqVersions.size))\n        .flatMap(i => ltEqVersions.sliding(i).filter(_.size == i))\n        .map(l => (l.head, l.last))\n        .distinct\n      CrossVersion.partialVersion(scalaVersion.value).toList.flatMap {\n        version =>\n          val rangeVersions = allRangeVersions\n            .filter { case (l, r) => l <= version && version <= r }\n            .map { case (l, r) => s\"-${joinV(l)}-${joinV(r)}\" }\n          (Test / unmanagedSourceDirectories).value.flatMap {\n            case dir if dir.getPath.endsWith(\"scala\") => rangeVersions.map { vStr => file(dir.getPath + vStr) }\n            case _ => Seq.empty\n          }\n      }\n    },\n    Compile / doc / sources := { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"3.3.6\") => Seq(\n      \n      )\n      case (_, _) => (Compile / doc / sources).value\n    } },\n    Test / testOptions += Tests.Argument(\"-oDF\"),\n    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"2.11.12\") => Seq.empty\n      case (_, \"2.12.20\") => Seq(\n        \"-release:8\",\n        \"-explaintypes\",\n        \"-Ypartial-unification\",\n        if (insideCI.value) \"-Wconf:any:error\" else \"-Wconf:any:warning\",\n        \"-Wconf:cat=optimizer:warning\",\n        \"-Wconf:cat=other-match-analysis:error\",\n        \"-Ybackend-parallelism\",\n        math.min(16, math.max(1, sys.runtime.availableProcessors() - 1)).toString,\n        \"-Xlint:adapted-args\",\n        \"-Xlint:by-name-right-associative\",\n        \"-Xlint:constant\",\n        \"-Xlint:delayedinit-select\",\n        \"-Xlint:doc-detached\",\n        \"-Xlint:inaccessible\",\n        \"-Xlint:infer-any\",\n        \"-Xlint:missing-interpolator\",\n        \"-Xlint:nullary-override\",\n        \"-Xlint:nullary-unit\",\n        \"-Xlint:option-implicit\",\n        \"-Xlint:package-object-classes\",\n        \"-Xlint:poly-implicit-overload\",\n        \"-Xlint:private-shadow\",\n        \"-Xlint:stars-align\",\n        \"-Xlint:type-parameter-shadow\",\n        \"-Xlint:unsound-match\",\n        \"-opt-warnings:_\",\n        \"-Ywarn-extra-implicit\",\n        \"-Ywarn-unused:_\",\n        \"-Ywarn-adapted-args\",\n        \"-Ywarn-dead-code\",\n        \"-Ywarn-inaccessible\",\n        \"-Ywarn-infer-any\",\n        \"-Ywarn-nullary-override\",\n        \"-Ywarn-nullary-unit\",\n        \"-Ywarn-numeric-widen\",\n        \"-Ywarn-unused-import\",\n        \"-Ywarn-value-discard\",\n        \"-Ycache-plugin-class-loader:always\",\n        \"-Ycache-macro-class-loader:last-modified\",\n        \"-Wconf:msg=nowarn:silent\"\n      )\n      case (_, \"2.13.14\") => Seq(\n        \"-release:8\",\n        \"-explaintypes\",\n        if (insideCI.value) \"-Wconf:any:error\" else \"-Wconf:any:warning\",\n        \"-Wconf:cat=optimizer:warning\",\n        \"-Wconf:cat=other-match-analysis:error\",\n        \"-Vtype-diffs\",\n        \"-Ybackend-parallelism\",\n        math.min(16, math.max(1, sys.runtime.availableProcessors() - 1)).toString,\n        \"-Wdead-code\",\n        \"-Wextra-implicit\",\n        \"-Wnumeric-widen\",\n        \"-Woctal-literal\",\n        \"-Wvalue-discard\",\n        \"-Wunused:_\",\n        \"-Wmacros:default\",\n        \"-Ycache-plugin-class-loader:always\",\n        \"-Ycache-macro-class-loader:last-modified\",\n        \"-Wconf:msg=nowarn:silent\"\n      )\n      case (_, _) => Seq(\n        \"-Ykind-projector\",\n        \"-no-indent\",\n        \"-language:implicitConversions\"\n      )\n    } },\n    scalacOptions -= \"-Wconf:any:error\",\n    mimaPreviousArtifacts := { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"3.3.6\") => Set(organization.value %% name.value % \"2.2.5\", organization.value %% name.value % \"2.1.0\")\n      case (_, _) => Set(organization.value %% name.value % \"2.2.5\", organization.value %% name.value % \"2.1.0\", organization.value %% name.value % \"1.0.0\")\n    } },\n    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"2.13.14\") => Seq(\n        \"-Xlint:-implicit-recursion\"\n      )\n      case (_, _) => Seq.empty\n    } },\n    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {\n      case (false, \"2.12.20\") => Seq(\n        \"-opt:l:inline\",\n        \"-opt-inline-from:izumi.reflect.**\"\n      )\n      case (false, \"2.13.14\") => Seq(\n        \"-opt:l:inline\",\n        \"-opt-inline-from:izumi.reflect.**\"\n      )\n      case (_, _) => Seq.empty\n    } },\n    Compile / packageBin / packageOptions += Package.ManifestAttributes(\"Automatic-Module-Name\" -> s\"${organization.value.replaceAll(\"-\",\".\")}.${moduleName.value.replaceAll(\"-\",\".\")}\"),\n    Compile / scalacOptions --= Seq(\"-Ywarn-value-discard\",\"-Ywarn-unused:_\", \"-Wvalue-discard\", \"-Wunused:_\")\n  )\n  .jvmSettings(\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\",\n      \"2.11.12\"\n    ),\n    scalaVersion := crossScalaVersions.value.head\n  )\n  .jsSettings(\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\"\n    ),\n    scalaVersion := crossScalaVersions.value.head,\n    coverageEnabled := false,\n    scalaJSLinkerConfig := scalaJSLinkerConfig.value.withModuleKind(ModuleKind.CommonJSModule)\n  )\n  .nativeSettings(\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\"\n    ),\n    scalaVersion := crossScalaVersions.value.head,\n    coverageEnabled := false,\n    test := {},\n    Test / test := {}\n  )\nlazy val `izumi-reflect-thirdparty-boopickle-shadedJVM` = `izumi-reflect-thirdparty-boopickle-shaded`.jvm\nlazy val `izumi-reflect-thirdparty-boopickle-shadedJS` = `izumi-reflect-thirdparty-boopickle-shaded`.js\nlazy val `izumi-reflect-thirdparty-boopickle-shadedNative` = `izumi-reflect-thirdparty-boopickle-shaded`.native\n\nlazy val `izumi-reflect` = crossProject(JVMPlatform, JSPlatform, NativePlatform).crossType(CrossType.Pure).in(file(\"izumi-reflect/izumi-reflect\"))\n  .dependsOn(\n    `izumi-reflect-thirdparty-boopickle-shaded` % \"test->compile;compile->compile\"\n  )\n  .settings(\n    libraryDependencies ++= Seq(\n      \"org.scalatest\" %%% \"scalatest\" % V.scalatest % Test\n    ),\n    libraryDependencies ++= { if (scalaVersion.value.startsWith(\"2.\")) Seq(\n      compilerPlugin(\"org.typelevel\" % \"kind-projector\" % V.kind_projector cross CrossVersion.full),\n      \"org.scala-lang\" % \"scala-reflect\" % scalaVersion.value % Provided\n    ) else Seq.empty },\n    libraryDependencies ++= {\n      val version = scalaVersion.value\n      if (version.startsWith(\"0.\") || version.startsWith(\"3.\")) {\n        Seq(\n          \"org.scala-lang\" %% \"scala3-compiler\" % scalaVersion.value % Provided\n        )\n      } else Seq.empty\n    }\n  )\n  .settings(\n    organization := \"dev.zio\",\n    Compile / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ <= CrossVersion.partialVersion(version)).flatten\n      (Compile / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => ltEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n+\") }\n        case _ => Seq.empty\n      }\n    },\n    Test / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ <= CrossVersion.partialVersion(version)).flatten\n      (Test / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => ltEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n+\") }\n        case _ => Seq.empty\n      }\n    },\n    Compile / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val gtEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ >= CrossVersion.partialVersion(version)).flatten\n      (Compile / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => gtEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n-\") }\n        case _ => Seq.empty\n      }\n    },\n    Test / unmanagedSourceDirectories ++= {\n      val version = scalaVersion.value\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val gtEqVersions = crossVersions.map(CrossVersion.partialVersion).filter(_ >= CrossVersion.partialVersion(version)).flatten\n      (Test / unmanagedSourceDirectories).value.flatMap {\n        case dir if dir.getPath.endsWith(\"scala\") => gtEqVersions.map { case (m, n) => file(dir.getPath + s\"-$m.$n-\") }\n        case _ => Seq.empty\n      }\n    },\n    Compile / unmanagedSourceDirectories ++= {\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).sorted.flatten\n      def joinV = (_: Product).productIterator.mkString(\".\")\n      val allRangeVersions = (2 to math.max(2, ltEqVersions.size))\n        .flatMap(i => ltEqVersions.sliding(i).filter(_.size == i))\n        .map(l => (l.head, l.last))\n        .distinct\n      CrossVersion.partialVersion(scalaVersion.value).toList.flatMap {\n        version =>\n          val rangeVersions = allRangeVersions\n            .filter { case (l, r) => l <= version && version <= r }\n            .map { case (l, r) => s\"-${joinV(l)}-${joinV(r)}\" }\n          (Compile / unmanagedSourceDirectories).value.flatMap {\n            case dir if dir.getPath.endsWith(\"scala\") => rangeVersions.map { vStr => file(dir.getPath + vStr) }\n            case _ => Seq.empty\n          }\n      }\n    },\n    Test / unmanagedSourceDirectories ++= {\n      val crossVersions = crossScalaVersions.value\n      import Ordering.Implicits._\n      val ltEqVersions = crossVersions.map(CrossVersion.partialVersion).sorted.flatten\n      def joinV = (_: Product).productIterator.mkString(\".\")\n      val allRangeVersions = (2 to math.max(2, ltEqVersions.size))\n        .flatMap(i => ltEqVersions.sliding(i).filter(_.size == i))\n        .map(l => (l.head, l.last))\n        .distinct\n      CrossVersion.partialVersion(scalaVersion.value).toList.flatMap {\n        version =>\n          val rangeVersions = allRangeVersions\n            .filter { case (l, r) => l <= version && version <= r }\n            .map { case (l, r) => s\"-${joinV(l)}-${joinV(r)}\" }\n          (Test / unmanagedSourceDirectories).value.flatMap {\n            case dir if dir.getPath.endsWith(\"scala\") => rangeVersions.map { vStr => file(dir.getPath + vStr) }\n            case _ => Seq.empty\n          }\n      }\n    },\n    Compile / doc / sources := { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"3.3.6\") => Seq(\n      \n      )\n      case (_, _) => (Compile / doc / sources).value\n    } },\n    Test / testOptions += Tests.Argument(\"-oDF\"),\n    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"2.11.12\") => Seq.empty\n      case (_, \"2.12.20\") => Seq(\n        \"-release:8\",\n        \"-explaintypes\",\n        \"-Ypartial-unification\",\n        if (insideCI.value) \"-Wconf:any:error\" else \"-Wconf:any:warning\",\n        \"-Wconf:cat=optimizer:warning\",\n        \"-Wconf:cat=other-match-analysis:error\",\n        \"-Ybackend-parallelism\",\n        math.min(16, math.max(1, sys.runtime.availableProcessors() - 1)).toString,\n        \"-Xlint:adapted-args\",\n        \"-Xlint:by-name-right-associative\",\n        \"-Xlint:constant\",\n        \"-Xlint:delayedinit-select\",\n        \"-Xlint:doc-detached\",\n        \"-Xlint:inaccessible\",\n        \"-Xlint:infer-any\",\n        \"-Xlint:missing-interpolator\",\n        \"-Xlint:nullary-override\",\n        \"-Xlint:nullary-unit\",\n        \"-Xlint:option-implicit\",\n        \"-Xlint:package-object-classes\",\n        \"-Xlint:poly-implicit-overload\",\n        \"-Xlint:private-shadow\",\n        \"-Xlint:stars-align\",\n        \"-Xlint:type-parameter-shadow\",\n        \"-Xlint:unsound-match\",\n        \"-opt-warnings:_\",\n        \"-Ywarn-extra-implicit\",\n        \"-Ywarn-unused:_\",\n        \"-Ywarn-adapted-args\",\n        \"-Ywarn-dead-code\",\n        \"-Ywarn-inaccessible\",\n        \"-Ywarn-infer-any\",\n        \"-Ywarn-nullary-override\",\n        \"-Ywarn-nullary-unit\",\n        \"-Ywarn-numeric-widen\",\n        \"-Ywarn-unused-import\",\n        \"-Ywarn-value-discard\",\n        \"-Ycache-plugin-class-loader:always\",\n        \"-Ycache-macro-class-loader:last-modified\",\n        \"-Wconf:msg=nowarn:silent\"\n      )\n      case (_, \"2.13.14\") => Seq(\n        \"-release:8\",\n        \"-explaintypes\",\n        if (insideCI.value) \"-Wconf:any:error\" else \"-Wconf:any:warning\",\n        \"-Wconf:cat=optimizer:warning\",\n        \"-Wconf:cat=other-match-analysis:error\",\n        \"-Vtype-diffs\",\n        \"-Ybackend-parallelism\",\n        math.min(16, math.max(1, sys.runtime.availableProcessors() - 1)).toString,\n        \"-Wdead-code\",\n        \"-Wextra-implicit\",\n        \"-Wnumeric-widen\",\n        \"-Woctal-literal\",\n        \"-Wvalue-discard\",\n        \"-Wunused:_\",\n        \"-Wmacros:default\",\n        \"-Ycache-plugin-class-loader:always\",\n        \"-Ycache-macro-class-loader:last-modified\",\n        \"-Wconf:msg=nowarn:silent\"\n      )\n      case (_, _) => Seq(\n        \"-Ykind-projector\",\n        \"-no-indent\",\n        \"-language:implicitConversions\"\n      )\n    } },\n    scalacOptions -= \"-Wconf:any:error\",\n    mimaPreviousArtifacts := { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"3.3.6\") => Set(organization.value %% name.value % \"2.2.5\", organization.value %% name.value % \"2.1.0\")\n      case (_, _) => Set(organization.value %% name.value % \"2.2.5\", organization.value %% name.value % \"2.1.0\", organization.value %% name.value % \"1.0.0\")\n    } },\n    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {\n      case (_, \"2.13.14\") => Seq(\n        \"-Xlint:-implicit-recursion\"\n      )\n      case (_, _) => Seq.empty\n    } },\n    scalacOptions ++= { (isSnapshot.value, scalaVersion.value) match {\n      case (false, \"2.12.20\") => Seq(\n        \"-opt:l:inline\",\n        \"-opt-inline-from:izumi.reflect.**\"\n      )\n      case (false, \"2.13.14\") => Seq(\n        \"-opt:l:inline\",\n        \"-opt-inline-from:izumi.reflect.**\"\n      )\n      case (_, _) => Seq.empty\n    } },\n    Compile / packageBin / packageOptions += Package.ManifestAttributes(\"Automatic-Module-Name\" -> s\"${organization.value.replaceAll(\"-\",\".\")}.${moduleName.value.replaceAll(\"-\",\".\")}\")\n  )\n  .jvmSettings(\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\",\n      \"2.11.12\"\n    ),\n    scalaVersion := crossScalaVersions.value.head\n  )\n  .jsSettings(\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\"\n    ),\n    scalaVersion := crossScalaVersions.value.head,\n    coverageEnabled := false,\n    scalaJSLinkerConfig := scalaJSLinkerConfig.value.withModuleKind(ModuleKind.CommonJSModule)\n  )\n  .nativeSettings(\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\"\n    ),\n    scalaVersion := crossScalaVersions.value.head,\n    coverageEnabled := false,\n    test := {},\n    Test / test := {}\n  )\nlazy val `izumi-reflectJVM` = `izumi-reflect`.jvm\nlazy val `izumi-reflectJS` = `izumi-reflect`.js\nlazy val `izumi-reflectNative` = `izumi-reflect`.native\n\nlazy val `izumi-reflect-aggregate` = (project in file(\".agg/izumi-reflect-izumi-reflect-aggregate\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Nil\n  )\n  .aggregate(\n    `izumi-reflect-thirdparty-boopickle-shadedJVM`,\n    `izumi-reflect-thirdparty-boopickle-shadedJS`,\n    `izumi-reflect-thirdparty-boopickle-shadedNative`,\n    `izumi-reflectJVM`,\n    `izumi-reflectJS`,\n    `izumi-reflectNative`\n  )\n\nlazy val `izumi-reflect-aggregate-jvm` = (project in file(\".agg/izumi-reflect-izumi-reflect-aggregate-jvm\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Nil\n  )\n  .aggregate(\n    `izumi-reflect-thirdparty-boopickle-shadedJVM`,\n    `izumi-reflectJVM`\n  )\n\nlazy val `izumi-reflect-aggregate-js` = (project in file(\".agg/izumi-reflect-izumi-reflect-aggregate-js\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Nil\n  )\n  .aggregate(\n    `izumi-reflect-thirdparty-boopickle-shadedJS`,\n    `izumi-reflectJS`\n  )\n\nlazy val `izumi-reflect-aggregate-native` = (project in file(\".agg/izumi-reflect-izumi-reflect-aggregate-native\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Nil\n  )\n  .aggregate(\n    `izumi-reflect-thirdparty-boopickle-shadedNative`,\n    `izumi-reflectNative`\n  )\n\nlazy val `izumi-reflect-root-jvm` = (project in file(\".agg/.agg-jvm\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\",\n      \"2.11.12\"\n    ),\n    scalaVersion := crossScalaVersions.value.head\n  )\n  .aggregate(\n    `izumi-reflect-aggregate-jvm`\n  )\n\nlazy val `izumi-reflect-root-js` = (project in file(\".agg/.agg-js\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\",\n      \"2.11.12\"\n    ),\n    scalaVersion := crossScalaVersions.value.head\n  )\n  .aggregate(\n    `izumi-reflect-aggregate-js`\n  )\n\nlazy val `izumi-reflect-root-native` = (project in file(\".agg/.agg-native\"))\n  .settings(\n    publish / skip := true,\n    crossScalaVersions := Seq(\n      \"3.3.6\",\n      \"2.13.14\",\n      \"2.12.20\",\n      \"2.11.12\"\n    ),\n    scalaVersion := crossScalaVersions.value.head\n  )\n  .aggregate(\n    `izumi-reflect-aggregate-native`\n  )\n\nlazy val `izumi-reflect-root` = (project in file(\".\"))\n  .settings(\n    publish / skip := true,\n    Global / onChangedBuildSource := ReloadOnSourceChanges,\n    ThisBuild / publishMavenStyle := true,\n    ThisBuild / scalacOptions ++= Seq(\n      \"-encoding\",\n      \"UTF-8\",\n      \"-feature\",\n      \"-unchecked\",\n      \"-deprecation\",\n      \"-language:higherKinds\"\n    ),\n    ThisBuild / javacOptions ++= Seq(\n      \"-encoding\",\n      \"UTF-8\",\n      \"-source\",\n      \"1.8\",\n      \"-target\",\n      \"1.8\",\n      \"-deprecation\",\n      \"-parameters\",\n      \"-Xlint:all\",\n      \"-XDignore.symbol.file\"\n    ),\n    crossScalaVersions := Nil,\n    ThisBuild / organization := \"dev.zio\",\n    ThisBuild / publishTo := {\n      if (isSnapshot.value) {\n        Some(\n          \"central-snapshots\" at \"https://central.sonatype.com/repository/maven-snapshots/\"\n        )\n      } else {\n        localStaging.value\n      }\n    },\n    ThisBuild / credentials ++= \n    {\n    Seq(\n      Path.userHome / \".sbt\" / \"secrets\" / \"credentials.sonatype-zio-new.properties\",\n      file(\".\") / \".secrets\" / \"credentials.sonatype-nexus.properties\"\n    )\n      .filter(_.exists())\n      .map(Credentials.apply)\n    },\n    ThisBuild / homepage := Some(url(\"https://zio.dev\")),\n    ThisBuild / licenses := Seq(\"Apache-2.0\" -> url(\"http://www.apache.org/licenses/LICENSE-2.0\")),\n    ThisBuild / developers := List(\n              Developer(id = \"jdegoes\", name = \"John De Goes\", url = url(\"http://degoes.net\"), email = \"john@degoes.net\"),\n              Developer(id = \"7mind\", name = \"Septimal Mind\", url = url(\"https://github.com/7mind\"), email = \"team@7mind.io\"),\n            ),\n    ThisBuild / scmInfo := Some(ScmInfo(url(\"https://github.com/zio/izumi-reflect\"), \"scm:git:https://github.com/zio/izumi-reflect.git\")),\n    ThisBuild / mimaBinaryIssueFilters ++= Seq(\n      ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTag\"),\n      ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTag110\"),\n      ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTag210\"),\n      ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTagM8\"),\n      ProblemFilters.exclude[IncompatibleResultTypeProblem](\"izumi.reflect.macrortti.LightTypeTagRef#FullReference._1\"),\n      ProblemFilters.exclude[InheritedNewAbstractMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef*\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LTTRenderables.r_LambdaParameterName\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTag.binaryFormatVersion\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.repr\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LTTRenderables.r_Wildcard\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LTTRenderables.prefixSplitter\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.longNameWithPrefix\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.longNameInternalSymbol\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef#AppliedNamedReference.symName\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef#AppliedNamedReference.prefix\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.scalaStyledName\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.scalaStyledRepr\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.AnyTag.=:=\"),\n      ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.AnyTag.<:<\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.TagMacro.*\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.macrortti.LightTypeTagImpl.*\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.macrortti.LightTypeTagImpl#*\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.dottyreflection.*\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.thirdparty.*\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.internal.*\"),\n      ProblemFilters.exclude[Problem](\"izumi.reflect.ReflectionUtil*\"),\n      ProblemFilters.exclude[DirectMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagImpl.norm\"),\n      ProblemFilters.exclude[DirectMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagImpl.izumi$reflect$macrortti$LightTypeTagImpl$$*\"),\n      ProblemFilters.exclude[DirectMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagInheritance.CtxExt\"),\n      ProblemFilters.exclude[MissingFieldProblem](\"izumi.reflect.macrortti.LightTypeTagInheritance.CtxExt\"),\n      ProblemFilters.exclude[FinalClassProblem](\"izumi.reflect.macrortti.LightTypeTagInheritance$CtxExt\"),\n      ProblemFilters.exclude[MissingTypesProblem]       (\"izumi.reflect.macrortti.LightTypeTagInheritance$Ctx*\"),\n      ProblemFilters.exclude[Problem]                   (\"izumi.reflect.macrortti.LightTypeTagInheritance#Ctx*\"),\n      ProblemFilters.exclude[Problem]                   (\"izumi.reflect.macrortti.LightTypeTagUnpacker*\")\n    ),\n    ThisBuild / mimaFailOnProblem := true,\n    ThisBuild / mimaFailOnNoPrevious := false,\n    ThisBuild / useGpg := false,\n    libraryDependencies += \"io.7mind.izumi.sbt\" % \"sbtgen_2.13\" % \"0.0.107\" % Provided\n  )\n  .aggregate(\n    `izumi-reflect-aggregate`\n  )\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\nid: index\ntitle: \"Introduction to izumi-reflect\"\nsidebar_label: \"izumi-reflect\"\n---\n\n@PROJECT_BADGES@\n\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"name\": \"@zio.dev/izumi-reflect\",\n  \"description\": \"izumi-reflect Documentation\",\n  \"license\": \"Apache-2.0\"\n}\n"
  },
  {
    "path": "docs/sidebars.js",
    "content": "const sidebars = {\n  sidebar: [\n    {\n      type: \"category\",\n      label: \"Izumi Reflect\",\n      collapsed: false,\n      link: { type: \"doc\", id: \"index\" },\n      items: [ ]\n    }\n  ]\n};\n\nmodule.exports = sidebars;\n"
  },
  {
    "path": "flake.nix",
    "content": "{\n  description = \"izumi-reflect build environment\";\n\n  inputs.nixpkgs.url = \"github:NixOS/nixpkgs/25.11\";\n\n  inputs.flake-utils.url = \"github:numtide/flake-utils\";\n\n  inputs.mudyla.url = \"github:7mind/mudyla\";\n  inputs.mudyla.inputs.nixpkgs.follows = \"nixpkgs\";\n\n  outputs =\n    { self\n    , nixpkgs\n    , flake-utils\n    , mudyla\n    }:\n    flake-utils.lib.eachDefaultSystem (\n      system:\n      let\n          pkgs = import nixpkgs {\n            inherit system;\n            config.allowUnfree = true;\n          };\n      in\n      {\n        devShells.default = pkgs.mkShell {\n          nativeBuildInputs = with pkgs.buildPackages; [\n            ncurses\n\n            coursier\n            sbt\n\n            nodejs\n            nodePackages.npm\n\n            gitMinimal\n            gnupg\n\n            mudyla.packages.${system}.default\n          ];\n\n          shellHook = ''\n            export JDK11=${pkgs.jdk11_headless}\n            export JDK17=${pkgs.jdk17_headless}\n            export JDK21=${pkgs.jdk21_headless}\n            export JDK_DEV=${pkgs.graalvmPackages.graalvm-ce}\n\n            # Create .env directory with JDK symlink (ignore errors if already exists)\n            mkdir -p ./.env 2>/dev/null || true\n            rm -f ./.env/jdk 2>/dev/null || true\n            ln -sf ''${JDK_DEV} ./.env/jdk 2>/dev/null || true\n          '';\n        };\n      }\n    );\n}\n"
  },
  {
    "path": "fmt-all",
    "content": "#!/usr/bin/env sh\n\ncs launch scalafmt -- $@\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/.js/src/test/scala-2/izumi/reflect/test/PlatformSpecific.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.macrortti.{LTag, LightTypeTag}\n\nobject PlatformSpecific {\n  def fromRuntime[T: LTag]: LightTypeTag = LTag[T].tag\n  def fromRuntime[T: LTag](loud: Boolean): LightTypeTag = LTag[T].tag\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/.jvm/src/test/scala-2/izumi/reflect/test/AllPartsStrongTestScala2Jvm.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.ReflectionUtil\nimport izumi.reflect.test.DiscoveryModel.{DiscoverableService, DiscoverableServiceImpl, DiscoveryNodeProvider, GetDiscoveryNode}\nimport org.scalatest.wordspec.AnyWordSpec\n\nclass AllPartsStrongTestScala2Jvm extends AnyWordSpec {\n\n  type FP1[+T] = List[T]\n  type Ap1[+F[+_], +T] = F[T]\n  type FP[+T] = FP1[T]\n\n  trait C {\n    type A\n  }\n\n  \"allPartsStrong for Identity typelambda\" in {\n    val res1 = ReflectionUtil.allPartsStrong(scala.reflect.runtime.universe.typeOf[ID.id[C]].typeConstructor)\n    assert(res1)\n  }\n\n  \"allPartsStrong for eta-expansion typelambda\" in {\n    val res1 = ReflectionUtil.allPartsStrong(scala.reflect.runtime.universe.typeOf[FP1[C]].typeConstructor)\n    assert(res1)\n  }\n\n  \"allPartsStrong for application typelambda\" in {\n    val tpe = scala.reflect.runtime.universe.typeOf[Ap1[List, Int]].typeConstructor\n    val res1 = ReflectionUtil.allPartsStrong(tpe)\n    assert(res1)\n  }\n\n  \"allPartsStrong for anonymous application typelambda\" in {\n    val tpe = scala\n      .reflect.runtime.universe.weakTypeOf[{ type l[F[_], A] = F[A] }]\n      .asInstanceOf[scala.reflect.runtime.universe.RefinedTypeApi].decl(scala.reflect.runtime.universe.TypeName(\"l\"))\n      .asType.typeSignature\n      .typeConstructor\n    val res1 = ReflectionUtil.allPartsStrong(tpe)\n    assert(res1)\n  }\n\n  \"allPartsStrong for x.F[x.Id] typelambda\" in {\n    val res1 = ReflectionUtil.allPartsStrong { object x { type F[_[_]]; type Id[A] = A }; scala.reflect.runtime.universe.weakTypeOf[x.F[x.Id]] }\n    assert(res1)\n  }\n\n  \"allPartsStrong is false for TC#DiscoveryNode type projection\" in {\n    def test1[TC <: DiscoverableService]: Boolean = {\n      ReflectionUtil.allPartsStrong(scala.reflect.runtime.universe.weakTypeOf[DiscoveryNodeProvider[GetDiscoveryNode[TC]]])\n    }\n    def test2[TC <: DiscoverableService]: Boolean = {\n      ReflectionUtil.allPartsStrong(scala.reflect.runtime.universe.weakTypeOf[DiscoveryNodeProvider[TC#DiscoveryNode]])\n    }\n    assert(!test1[DiscoverableServiceImpl])\n    assert(!test2[DiscoverableServiceImpl])\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/.jvm/src/test/scala-2/izumi/reflect/test/PlatformSpecific.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.macrortti.{LightTypeTag, LightTypeTagImpl}\n\nimport scala.reflect.runtime.{universe => ru}\n\nobject PlatformSpecific {\n  /** Use for stepping through in debugger */\n  def fromRuntime[T: ru.TypeTag]: LightTypeTag = fromRuntime(ru.typeOf[T], loud = false)\n  def fromRuntime[T: ru.TypeTag](loud: Boolean): LightTypeTag = fromRuntime(ru.typeOf[T], loud)\n\n  /** Use for stepping through in debugger */\n  def fromRuntime(tpe: ru.Type, loud: Boolean): LightTypeTag = {\n    def makeTag() = LightTypeTagImpl.makeLightTypeTag(ru)(tpe)\n    synchronized {\n      if (loud) TagLogging.withSanityChecks(TagLogging.withDebugOutput(makeTag())) else makeTag()\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/.native/src/test/scala-2/izumi/reflect/test/PlatformSpecific.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.macrortti.{LTag, LightTypeTag}\n\nobject PlatformSpecific {\n  def fromRuntime[T: LTag]: LightTypeTag = LTag[T].tag\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/DebugProperties.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\n/**\n  * Java properties and macro settings that control behavior and debug output of Lightweight Reflection macros\n  *\n  * @see [[DebugProperties]]\n  */\nobject DebugProperties {\n  /**\n    * Set system property `-Dizumi.reflect.rtti.optimized.equals=false` to disable optimized `equals` comparison for\n    * monomorphic [[izumi.reflect.macrortti.LightTypeTag]]s (instances of [[izumi.reflect.macrortti.LightTypeTag.ParsedLightTypeTag210]]).\n    * Try this if you're experiencing \"impossible\" false negatives. While we believe that such false negatives are impossible,\n    * even between tags generated by different versions of `izumi-reflect`, they could still be possible in actuality.\n    *\n    * {{{\n    *   sbt -Dizumi.reflect.rtti.optimized.equals=false\n    * }}}\n    *\n    * Default: `true`\n    */\n  final val `izumi.reflect.rtti.optimized.equals` = \"izumi.reflect.rtti.optimized.equals\"\n\n  /**\n    * Add compiler option `-Xmacro-settings:izumi.reflect.rtti.cache.compile=false` to disable compile-time caching of computed\n    * LightTypeTags. Caching is enabled by default for compile-time light type tag creation.\n    *\n    * {{{\n    *   scalacOptions += \"-Xmacro-settings:izumi.reflect.rtti.cache.compile=false\"\n    * }}}\n    *\n    * Default: `true`\n    */\n  final val `izumi.reflect.rtti.cache.compile` = \"izumi.reflect.rtti.cache.compile\"\n\n  /**\n    * Set system property `-Dizumi.reflect.rtti.cache.runtime=false` to disable caching for runtime creation of LightTypeTags.\n    * Caching is enabled by default for runtime light type tag creation.\n    *\n    * {{{\n    *   sbt -Dizumi.reflect.rtti.cache.runtime=false\n    * }}}\n    *\n    * Default: `true`\n    */\n  final val `izumi.reflect.rtti.cache.runtime` = \"izumi.reflect.rtti.cache.runtime\"\n\n  /**\n    * To see macro debug output during compilation, set `-Dizumi.reflect.debug.macro.rtti=true` system property\n    *\n    * {{{\n    *   sbt -Dizumi.reflect.debug.macro.rtti=true compile\n    * }}}\n    *\n    * Default: `false`\n    */\n  final val `izumi.reflect.debug.macro.rtti` = \"izumi.reflect.debug.macro.rtti\"\n\n  /**\n    * To enable sanity checking assertions during compilation, set `-Dizumi.reflect.debug.macro.rtti=true` system property\n    *\n    * {{{\n    *   sbt -Dizumi.reflect.debug.macro.rtti.assertions=true compile\n    * }}}\n    *\n    * Default: `false`\n    */\n  final val `izumi.reflect.debug.macro.rtti.assertions` = \"izumi.reflect.debug.macro.rtti.assertions\"\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/collections/IzCollections.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.collections\n\nimport izumi.reflect.internal.CollectionCompat\n\nimport scala.language.implicitConversions\n\nprivate[reflect] object IzCollections {\n  private[reflect] implicit def toRich[A, B](xs: CollectionCompat.IterableOnce[(A, B)]): IzMappings[A, B] = new IzMappings(xs)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/collections/IzMappings.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.collections\n\nimport izumi.reflect.internal.{CollectionCompat, NowarnCompat}\n\nimport scala.collection.mutable\n\nprivate[reflect] final class IzMappings[A, B](private val list: CollectionCompat.IterableOnce[(A, B)]) extends AnyVal {\n  @NowarnCompat.nowarn(\"msg=deprecated\")\n  def toMutableMultimap: MutableMultiMap[A, B] = {\n    list.foldLeft(new mutable.HashMap[A, mutable.Set[B]] with mutable.MultiMap[A, B]) {\n      (map, pair) => map.addBinding(pair._1, pair._2)\n    }\n  }\n\n  @NowarnCompat.nowarn(\"msg=deprecated\")\n  def toMultimap: ImmutableMultiMap[A, B] = {\n    toMutableMultimap.mapValues(_.toSet).toMap\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/collections/package.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals\n\nimport izumi.reflect.internal.NowarnCompat\n\nimport scala.collection.mutable\n\npackage object collections {\n  @NowarnCompat.nowarn(\"msg=deprecated\")\n  private[reflect] type MutableMultiMap[A, B] = mutable.HashMap[A, mutable.Set[B]] with mutable.MultiMap[A, B]\n  private[reflect] type ImmutableMultiMap[A, B] = Map[A, Set[B]]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/functional/Renderable.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.functional\n\nimport izumi.reflect.internal.fundamentals.functional.WithRenderableSyntax.RenderableSyntax\n\nimport scala.language.implicitConversions\n\nprivate[reflect] trait Renderable[T] {\n  def render(value: T): String\n}\nprivate[reflect] object Renderable extends WithRenderableSyntax {\n  @inline def apply[T: Renderable]: Renderable[T] = implicitly\n}\n\nprivate[reflect] trait WithRenderableSyntax {\n  @inline implicit final def RenderableSyntax[T](r: T): RenderableSyntax[T] = new RenderableSyntax[T](r)\n}\nprivate[reflect] object WithRenderableSyntax {\n  private[reflect] final class RenderableSyntax[T](private val r: T) extends AnyVal {\n    def render()(implicit R: Renderable[T]): String = R.render(r)\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/platform/assertions/IzAssert.scala",
    "content": "package izumi.reflect.internal.fundamentals.platform.assertions\n\nimport izumi.reflect.DebugProperties\nimport izumi.reflect.internal.fundamentals.platform.strings.IzString.toRichString\n\nimport java.util.concurrent.atomic.AtomicBoolean\n\nprivate[reflect] object IzAssert {\n  private[reflect] final def apply(assertion: => Boolean): Unit = apply(assertion, \"\")\n  private[reflect] final def apply(assertion: => Boolean, clue: => Any): Unit = {\n    if (statusAsserts()) {\n      if (!assertion) throw new IllegalArgumentException(s\"IzAssert failed: $clue\")\n    }\n  }\n\n  /** caching is enabled by default for runtime light type tag creation */\n  private[this] val enabled: AtomicBoolean = {\n    val prop = System.getProperty(DebugProperties.`izumi.reflect.debug.macro.rtti.assertions`).asBoolean().getOrElse(false)\n    new AtomicBoolean(prop)\n  }\n  // for calling within a debugger or tests\n  private[reflect] def enableAsserts(): Unit = enabled.set(true)\n  private[reflect] def disableAsserts(): Unit = enabled.set(false)\n  private[reflect] def statusAsserts(): Boolean = enabled.get()\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/platform/basics/IzBoolean.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.platform.basics\n\nimport scala.language.implicitConversions\n\nprivate[reflect] object IzBoolean {\n  @inline private[reflect] final implicit class LazyBool(private val b: () => Boolean) extends AnyVal {\n    @inline def value: Boolean = b()\n  }\n\n  @inline implicit final def toLazyBool(b: => Boolean): LazyBool = new LazyBool(() => b)\n\n  @inline final def all(b1: Boolean, b2: => Boolean): Boolean = {\n    b1 && b2\n  }\n  @inline final def all(b1: Boolean, b: LazyBool*): Boolean = {\n    b1 && b.forall(_.value)\n  }\n\n  @inline final def any(b1: Boolean): Boolean = {\n    b1\n  }\n  @inline final def any(b1: Boolean, b2: => Boolean): Boolean = {\n    b1 || b2\n  }\n  @inline final def any(b1: Boolean, b2: => Boolean, b3: => Boolean): Boolean = {\n    b1 || b2 || b3\n  }\n  @inline final def any(b1: Boolean, b2: => Boolean, b3: => Boolean, b4: => Boolean): Boolean = {\n    b1 || b2 || b3 || b4\n  }\n  @inline final def any(b1: Boolean, b: LazyBool*): Boolean = {\n    b1 || b.exists(_.value)\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/platform/console/TrivialLogger.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.platform.console\n\nimport izumi.reflect.DebugProperties\nimport izumi.reflect.internal.NowarnCompat\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger.Config\nimport izumi.reflect.internal.fundamentals.platform.strings.IzString._\n\nimport java.util.concurrent.atomic.AtomicBoolean\nimport scala.annotation.tailrec\nimport scala.reflect.{ClassTag, classTag}\n\nprivate[reflect] trait TrivialLogger {\n  def log(s: => String): Unit\n  def sub(): TrivialLogger = sub(1)\n  def sub(delta: Int): TrivialLogger\n}\n\nprivate[reflect] trait AbstractStringTrivialSink {\n  def flush(value: => String): Unit\n}\nprivate[reflect] object AbstractStringTrivialSink {\n  private[reflect] object Console extends AbstractStringTrivialSink {\n    override def flush(value: => String): Unit = System.out.println(value)\n  }\n}\n\nprivate[reflect] final class TrivialLoggerImpl(config: Config, id: String, logMessages: Boolean, loggerLevel: Int) extends TrivialLogger {\n  override def log(s: => String): Unit = {\n    flush(format(s))\n  }\n\n  override def sub(delta: Int): TrivialLogger = {\n    new TrivialLoggerImpl(config, id, logMessages, loggerLevel + delta)\n  }\n\n  @inline private[this] def format(s: => String): String = {\n    s\"$id: $s\"\n  }\n\n  @inline private[this] def flush(s: => String): Unit = {\n    if (logMessages) {\n      config.sink.flush(s.shift(loggerLevel, \"> \"))\n    }\n  }\n}\n\nprivate[reflect] object TrivialLogger {\n  private[reflect] final case class Config(\n    sink: AbstractStringTrivialSink,\n    forceLog: Boolean\n  )\n  private[reflect] object Config {\n    private[reflect] lazy val console: Config = Config(sink = AbstractStringTrivialSink.Console, forceLog = false)\n  }\n\n  def make[T: ClassTag](config: Config): TrivialLogger = {\n    val logMessages: Boolean = checkLog(config)\n    new TrivialLoggerImpl(config, classTag[T].runtimeClass.getSimpleName, logMessages, loggerLevel = 0)\n  }\n\n  @inline private[this] def checkLog(config: Config): Boolean = {\n    config.forceLog || enabled.get()\n  }\n\n  @NowarnCompat.nowarn(\"msg=return statement\")\n  private[this] val enabled: AtomicBoolean = {\n    def prop(): Boolean = {\n      val sysProperty = DebugProperties.`izumi.reflect.debug.macro.rtti` // this is the only debug logging property supported in the library\n      val default = false\n\n      val parts = sysProperty.split('.').toList\n\n      @tailrec\n      def check(current: String, tail: List[String]): Boolean = {\n        if (System.getProperty(current).asBoolean().getOrElse(default)) {\n          true\n        } else {\n          tail match {\n            case ::(head, next) => check(s\"$current.$head\", next)\n            case Nil => default\n          }\n        }\n      }\n      check(parts.head, parts.tail)\n    }\n    new AtomicBoolean(prop())\n  }\n  // for calling within a debugger or tests\n  private[reflect] def enableLogs(): Unit = enabled.set(true)\n  private[reflect] def disableLogs(): Unit = enabled.set(false)\n  private[reflect] def statusLogs(): Boolean = enabled.get()\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/internal/fundamentals/platform/strings/IzString.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.platform.strings\n\nimport scala.language.implicitConversions\nimport scala.util.Try\n\nprivate[reflect] final class IzString(private val s: String) extends AnyVal {\n  @inline final def asBoolean(): Option[Boolean] = {\n    Try(s.toBoolean).toOption\n  }\n\n  @inline final def shift(delta: Int, fill: String = \" \"): String = {\n    val shift = fill * delta\n    s.split(\"\\\\\\n\", -1).map(s => s\"$shift$s\").mkString(\"\\n\")\n  }\n}\n\nprivate[reflect] final class IzIterable[A](private val s: Iterable[A]) extends AnyVal {\n  def niceList(shift: String = \" \", prefix: String = \"- \"): String = {\n    if (s.nonEmpty) {\n      val fullPrefix = s\"\\n$shift$prefix\"\n      s.mkString(fullPrefix, fullPrefix, \"\")\n    } else {\n      \"ø\"\n    }\n  }\n}\n\nprivate[reflect] object IzString {\n  private[reflect] implicit def toRichString(s: String): IzString = new IzString(s)\n  private[reflect] implicit def toRichIterable[A](s: Iterable[A]): IzIterable[A] = new IzIterable(s)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/LTTOrdering.scala",
    "content": "package izumi.reflect.macrortti\n\nimport izumi.reflect.internal.OrderingCompat\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.{LambdaParamName, SymLiteral, SymTermName, SymTypeName}\n\nimport scala.util.Sorting\n\nprivate[macrortti] trait LTTOrdering {\n  import LightTypeTagRef._\n\n  @inline private[macrortti] final def OrderingAbstractReferenceInstance[A <: AbstractReference]: Ordering[A] = OrderingAbstractReference.asInstanceOf[Ordering[A]]\n\n  @inline private[macrortti] final def OrderingRefinementDeclInstance: Ordering[RefinementDecl] = OrderingRefinementDecl\n\n  private[macrortti] def refSetToSortedArray[T <: AbstractReference](set: Set[_ <: T]): Array[T] = {\n    @inline implicit def OrderingInstance: Ordering[AbstractReference] = LightTypeTagRef.OrderingAbstractReferenceInstance\n\n    val array: Array[AbstractReference] = set.toArray\n    Sorting.stableSort(array)\n    array.asInstanceOf[Array[T]]\n  }\n\n  private[macrortti] def refinementDeclSetToSortedArray(set: Set[RefinementDecl]): Array[RefinementDecl] = {\n    @inline implicit def OrderingInstance: Ordering[RefinementDecl] = LightTypeTagRef.OrderingRefinementDeclInstance\n\n    val array: Array[RefinementDecl] = set.toArray\n    Sorting.stableSort(array)\n    array\n  }\n\n  private[this] val OrderingAbstractReference: Ordering[AbstractReference] = new Ordering[AbstractReference] {\n    override def equiv(x: AbstractReference, y: AbstractReference): Boolean = x == y\n\n    override def compare(x: AbstractReference, y: AbstractReference): Int = (x, y) match {\n      case (lx: Lambda, ly: Lambda) =>\n        // Mirror Lambda#equals\n        val compare1 = Ordering.Int.compare(lx.input.size, ly.input.size)\n        if (compare1 != 0) return compare1\n        OrderingAbstractReference.compare(lx.normalizedOutput, ly.normalizedOutput)\n\n      case (IntersectionReference(refsx), IntersectionReference(refsy)) =>\n        OrderingArrayAbstractReference.compare(refSetToSortedArray(refsx), refSetToSortedArray(refsy))\n\n      case (UnionReference(refsx), UnionReference(refsy)) =>\n        OrderingArrayAbstractReference.compare(refSetToSortedArray(refsx), refSetToSortedArray(refsy))\n\n      case (Refinement(referencex, declsx), Refinement(referencey, declsy)) =>\n        val compare1 = compare(referencex, referencey)\n        if (compare1 != 0) return compare1\n        OrderingArrayRefinementDecl.compare(refinementDeclSetToSortedArray(declsx), refinementDeclSetToSortedArray(declsy))\n\n      case (NameReference(symx, boundariesx, prefixx), NameReference(symy, boundariesy, prefixy)) =>\n        val compare1 = OrderingSymName.compare(symx, symy)\n        if (compare1 != 0) return compare1\n        val compare2 = OrderingBoundaries.compare(boundariesx, boundariesy)\n        if (compare2 != 0) return compare2\n        OrderingOptionAbstractReference.compare(prefixx, prefixy)\n\n      case (FullReference(refx, parametersx, prefixx), FullReference(refy, parametersy, prefixy)) =>\n        val compare1 = OrderingSymName.compare(refx, refy)\n        if (compare1 != 0) return compare1\n        val compare2 = OrderingListTypeParam.compare(parametersx, parametersy)\n        if (compare2 != 0) return compare2\n        OrderingOptionAbstractReference.compare(prefixx, prefixy)\n\n      case _ =>\n        def idx(abstractReference: AbstractReference): Int = abstractReference match {\n          case _: Lambda => 0\n          case _: IntersectionReference => 1\n          case _: UnionReference => 2\n          case _: Refinement => 3\n          case _: NameReference => 4\n          case _: FullReference => 5\n          case _: WildcardReference => 6\n        }\n\n        Ordering.Int.compare(idx(x), idx(y))\n    }\n  }\n\n  private[this] val OrderingRefinementDecl: Ordering[RefinementDecl] = new Ordering[RefinementDecl] {\n    override def equiv(x: RefinementDecl, y: RefinementDecl): Boolean = x == y\n\n    override def compare(x: RefinementDecl, y: RefinementDecl): Int = (x, y) match {\n      case (RefinementDecl.Signature(namex, inputx, outputx), RefinementDecl.Signature(namey, inputy, outputy)) =>\n        val compare1 = Ordering.String.compare(namex, namey)\n        if (compare1 != 0) return compare1\n        val compare2 = OrderingListAbstractReference.compare(inputx, inputy)\n        if (compare2 != 0) return compare2\n        OrderingAbstractReference.compare(outputx, outputy)\n\n      case (RefinementDecl.TypeMember(namex, refx), RefinementDecl.TypeMember(namey, refy)) =>\n        val compare1 = Ordering.String.compare(namex, namey)\n        if (compare1 != 0) return compare1\n        OrderingAbstractReference.compare(refx, refy)\n\n      case _ =>\n        def idx(refinementDecl: RefinementDecl): Int = refinementDecl match {\n          case _: RefinementDecl.Signature => 0\n          case _: RefinementDecl.TypeMember => 1\n        }\n\n        Ordering.Int.compare(idx(x), idx(y))\n    }\n  }\n\n  private[this] val OrderingSymName: Ordering[SymName] = new Ordering[SymName] {\n    override def equiv(x: SymName, y: SymName): Boolean = x == y\n\n    override def compare(x: SymName, y: SymName): Int = {\n      def idx(symName: SymName): Int = symName match {\n        case SymTermName(_) => 0\n        case SymTypeName(_) => 1\n        case SymLiteral(_) => 2\n        case LambdaParamName(_, _, _) => 3\n      }\n\n      val compare1 = Ordering.Int.compare(idx(x), idx(y))\n      if (compare1 != 0) return compare1\n\n      (x, y) match {\n        case (x1: SymName.NamedSymbol, y1: SymName.NamedSymbol) => Ordering.String.compare(x1.name, y1.name)\n        case (x1: SymName.LambdaParamName, y1: SymName.LambdaParamName) =>\n          Ordering.Tuple3[Int, Int, Int].compare((x1.depth, x1.index, x1.arity), (y1.depth, y1.index, y1.arity))\n        case (x1: SymName.NamedSymbol, y1: SymName.LambdaParamName) =>\n          Ordering.String.compare(x1.name, SymName.forceName(y1))\n        case (x1: SymName.LambdaParamName, y1: SymName.NamedSymbol) =>\n          Ordering.String.compare(SymName.forceName(x1), y1.name)\n      }\n    }\n  }\n\n  private[this] val OrderingBoundaries: Ordering[Boundaries] = new Ordering[Boundaries] {\n    override def equiv(x: Boundaries, y: Boundaries): Boolean = x == y\n\n    override def compare(x: Boundaries, y: Boundaries): Int = (x, y) match {\n      case (Boundaries.Defined(rebx, retx), Boundaries.Defined(reby, rety)) =>\n        val compare1 = OrderingAbstractReference.compare(rebx, reby)\n        if (compare1 != 0) return compare1\n        OrderingAbstractReference.compare(retx, rety)\n\n      case (x, y) =>\n        def idx(boundaries: Boundaries): Int = boundaries match {\n          case _: Boundaries.Empty.type => 0\n          case _: Boundaries.Defined => 1\n        }\n\n        Ordering.Int.compare(idx(x), idx(y))\n    }\n  }\n\n  private[this] val OrderingTypeParam: Ordering[TypeParam] = new Ordering[TypeParam] {\n    override def equiv(x: TypeParam, y: TypeParam): Boolean = x == y\n\n    override def compare(x: TypeParam, y: TypeParam): Int = (x, y) match {\n      case (TypeParam(namex, varx), TypeParam(namey, vary)) =>\n        val compare1 = OrderingAbstractReference.compare(namex, namey)\n        if (compare1 != 0) return compare1\n        OrderingVariance.compare(varx, vary)\n    }\n  }\n\n  private[this] val OrderingVariance: Ordering[Variance] = Ordering.by {\n    case Variance.Invariant => 0\n    case Variance.Contravariant => 1\n    case Variance.Covariant => 2\n  }\n\n  private[this] val OrderingListAbstractReference: Ordering[List[AbstractReference]] = OrderingCompat.listOrdering(OrderingAbstractReference)\n  private[this] val OrderingArrayAbstractReference: Ordering[Array[AbstractReference]] = OrderingCompat.arrayOrdering(OrderingAbstractReference)\n  private[this] val OrderingOptionAbstractReference: Ordering[Option[AbstractReference]] = Ordering.Option(OrderingAbstractReference)\n\n  private[this] val OrderingArrayRefinementDecl: Ordering[Array[RefinementDecl]] = OrderingCompat.arrayOrdering(OrderingRefinementDecl)\n\n  private[this] val OrderingListTypeParam: Ordering[List[TypeParam]] = OrderingCompat.listOrdering(OrderingTypeParam)\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/LTTRenderables.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.internal.fundamentals.functional.{Renderable, WithRenderableSyntax}\nimport izumi.reflect.internal.fundamentals.platform.language.unused\nimport izumi.reflect.macrortti.LightTypeTagInheritance.{tpeAny, tpeAnyRef, tpeNothing, tpeNull, tpeObject}\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.SymLiteral\nimport izumi.reflect.macrortti.LightTypeTagRef._\n\ntrait LTTRenderables extends Serializable with WithRenderableSyntax {\n\n  def r_SymName(sym: SymName, hasPrefix: Boolean): String\n\n  def prefixSplitter: String = \"::\"\n\n  implicit lazy val r_LightTypeTag: Renderable[LightTypeTagRef] = new Renderable[LightTypeTagRef] {\n    override def render(value: LightTypeTagRef): String = value match {\n      case a: AbstractReference =>\n        a.render()\n    }\n  }\n\n  implicit lazy val r_AbstractReference: Renderable[AbstractReference] = new Renderable[AbstractReference] {\n    override def render(value: AbstractReference): String = value match {\n      case a: AppliedReference =>\n        a.render()\n      case l: Lambda =>\n        l.render()\n    }\n  }\n\n  implicit lazy val r_AppliedReference: Renderable[AppliedReference] = new Renderable[AppliedReference] {\n    override def render(value: AppliedReference): String = value match {\n      case a: AppliedNamedReference =>\n        a.render()\n      case i: IntersectionReference =>\n        i.render()\n      case u: UnionReference =>\n        u.render()\n      case r: Refinement =>\n        r.render()\n      case r: WildcardReference =>\n        r.render()\n    }\n  }\n\n  implicit lazy val r_Refinement: Renderable[Refinement] = new Renderable[Refinement] {\n    override def render(value: Refinement): String = {\n      s\"(${value.reference.render()} ${value.decls.toSeq.sorted(OrderingRefinementDeclInstance).map(_.render()).mkString(\"{\", \", \", \"}\")})\"\n    }\n  }\n\n  implicit lazy val r_Wildcard: Renderable[WildcardReference] = new Renderable[WildcardReference] {\n    override def render(value: WildcardReference): String = {\n      value.boundaries match {\n        case _: Boundaries.Defined =>\n          s\"?: ${value.boundaries.render()}\"\n\n        case Boundaries.Empty =>\n          \"?\"\n      }\n    }\n  }\n\n  implicit lazy val r_RefinementDecl: Renderable[RefinementDecl] = new Renderable[RefinementDecl] {\n    override def render(value: RefinementDecl): String = value match {\n      case RefinementDecl.Signature(name, input, output) =>\n        s\"def $name${input.map(_.render()).mkString(\"(\", \", \", \")\")}: ${output.render()}\"\n      case RefinementDecl.TypeMember(name, tpe) =>\n        s\"type $name = $tpe\"\n    }\n  }\n\n  implicit lazy val r_AppliedNamedReference: Renderable[AppliedNamedReference] = new Renderable[AppliedNamedReference] {\n    override def render(value: AppliedNamedReference): String = value match {\n      case n: NameReference =>\n        n.render()\n      case f: FullReference =>\n        f.render()\n    }\n  }\n\n  implicit lazy val r_Lambda: Renderable[Lambda] = new Renderable[Lambda] {\n    override def render(value: Lambda): String = {\n      s\"λ ${value.input.map(_.render()).map(p => s\"%$p\").mkString(\",\")} → ${value.output.render()}\"\n    }\n  }\n\n  implicit lazy val r_LambdaParameterName: Renderable[SymName.LambdaParamName] = new Renderable[SymName.LambdaParamName] {\n    override def render(value: SymName.LambdaParamName): String = {\n      value.depth match {\n        case t if t <= 0 =>\n          s\"${value.index}\"\n        case t if t > 0 =>\n          s\"${value.depth}:${value.index}\"\n        // FIXME so-called \"debug\" view doesn't display all the data here which could lead to confusion when \"debugging\"\n        //          s\"[${value.arity}]${value.depth}:${value.index}\"\n      }\n    }\n  }\n\n  implicit lazy val r_NameRefRenderer: Renderable[NameReference] = new Renderable[NameReference] {\n    override def render(value: NameReference): String = {\n      val r = r_SymName(value.ref, value.prefix.isDefined)\n\n      val rr = value.boundaries match {\n        case _: Boundaries.Defined =>\n          s\"$r|${value.boundaries.render()}\"\n        case Boundaries.Empty =>\n          r\n      }\n\n      value.prefix match {\n        case Some(p) =>\n          s\"${p.render()}$prefixSplitter$rr\"\n        case None =>\n          rr\n      }\n    }\n  }\n\n  implicit lazy val r_FullReference: Renderable[FullReference] = new Renderable[FullReference] {\n    override def render(value: FullReference): String = {\n      s\"${value.asName.render()}${value.parameters.map(_.render()).mkString(\"[\", \",\", \"]\")}\"\n    }\n  }\n\n  implicit lazy val r_IntersectionReference: Renderable[IntersectionReference] = new Renderable[IntersectionReference] {\n    override def render(value: IntersectionReference): String = {\n      value.refs.toSeq.sorted(OrderingAbstractReferenceInstance).map(r => (r: AppliedReference).render()).mkString(\"{\", \" & \", \"}\")\n    }\n  }\n\n  implicit lazy val r_UnionReference: Renderable[UnionReference] = new Renderable[UnionReference] {\n    override def render(value: UnionReference): String = {\n      value.refs.toSeq.sorted(OrderingAbstractReferenceInstance).map(r => (r: AppliedReference).render()).mkString(\"{\", \" | \", \"}\")\n    }\n  }\n\n  implicit lazy val r_TypeParam: Renderable[TypeParam] = new Renderable[TypeParam] {\n    override def render(value: TypeParam): String = {\n      s\"${value.variance.render()}${value.ref.render()}\"\n    }\n  }\n\n  implicit lazy val r_Variance: Renderable[Variance] = new Renderable[Variance] {\n    override def render(value: Variance): String = value match {\n      case Variance.Invariant => \"=\"\n      case Variance.Contravariant => \"-\"\n      case Variance.Covariant => \"+\"\n    }\n  }\n\n  implicit lazy val r_Boundaries: Renderable[Boundaries] = new Renderable[Boundaries] {\n    override def render(value: Boundaries): String = value match {\n      case Boundaries.Defined(bottom, top) =>\n        s\"<${bottom.render()}..${top.render()}>\"\n\n      case Boundaries.Empty =>\n        \"\"\n    }\n  }\n\n  @deprecated(\"bincompat only\", \"20.03.2023\")\n  private[macrortti] implicit lazy val r_LambdaParameter: Renderable[LambdaParameter] = new Renderable[LambdaParameter] {\n    override def render(value: LambdaParameter): String = value match {\n      case l: SymName.LambdaParamName => r_SymName(l, hasPrefix = false)\n    }\n  }\n\n}\n\nobject LTTRenderables {\n\n  // omit package names\n  object Short extends LTTRenderables {\n    override def r_SymName(sym: SymName, @unused hasPrefix: Boolean): String = {\n      sym match {\n        case SymLiteral(c) =>\n          c\n        case t: SymName.LambdaParamName =>\n          t.render()\n        case s: SymName.NamedSymbol =>\n          s.name.split('.').last\n      }\n    }\n  }\n\n  object Long extends Long\n\n  // print package names\n  private[LTTRenderables] trait Long extends LTTRenderables {\n    override def r_SymName(sym: SymName, hasPrefix: Boolean): String = {\n      if (hasPrefix) {\n        Short.r_SymName(sym, hasPrefix)\n      } else {\n        sym match {\n          case t: SymName.LambdaParamName => t.render()\n          case o: SymName.NamedSymbol => o.name\n        }\n      }\n    }\n\n    private[macrortti] def renderDb(db: Map[_ <: AbstractReference, Set[_ <: AbstractReference]]): String = {\n      import izumi.reflect.internal.fundamentals.platform.strings.IzString._\n      db.toList.sortBy(_._1)(OrderingAbstractReferenceInstance).map {\n          case (k, v) => s\"${k.repr} -> ${v.toList.sorted(OrderingAbstractReferenceInstance).map(_.repr).niceList(prefix = \"* \").shift(2)}\"\n        }.niceList()\n    }\n  }\n\n  // Same as `Long`, but split prefixes with . instead of ::\n  object LongPrefixDot extends LTTRenderables {\n    override def r_SymName(sym: SymName, hasPrefix: Boolean): String = {\n      Long.r_SymName(sym, hasPrefix)\n    }\n\n    override def prefixSplitter: String = \".\"\n  }\n\n  object ScalaStyledLambdas extends ScalaStyledLambdasShared {\n    override implicit lazy val r_LambdaParameterName: Renderable[SymName.LambdaParamName] = new Renderable[SymName.LambdaParamName] {\n      override def render(value: SymName.LambdaParamName): String = \"_\"\n    }\n\n    override implicit lazy val r_Lambda: Renderable[Lambda] = new Renderable[Lambda] {\n      override def render(value: Lambda): String = {\n        val isSimpleShape = value match {\n          case Lambda(input, FullReference(_, tparams, _)) =>\n            val (unusedRemaining, suspicious) = tparams.foldLeft((input, List.empty[AbstractReference])) {\n              // params must be applied in definition order\n              case ((all @ unusedArg :: tl, suspicious), TypeParam(p: AppliedNamedReference, variance)) =>\n                if (p.symName == unusedArg) {\n                  p match {\n                    case _: NameReference =>\n                      (tl, suspicious)\n                    case FullReference(symName, parameters, prefix) =>\n                      (tl, parameters.map(_.ref) ++ suspicious)\n                  }\n                } else {\n                  (all, p :: suspicious)\n                }\n              case ((all, suspicious), TypeParam(other, _)) => (all, other :: suspicious)\n            }\n            val innerUses = suspicious.iterator.flatMap(RuntimeAPI.unpack).map(_.symName).toSet\n            unusedRemaining.isEmpty && input.toSet.intersect(innerUses).isEmpty\n          case _ =>\n            false\n        }\n        if (isSimpleShape) {\n          s\"${value.output.render()}\"\n        } else {\n          ScalaStyledLambdasLong.r_Lambda.render(value)\n        }\n      }\n    }\n  }\n\n  object ScalaStyledLambdasLong extends ScalaStyledLambdasShared {\n    override implicit lazy val r_LambdaParameterName: Renderable[SymName.LambdaParamName] = new Renderable[SymName.LambdaParamName] {\n      override def render(value: SymName.LambdaParamName): String = {\n        val char = ('A' + (value.index % 25)).toChar.toString\n        val numChars = 1 + value.index / 25\n        val suffix = if (value.depth > 0) s\"${value.depth}\" else \"\"\n        s\"${char * numChars}$suffix\"\n      }\n    }\n\n    override implicit lazy val r_Lambda: Renderable[Lambda] = new Renderable[Lambda] {\n      override def render(value: Lambda): String = {\n        s\"[${value.input.map(_.render()).mkString(\",\")}] ➾ ${value.output.render()}\"\n      }\n    }\n  }\n\n  private[LTTRenderables] trait ScalaStyledLambdasShared extends Long {\n    override def prefixSplitter: String = \".\"\n\n    override implicit lazy val r_Variance: Renderable[Variance] = new Renderable[Variance] {\n      override def render(value: Variance): String = value match {\n        case Variance.Invariant => \"\"\n        case Variance.Contravariant => \"-\"\n        case Variance.Covariant => \"+\"\n      }\n    }\n\n    override implicit lazy val r_NameRefRenderer: Renderable[NameReference] = new Renderable[NameReference] {\n      override def render(value: NameReference): String = {\n        val r = r_SymName(value.ref, value.prefix.isDefined)\n\n        val rr = value.boundaries match {\n          case _: Boundaries.Defined =>\n            s\"$r ${value.boundaries.render()}\"\n          case Boundaries.Empty =>\n            r\n        }\n\n        value.prefix match {\n          case Some(p) =>\n            s\"${p.render()}$prefixSplitter$rr\"\n          case None =>\n            rr\n        }\n      }\n    }\n\n    override implicit lazy val r_Boundaries: Renderable[Boundaries] = new Renderable[Boundaries] {\n      override def render(value: Boundaries): String = value match {\n        case Boundaries.Defined(bottom, top) if bottom == tpeNothing || bottom == tpeNull => s\"<: ${top.render()}\"\n        case Boundaries.Defined(bottom, top) if top == tpeAny || top == tpeAnyRef || top == tpeObject => s\">: ${bottom.render()}\"\n        case Boundaries.Defined(bottom, top) => s\">: ${bottom.render()} <: ${top.render()}\"\n        case Boundaries.Empty => \"\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/LTTSyntax.scala",
    "content": "package izumi.reflect.macrortti\n\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.LambdaParamName\nimport izumi.reflect.macrortti.LightTypeTagRef._\n\nimport scala.annotation.tailrec\n\nprivate[macrortti] trait LTTSyntax {\n  this: LightTypeTagRef =>\n\n  protected[this] final def combineImpl(args: Seq[LightTypeTagRef]): AbstractReference = {\n    if (args.nonEmpty) {\n      applySeq(args.map { case v: AbstractReference => v })\n    } else {\n      // while user is not expected to combine an arbitrary tag with an empty args list\n      // it's a sound operation which should just return the tag itself\n      // see also: https://github.com/7mind/izumi/pull/1528\n      this match {\n        case ref: AbstractReference =>\n          ref\n      }\n    }\n  }\n\n  protected[this] final def combineNonPosImpl(args: Seq[Option[LightTypeTagRef]]): AbstractReference = {\n    applyParameters {\n      l =>\n        l.input.zip(args).flatMap {\n          case (p, v) =>\n            v match {\n              case Some(value: AbstractReference) =>\n                Seq(p -> value)\n              case None =>\n                Seq.empty\n            }\n        }\n    }\n  }\n\n  protected[this] final def withoutArgsImpl: AbstractReference = {\n    def appliedNamedReference(reference: AppliedNamedReference) = {\n      reference match {\n        case LightTypeTagRef.NameReference(_, _, _) => reference\n        case r @ LightTypeTagRef.FullReference(_, parameters @ _, prefix) => NameReference(r.symName, Boundaries.Empty, prefix)\n      }\n    }\n\n    def appliedReference(reference: AppliedReference): AppliedReference = {\n      reference match {\n        case reference: AppliedNamedReference =>\n          appliedNamedReference(reference)\n        case LightTypeTagRef.IntersectionReference(refs) =>\n          LightTypeTagRef.maybeIntersection(refs.map(appliedReference))\n        case LightTypeTagRef.UnionReference(refs) =>\n          LightTypeTagRef.maybeUnion(refs.map(appliedReference))\n        case LightTypeTagRef.Refinement(reference, decls) =>\n          LightTypeTagRef.Refinement(appliedReference(reference), decls)\n        case r: LightTypeTagRef.WildcardReference =>\n          r\n      }\n    }\n\n    @tailrec\n    def go(self: LightTypeTagRef): AbstractReference = {\n      self match {\n        case Lambda(_, output) =>\n          go(output)\n        case reference: AppliedReference =>\n          appliedReference(reference)\n      }\n    }\n\n    go(this)\n  }\n\n  /** Render to string, omitting package names */\n  protected[this] final def toStringImpl: String = {\n    import izumi.reflect.macrortti.LTTRenderables.Short._\n    (this: LightTypeTagRef).render()\n  }\n\n  /** Fully-qualified rendering of a type, including packages and prefix types.\n    * Use [[toString]] for a rendering that omits package names\n    */\n  protected[this] final def reprImpl: String = {\n    import izumi.reflect.macrortti.LTTRenderables.Long._\n    (this: LightTypeTagRef).render()\n  }\n\n  protected[this] final def scalaStyledReprImpl: String = {\n    import izumi.reflect.macrortti.LTTRenderables.ScalaStyledLambdas._\n    (this: LightTypeTagRef).render()\n  }\n\n  protected[this] final def shortNameImpl: String = {\n    getName(r => LTTRenderables.Short.r_SymName(r.symName, hasPrefix = false))\n  }\n\n  protected[this] final def longNameWithPrefixImpl: String = {\n    getName(r => LTTRenderables.LongPrefixDot.r_NameRefRenderer.render(r.asName.copy(boundaries = Boundaries.Empty)))\n  }\n\n  protected[this] final def longNameInternalSymbolImpl: String = {\n    getName(r => LTTRenderables.Long.r_SymName(r.symName, hasPrefix = false))\n  }\n\n  @deprecated(\n    \"Produces Scala version dependent output, with incorrect prefixes for types with value prefixes. Use `longNameWithPrefix` instead, or `longNameInternalSymbol` for old behavior\",\n    \"2.2.2\"\n  )\n  protected[this] final def longNameImpl: String = {\n    longNameInternalSymbol\n  }\n\n  protected[this] final def getPrefixImpl: Option[AppliedReference] = {\n    @tailrec\n    @inline\n    def getPrefix(self: LightTypeTagRef): Option[AppliedReference] = {\n      self match {\n        case Lambda(_, output) => getPrefix(output)\n        case NameReference(_, _, prefix) => prefix\n        case FullReference(_, _, prefix) => prefix\n        case IntersectionReference(refs) =>\n          val prefixes = refs.flatMap(_.getPrefix)\n          if (prefixes.nonEmpty) Some(maybeIntersection(prefixes)) else None\n        case UnionReference(refs) =>\n          val prefixes = refs.flatMap(_.getPrefix)\n          if (prefixes.nonEmpty) Some(maybeUnion(prefixes)) else None\n        case Refinement(reference, _) => getPrefix(reference)\n        case _: WildcardReference => None\n      }\n    }\n\n    getPrefix(this)\n  }\n\n  protected[this] final def typeArgsImpl: List[AbstractReference] = {\n    this match {\n      case Lambda(input, output) =>\n        val params = input.iterator.toSet[SymName]\n        output.typeArgs.filter {\n          case n: AppliedNamedReference =>\n            !params.contains(n.asName.ref)\n          case _ =>\n            true\n        }\n      case NameReference(_, _, _) =>\n        Nil\n      case FullReference(_, parameters, _) =>\n        parameters.map(_.ref)\n      case IntersectionReference(_) =>\n        Nil\n      case UnionReference(_) =>\n        Nil\n      case WildcardReference(_) =>\n        Nil\n      case Refinement(reference, _) =>\n        reference.typeArgs\n    }\n  }\n\n  /** decompose intersection type */\n  protected[this] final def decomposeImpl: Set[AppliedReferenceExceptIntersection] = {\n    this match {\n      case IntersectionReference(refs) =>\n        refs.flatMap(_.decompose)\n      case appliedReference: AppliedReferenceExceptIntersection =>\n        Set(appliedReference)\n      // lambdas cannot appear _inside_ intersections in LightTypeTagRef model\n      case Lambda(_, _) =>\n        Set.empty\n    }\n  }\n\n  protected[this] final def decomposeUnionImpl: Set[AppliedReferenceExceptUnion] = {\n    this match {\n      case UnionReference(refs) =>\n        refs.flatMap(_.decomposeUnion)\n      case appliedReference: AppliedReferenceExceptUnion =>\n        Set(appliedReference)\n      // lambdas cannot appear _inside_ unions in LightTypeTagRef model\n      case Lambda(_, _) =>\n        Set.empty\n    }\n  }\n\n  private[macrortti] final def applySeq(refs: Seq[AbstractReference]): AbstractReference = {\n    applyParameters {\n      l =>\n        l.input.zip(refs).map {\n          case (p, v) =>\n            p -> v\n        }\n    }\n  }\n\n  private[macrortti] final def applyParameters(p: Lambda => Seq[(LambdaParamName, AbstractReference)]): AbstractReference = {\n    this match {\n      case l: Lambda =>\n        val parameters = p(l)\n        if (l.input.size < parameters.size) {\n          throw new IllegalArgumentException(s\"$this expects no more than ${l.input.size} parameters: ${l.input} but got $parameters\")\n        }\n        val expected = l.input.iterator.toSet\n        val unknownKeys = parameters.iterator.map(_._1).toSet.diff(expected)\n        if (unknownKeys.nonEmpty) {\n          throw new IllegalArgumentException(s\"$this takes parameters: $expected but got unexpected ones: $unknownKeys\")\n        }\n\n        RuntimeAPI.applyLambda(l, parameters)\n      case _ =>\n        throw new IllegalArgumentException(s\"$this is not a type lambda, it cannot be parameterized\")\n    }\n  }\n\n  @inline\n  private[this] final def getName(render: AppliedNamedReference => String): String = {\n    @tailrec\n    @inline\n    def go(r: LightTypeTagRef): String = r match {\n      case Lambda(_, output) => go(output)\n      case ref: NameReference => render(ref)\n      case ref: FullReference => render(ref)\n      case IntersectionReference(refs) => refs.map(goDeep).mkString(\" & \")\n      case UnionReference(refs) => refs.map(goDeep).mkString(\" | \")\n      case Refinement(reference, _) => go(reference)\n      case WildcardReference(_) => \"?\"\n    }\n\n    def goDeep(r: LightTypeTagRef): String = go(r)\n\n    go(this)\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/LightTypeTag.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.DebugProperties\nimport izumi.reflect.internal.NowarnCompat\nimport izumi.reflect.internal.OrderingCompat.ArraySeqLike\nimport izumi.reflect.internal.fundamentals.platform.strings.IzString.toRichString\nimport izumi.reflect.macrortti.LightTypeTag.ParsedLightTypeTag.SubtypeDBs\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.{LambdaParamName, SymLiteral, SymTermName, SymTypeName}\nimport izumi.reflect.macrortti.LightTypeTagRef._\nimport izumi.reflect.thirdparty.internal.boopickle.NoMacro.Pickler\nimport izumi.reflect.thirdparty.internal.boopickle.{PickleImpl, UnpickleState}\n\nimport java.nio.ByteBuffer\nimport java.nio.charset.StandardCharsets\nimport scala.collection.immutable.HashSet\n\n/**\n  * Extracts internal databases from [[LightTypeTag]].\n  * Should not be used under normal circumstances.\n  *\n  * Internal API: binary compatibility not guaranteed.\n  */\nfinal case class LightTypeTagUnpacker(tag: LightTypeTag) {\n  def bases: Map[AbstractReference, Set[AbstractReference]] = tag.basesdb\n  def inheritance: Map[NameReference, Set[NameReference]] = tag.idb\n}\n\nabstract class LightTypeTag private[reflect] (\n  bases: () => Map[AbstractReference, Set[AbstractReference]],\n  inheritanceDb: () => Map[NameReference, Set[NameReference]]\n) extends Serializable {\n\n  def ref: LightTypeTagRef\n\n  // full subtyping db with lambdas, parameters and variance, e.g. List[+A] <: SeqOps[A, List, List[A]], λ %0 → List[+%0] <: λ %0,%1,%2 → SeqOps[+%0, +%1, +%2]\n  private[reflect] lazy val basesdb: Map[AbstractReference, Set[AbstractReference]] = bases()\n  // class inheritance db without lambdas and without parameters, e.g. List <: SeqOps, Iterable\n  private[reflect] lazy val idb: Map[NameReference, Set[NameReference]] = inheritanceDb()\n\n  def binaryFormatVersion: Int\n\n  def serialize(): LightTypeTag.Serialized = {\n    val hashCodeRef = this.hashCode()\n    val strRef = PickleImpl.serializeIntoString(this.ref, LightTypeTag.lttRefSerializer)\n    val strDBs = PickleImpl.serializeIntoString(SubtypeDBs.make(this.basesdb, this.idb), LightTypeTag.subtypeDBsSerializer)\n    LightTypeTag.Serialized(hashCodeRef, strRef, strDBs, LightTypeTag.currentBinaryFormatVersion)\n  }\n\n  @inline final def <:<(maybeParent: LightTypeTag): Boolean = {\n    new LightTypeTagInheritance(this, maybeParent).isChild()\n  }\n\n  @inline final def =:=(other: LightTypeTag): Boolean = {\n    this == other\n  }\n\n  final def decompose: Set[LightTypeTag] = {\n    ref match {\n      case intersection: LightTypeTagRef.IntersectionReference =>\n        val refs = intersection.decompose // make sure to unwrap nested intersections\n        refs.map(LightTypeTag(_, basesdb, idb))\n      case _ =>\n        Set(this)\n    }\n  }\n\n  final def decomposeUnion: Set[LightTypeTag] = {\n    ref match {\n      case union: LightTypeTagRef.UnionReference =>\n        val refs = union.decomposeUnion // make sure to unwrap nested unions\n        refs.map(LightTypeTag(_, basesdb, idb))\n      case _ =>\n        Set(this)\n    }\n  }\n\n  /**\n    * Parameterize this type tag with `args` if it describes an unapplied type lambda\n    *\n    * If there are less `args` given than this type takes parameters, it will remain a type\n    * lambda taking remaining arguments:\n    *\n    * {{{\n    *   F[_, _, _].combine(A, B) = F[A, B, _]\n    * }}}\n    */\n  def combine(args: LightTypeTag*): LightTypeTag = {\n    val argRefs = args.map(_.ref)\n    val appliedBases = basesdb ++ basesdb.iterator.collect { // do not remove the unapplied base lambdas after combination (required for inferredLambdaParents in isChild)\n      case (self: LightTypeTagRef.Lambda, parents) =>\n        self.combine(argRefs) -> parents.map {\n          case l: LightTypeTagRef.Lambda =>\n            l.combine(argRefs)\n          case nonLambdaParent =>\n            val context = self.input.zip(argRefs.collect { case a: AbstractReference => a }).toMap\n            new RuntimeAPI.Rewriter(context).replaceRefs(nonLambdaParent)\n        }\n    }\n\n    def mergedBasesDB = LightTypeTag.mergeIDBs(appliedBases, args.iterator.map(_.basesdb))\n\n    def mergedInheritanceDb = LightTypeTag.mergeIDBs(idb, args.iterator.map(_.idb))\n\n    LightTypeTag(ref.combine(argRefs), mergedBasesDB, mergedInheritanceDb)\n  }\n\n  /**\n    * Parameterize this type tag with `args` if it describes an unapplied type lambda\n    *\n    * The resulting type lambda will take parameters in places where `args` was None:\n    *\n    * {{{\n    *   F[_, _, _].combine(Some(A), None, Some(C)) = F[A, _, C]\n    * }}}\n    */\n  def combineNonPos(args: Option[LightTypeTag]*): LightTypeTag = {\n    val argRefs = args.map(_.map(_.ref))\n    val appliedBases = basesdb ++ basesdb.iterator.collect { // do not remove the unapplied base lambdas after combination (required for inferredLambdaParents in isChild)\n      case (self: LightTypeTagRef.Lambda, parents) =>\n        self.combineNonPos(argRefs) -> parents.map {\n          case l: LightTypeTagRef.Lambda =>\n            l.combineNonPos(argRefs)\n          case nonLambdaParent =>\n            val context = self.input.zip(argRefs.flatten.collect { case a: AbstractReference => a }).toMap\n            new RuntimeAPI.Rewriter(context).replaceRefs(nonLambdaParent)\n        }\n    }\n\n    def mergedBasesDB = LightTypeTag.mergeIDBs(appliedBases, args.iterator.map(_.map(_.basesdb).getOrElse(Map.empty)))\n\n    def mergedInheritanceDb = LightTypeTag.mergeIDBs(idb, args.iterator.map(_.map(_.idb).getOrElse(Map.empty)))\n\n    LightTypeTag(ref.combineNonPos(argRefs), mergedBasesDB, mergedInheritanceDb)\n  }\n\n  /**\n    * Strip all args from type tag of parameterized type and its supertypes\n    * Useful for very rough type-constructor / class-only comparisons.\n    *\n    * NOTE: This DOES NOT RESTORE TYPE CONSTRUCTOR/LAMBDA and is\n    * NOT equivalent to .typeConstructor call in scala-reflect\n    *       - You won't be able to call [[combine]] on result type\n    * and partially applied types will not work correctly\n    */\n  @NowarnCompat.nowarn(\"msg=deprecated\")\n  def withoutArgs: LightTypeTag = {\n    LightTypeTag(ref.withoutArgs, basesdb.mapValues(_.map(_.withoutArgs)).iterator.toMap, idb)\n  }\n\n  /**\n    * Extract arguments applied to this type constructor\n    */\n  def typeArgs: List[LightTypeTag] = {\n    ref.typeArgs.map(LightTypeTag(_, basesdb, idb))\n  }\n\n  /**\n    * Remove types that are supertypes of other types in the intersection from it\n    *\n    * e.g. transform `Tag[TraitSuper & TraitChild & AnyRef]` to `Tag[TraitChild]`\n    */\n  def removeIntersectionTautologies: LightTypeTag = {\n    ref match {\n      case IntersectionReference(refs) =>\n        if (refs.size <= 1) {\n          this\n        } else {\n          refs.tail.foldLeft(LightTypeTag(refs.head, basesdb, idb)) {\n            case (acc, tref) =>\n              val t = LightTypeTag(tref, basesdb, idb)\n              if (t <:< acc) {\n                t\n              } else if (acc <:< t) {\n                acc\n              } else {\n                LightTypeTag(LightTypeTagRef.IntersectionReference(acc.ref.decompose + tref), basesdb, idb)\n              }\n          }\n        }\n      case _ =>\n        this\n    }\n  }\n\n  /**\n    * Remove types that are subtypes of other types in the union from it\n    *\n    * e.g. transform `Tag[TraitSuper | TraitChild | Nothing]` to `Tag[TraitSuper]`\n    */\n  def removeUnionTautologies: LightTypeTag = {\n    ref match {\n      case UnionReference(refs) =>\n        if (refs.size <= 1) {\n          this\n        } else {\n          refs.tail.foldLeft(LightTypeTag(refs.head, basesdb, idb)) {\n            case (acc, tref) =>\n              val t = LightTypeTag(tref, basesdb, idb)\n              if (t <:< acc) {\n                acc\n              } else if (acc <:< t) {\n                t\n              } else {\n                LightTypeTag(LightTypeTagRef.UnionReference(acc.ref.decomposeUnion + tref), basesdb, idb)\n              }\n          }\n        }\n      case _ =>\n        this\n    }\n  }\n\n  /** Render to string, omitting package names */\n  override def toString: String = {\n    ref.toString\n  }\n\n  /**\n    * Fully-qualified rendering of a type, including packages and prefix types.\n    * Use [[toString]] for a rendering that omits package names\n    */\n  def repr: String = {\n    ref.repr\n  }\n\n  /**\n    * Fully-qualified rendering of a type, including packages and prefix types.\n    * Traditional Scala notation for lambdas, e.g. scala.util.Either[+scala.Int,+_]\n    */\n  def scalaStyledRepr: String = {\n    ref.scalaStyledRepr\n  }\n\n  /** Short class or type-constructor name of this type, without package or prefix names\n    *\n    * @note This will produce only a type constructor name, for full rendering of the type use [[toString]], [[repr]] or [[scalaStyledRepr]]\n    */\n  def shortName: String = {\n    ref.shortName\n  }\n\n  /** Class or type-constructor name of this type, with package and prefix names\n    *\n    * @note This will produce only a type constructor name, for full rendering of the type use [[toString]], [[repr]] or [[scalaStyledRepr]]\n    */\n  def longNameWithPrefix: String = {\n    ref.longNameWithPrefix\n  }\n\n  /** Internal symbol name of type-constructor of this type, with package and containing definition names\n    *\n    * @note This will produce only a type constructor name, for full rendering of the type use [[toString]], [[repr]] or [[scalaStyledRepr]]\n    */\n  def longNameInternalSymbol: String = {\n    ref.longNameInternalSymbol\n  }\n\n  @deprecated(\"Renamed to scalaStyledRepr\", \"3.0.8\")\n  def scalaStyledName: String = {\n    ref.scalaStyledName\n  }\n\n  @deprecated(\n    \"Produces Scala version dependent output, with incorrect prefixes for types with value prefixes. Use `longNameWithPrefix` instead, or `longNameInternalSymbol` for old behavior\",\n    \"2.2.2\"\n  )\n  /** @deprecated Produces Scala version dependent output, with incorrect prefixes for types with value prefixes. Use `longNameWithPrefix` instead, or `longNameInternalSymbol` for old behavior */\n  def longName: String = {\n    ref.longName\n  }\n\n  /** Print internal structures state */\n  def debug(name: String = \"\"): String = {\n    s\"\"\"⚙️ begin $name: ${this.repr}\n       |⚡️bases:${LTTRenderables.Long.renderDb(basesdb)}\n       |⚡️inheritance:${LTTRenderables.Long.renderDb(idb)}\n       |⚙️ end $name\"\"\".stripMargin\n  }\n\n  override def equals(other: Any): Boolean = {\n    other match {\n      case that: LightTypeTag =>\n        ref == that.ref\n      case _ => false\n    }\n  }\n\n  override def hashCode(): Int = {\n    hashcode\n  }\n\n  private[this] lazy val hashcode: Int = {\n    ref.hashCode() * 31\n  }\n}\n\nobject LightTypeTag {\n  final val currentBinaryFormatVersion = 30\n\n  case class Serialized(hash: Int, ref: String, databases: String, version: Int)\n\n  @inline def apply(ref0: LightTypeTagRef, bases: => Map[AbstractReference, Set[AbstractReference]], db: => Map[NameReference, Set[NameReference]]): LightTypeTag = {\n    new UnparsedLightTypeTag(ref0, () => bases, () => db)\n  }\n\n  /** Create a [[LightTypeTag]] formed of `intersection` with the structural refinement taken from `structure`\n    *\n    * @param structure the non-structural part of structure is ignored, except SubtypeDBs\n    * @param additionalTypeMembers additional type members\n    */\n  def refinedType(intersection: List[LightTypeTag], structure: LightTypeTag, additionalTypeMembers: Map[String, LightTypeTag]): LightTypeTag = {\n    val intersectionRef = LightTypeTagRef.maybeIntersection(intersection.iterator.map(_.ref))\n    val ref = {\n      val decls = structure.ref match {\n        case LightTypeTagRef.Refinement(_, decls) if decls.nonEmpty =>\n          decls\n        case _ =>\n          Set.empty[RefinementDecl]\n      }\n      if (decls.nonEmpty || additionalTypeMembers.nonEmpty) {\n        val newDecls = decls.filterNot(additionalTypeMembers contains _.name) ++ additionalTypeMembers.iterator.map {\n          case (k, v) =>\n            RefinementDecl.TypeMember(k, v.ref match { case r: AbstractReference => r })\n        }\n        LightTypeTagRef.Refinement(intersectionRef, newDecls)\n      } else {\n        intersectionRef\n      }\n    }\n\n    def mergedBasesDB: Map[AbstractReference, Set[AbstractReference]] =\n      LightTypeTag.mergeIDBs(structure.basesdb, intersection.iterator.map(_.basesdb) ++ additionalTypeMembers.iterator.map(_._2.basesdb))\n\n    def mergedInheritanceDb: Map[NameReference, Set[NameReference]] =\n      LightTypeTag.mergeIDBs(structure.idb, intersection.iterator.map(_.idb) ++ additionalTypeMembers.iterator.map(_._2.idb))\n\n    LightTypeTag(ref, mergedBasesDB, mergedInheritanceDb)\n  }\n\n  def unionType(union: List[LightTypeTag]): LightTypeTag = {\n    val ref = LightTypeTagRef.maybeUnion(union.iterator.map(_.ref))\n\n    def mergedBasesDB: Map[AbstractReference, Set[AbstractReference]] =\n      LightTypeTag.mergeIDBs(union.iterator.flatMap(_.basesdb))\n\n    def mergedInheritanceDb: Map[NameReference, Set[NameReference]] =\n      LightTypeTag.mergeIDBs(union.iterator.flatMap(_.idb))\n\n    LightTypeTag(ref, mergedBasesDB, mergedInheritanceDb)\n  }\n\n  def wildcardType(lowTag: LightTypeTag, highTag: LightTypeTag): LightTypeTag = {\n    val ref = LightTypeTagRef.WildcardReference(\n      Boundaries.Defined(\n        lowTag.ref match { case r: AbstractReference => r },\n        highTag.ref match { case r: AbstractReference => r }\n      )\n    )\n\n    def mergedBasesDB: Map[AbstractReference, Set[AbstractReference]] =\n      LightTypeTag.mergeIDBs(highTag.basesdb, lowTag.basesdb)\n\n    def mergedInheritanceDb: Map[NameReference, Set[NameReference]] =\n      LightTypeTag.mergeIDBs(highTag.idb, lowTag.idb)\n\n    LightTypeTag(ref, mergedBasesDB, mergedInheritanceDb)\n  }\n\n  def parse(serialized: Serialized): LightTypeTag = {\n    parse[LightTypeTag](serialized.hash, serialized.ref, serialized.databases, serialized.version)\n  }\n\n  def parse[T](hashCode: Int, refString: String, basesString: String, version: Int): LightTypeTag = {\n    lazy val shared = {\n      subtypeDBsSerializer.unpickle(UnpickleState(ByteBuffer.wrap(basesString.getBytes(StandardCharsets.ISO_8859_1))))\n    }\n\n    if (version >= 0 && version < currentBinaryFormatVersion) {\n      // because lambda parameter names in binary format are not normalized, the hashCode of the\n      // binary string can/will violate equals/hashCode contract when comparing binary strings\n      // between different binary version format or when using any hashCode from older binary\n      // string. So we ignore all hashCodes and fast paths from old binary strings\n      new ParsedLightTypeTagOldOrPre230(binaryFormatVersion = version, refString, () => shared.bases, () => shared.idb)\n    } else if (version == currentBinaryFormatVersion) {\n      new ParsedLightTypeTag230Plus(version, hashCode, refString, () => shared.bases, () => shared.idb)\n    } else {\n      throw new LinkageError(s\"\"\"Couldn't parse a `LightTypeTag` version=$version generated by a newer version of `izumi-reflect`,\n                                |please include a newer version of the library jar `dev.zio:izumi-reflect`!\n                                |\n                                |Supported `version` range in this version: 0..$currentBinaryFormatVersion\"\"\".stripMargin)\n    }\n  }\n\n  @deprecated(\"Binary compatibility for 1.0.0-M6+\", \"1.0.0-M6\")\n  private[reflect] def refinedType(intersection: List[LightTypeTag], structure: LightTypeTag): LightTypeTag = {\n    refinedType(intersection, structure, Map.empty)\n  }\n\n  private[reflect] final class UnparsedLightTypeTag private[reflect] (\n    override val ref: LightTypeTagRef,\n    bases: () => Map[AbstractReference, Set[AbstractReference]],\n    inheritanceDb: () => Map[NameReference, Set[NameReference]]\n  ) extends LightTypeTag(bases, inheritanceDb) {\n    @noinline override def binaryFormatVersion: Int = -1\n  }\n\n  private[reflect] object ParsedLightTypeTag {\n    private[reflect] final case class SubtypeDBs private (\n      bases: Map[AbstractReference, Set[AbstractReference]],\n      idb: Map[NameReference, Set[NameReference]]\n    )\n\n    private[reflect] object SubtypeDBs {\n      @NowarnCompat.nowarn(\"msg=deprecated\")\n      private[reflect] def make(bases: Map[AbstractReference, Set[AbstractReference]], idb: Map[NameReference, Set[NameReference]]): SubtypeDBs = {\n        new SubtypeDBs(\n          bases.mapValues(_.filterNot(v => LightTypeTagRef.isIgnored(v))).filterNot(_._2.isEmpty).iterator.toMap,\n          idb.mapValues(_.filterNot(v => LightTypeTagRef.isIgnored(v))).filterNot(_._2.isEmpty).iterator.toMap\n        )\n      }\n    }\n  }\n\n  /** `ParsedLightTypeTag` before 2.3.0 or before current version. It is forcefully deoptimized */\n  private[reflect] final class ParsedLightTypeTagOldOrPre230 private[reflect] (\n    // disable precomputed hashCode on older binary versions\n    // (old serialized lambdas break equals-hashCode contract\n    // when compared with new serialized lambdas)\n//    override val hashCode: Int,\n    override val binaryFormatVersion: Int,\n    private[reflect] val refString: String,\n    bases: () => Map[AbstractReference, Set[AbstractReference]],\n    db: () => Map[NameReference, Set[NameReference]]\n  ) extends LightTypeTag(bases, db) {\n    override lazy val ref: LightTypeTagRef = {\n      deserializeRefString(refString)\n    }\n\n    // disable optimizations for older binary versions\n//    override def equals(other: Any): Boolean = {\n//      other match {\n//        case that: ParsedLightTypeTagPre230 if this.binaryFormatVersion == that.binaryFormatVersion =>\n//          if (this.refString == that.refString) true\n//          else if (optimisticEqualsEnabled) false\n//          else super.equals(other)\n//        case _ =>\n//          super.equals(other)\n//      }\n//    }\n  }\n\n  /** `ParsedLightTypeTag` since 2.3.0 or current binary format version */\n  private[reflect] final class ParsedLightTypeTag230Plus private[reflect] (\n    override val binaryFormatVersion: Int,\n    override val hashCode: Int,\n    private[reflect] val refString: String,\n    bases: () => Map[AbstractReference, Set[AbstractReference]],\n    db: () => Map[NameReference, Set[NameReference]]\n  ) extends LightTypeTag(bases, db) {\n    override lazy val ref: LightTypeTagRef = {\n      deserializeRefString(refString)\n    }\n\n    override def equals(other: Any): Boolean = {\n      other match {\n        case that: ParsedLightTypeTag230Plus if this.binaryFormatVersion == that.binaryFormatVersion =>\n          if (this.refString == that.refString) true\n          else if (optimisticEqualsEnabled) false\n          else super.equals(other)\n        case _ =>\n          super.equals(other)\n      }\n    }\n  }\n\n  @noinline private[reflect] def deserializeRefString(refString: String): LightTypeTagRef = {\n    lttRefSerializer.unpickle(UnpickleState(ByteBuffer.wrap(refString.getBytes(StandardCharsets.ISO_8859_1))))\n  }\n\n  private[this] final val optimisticEqualsEnabled = {\n    System\n      .getProperty(DebugProperties.`izumi.reflect.rtti.optimized.equals`)\n      .asBoolean()\n      .getOrElse(true)\n  }\n\n  private[reflect] val (lttRefSerializer: Pickler[LightTypeTagRef], subtypeDBsSerializer: Pickler[SubtypeDBs]) = {\n    import izumi.reflect.thirdparty.internal.boopickle\n    import izumi.reflect.thirdparty.internal.boopickle.BasicPicklers.IntPickler\n    import izumi.reflect.thirdparty.internal.boopickle.NoMacro.{Pickler => _, _}\n\n    implicit lazy val variance: Pickler[Variance] = IntPickler.xmap {\n      case 0 => Variance.Invariant: Variance\n      case 1 => Variance.Contravariant: Variance\n      case 2 => Variance.Covariant: Variance\n    } {\n      case Variance.Invariant => 0\n      case Variance.Contravariant => 1\n      case Variance.Covariant => 2\n    }\n    implicit lazy val symName: Pickler[SymName] = new Pickler[SymName] {\n      override def pickle(obj: SymName)(implicit state: PickleState): Unit = {\n        obj match {\n          case SymTermName(name) =>\n            state.enc.writeInt(0)\n            state.pickle[String](name)\n            ()\n\n          case SymTypeName(name) =>\n            state.enc.writeInt(1)\n            state.pickle[String](name)\n            ()\n\n          case SymLiteral(name) =>\n            state.enc.writeInt(2)\n            state.pickle[String](name)\n            ()\n\n          case LambdaParamName(index, depth, arity) =>\n            state.enc.writeInt(3)\n            state.enc.writeInt(index)\n            state.enc.writeInt(depth)\n            state.enc.writeInt(arity)\n            ()\n        }\n      }\n\n      override def unpickle(implicit state: UnpickleState): SymName = state.dec.readInt match {\n        case 0 =>\n          SymTermName(state.unpickle[String])\n        case 1 =>\n          SymTypeName(state.unpickle[String])\n        case 2 =>\n          SymLiteral(state.unpickle[String])\n        case 3 =>\n          LambdaParamName(state.dec.readInt, state.dec.readInt, state.dec.readInt)\n        case o =>\n          throw new IllegalArgumentException(s\"Unexpected data: $o\")\n      }\n    }\n\n    implicit lazy val boundariesDefined: Pickler[Boundaries.Defined] = new Pickler[Boundaries.Defined] {\n      override def pickle(obj: Boundaries.Defined)(implicit state: PickleState): Unit = {\n        Tuple2Pickler[AbstractReference, AbstractReference].pickle((obj.bottom, obj.top))\n      }\n\n      override def unpickle(implicit state: UnpickleState): Boundaries.Defined = {\n        val u = Tuple2Pickler[AbstractReference, AbstractReference].unpickle\n        Boundaries.Defined(u._1, u._2)\n      }\n    }\n    implicit lazy val boundaries: Pickler[Boundaries] = new Pickler[Boundaries] {\n      override def pickle(obj: Boundaries)(implicit state: PickleState): Unit = obj match {\n        case d: Boundaries.Defined =>\n          optionPickler[Boundaries.Defined].pickle(Some(d))\n        case Boundaries.Empty =>\n          optionPickler[Boundaries.Defined].pickle(None)\n      }\n\n      override def unpickle(implicit state: UnpickleState): Boundaries = {\n        optionPickler[Boundaries.Defined].unpickle match {\n          case Some(value) =>\n            value\n          case None =>\n            Boundaries.Empty\n        }\n      }\n    }\n\n    implicit def nameRefSerializer: Pickler[NameReference] = new boopickle.Pickler[LightTypeTagRef.NameReference] {\n      override def pickle(value: LightTypeTagRef.NameReference)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[LightTypeTagRef.SymName](value.ref)\n            state.pickle[LightTypeTagRef.Boundaries](value.boundaries)\n            state.pickle[Option[LightTypeTagRef.AppliedReference]](value.prefix)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.NameReference = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = new LightTypeTagRef.NameReference(\n            state.unpickle[LightTypeTagRef.SymName],\n            state.unpickle[LightTypeTagRef.Boundaries],\n            state.unpickle[Option[LightTypeTagRef.AppliedReference]]\n          )\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.NameReference](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val appliedref: Pickler[AppliedReference] = new boopickle.CompositePickler[LightTypeTagRef.AppliedReference] {\n      addConcreteType[FullReference]\n      addConcreteType[IntersectionReference]\n      addConcreteType[NameReference]\n      addConcreteType[Refinement]\n      addConcreteType[UnionReference]\n      addConcreteType[WildcardReference]\n    }\n    implicit lazy val aref: Pickler[AbstractReference] = new boopickle.CompositePickler[LightTypeTagRef.AbstractReference] {\n      addConcreteType[FullReference]\n      addConcreteType[IntersectionReference]\n      addConcreteType[LightTypeTagRef.Lambda]\n      addConcreteType[NameReference]\n      addConcreteType[Refinement]\n      addConcreteType[UnionReference]\n      addConcreteType[WildcardReference]\n    }\n    implicit lazy val tagref: Pickler[LightTypeTagRef] = new boopickle.CompositePickler[LightTypeTagRef] {\n      addConcreteType[FullReference]\n      addConcreteType[IntersectionReference]\n      addConcreteType[LightTypeTagRef.Lambda]\n      addConcreteType[NameReference]\n      addConcreteType[Refinement]\n      addConcreteType[UnionReference]\n      addConcreteType[WildcardReference]\n    }\n\n    implicit lazy val wildcardRefSerializer: Pickler[WildcardReference] = new boopickle.Pickler[LightTypeTagRef.WildcardReference] {\n      override def pickle(value: LightTypeTagRef.WildcardReference)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[LightTypeTagRef.Boundaries](value.boundaries)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.WildcardReference = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = new WildcardReference(\n            state.unpickle[Boundaries]\n          )\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.WildcardReference](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    // Deserializer for FullReference before version 2.3.0 (with String first parameter instead of SymName)\n    implicit lazy val fullRef: Pickler[FullReference] = new boopickle.Pickler[LightTypeTagRef.FullReference] {\n      override def pickle(value: LightTypeTagRef.FullReference)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            // After version 2.3.0 the FullReference format changed - we now use SymName not String for FullReference name\n            // Thankfully, boopickle's identity serialization only uses number range Int.MinValue..0,\n            // leaving us with all numbers above 0 to encode format variants.\n            state.enc.writeInt(1) // We use 1 instead of normal value 0\n            //\n            state.pickle[SymName](value.symName)\n            state.pickle[List[LightTypeTagRef.TypeParam]](value.parameters)\n            state.pickle[Option[LightTypeTagRef.AppliedReference]](value.prefix)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.FullReference = {\n        val ic = state.dec.readInt\n        if (ic == 0) { // Pre 2.3.0 format\n          val value = LightTypeTagRef.FullReference(\n            SymName.SymTypeName(state.unpickle[String]),\n            state.unpickle[List[LightTypeTagRef.TypeParam]],\n            state.unpickle[Option[LightTypeTagRef.AppliedReference]]\n          )\n          state.addIdentityRef(value)\n          value\n        } else if (ic == 1) { // Post 2.3.0\n          val value = LightTypeTagRef.FullReference(\n            state.unpickle[SymName],\n            state.unpickle[List[LightTypeTagRef.TypeParam]],\n            state.unpickle[Option[LightTypeTagRef.AppliedReference]]\n          )\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.FullReference](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val typeParam: Pickler[LightTypeTagRef.TypeParam] = new boopickle.Pickler[LightTypeTagRef.TypeParam] {\n      override def pickle(value: LightTypeTagRef.TypeParam)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[LightTypeTagRef.AbstractReference](value.ref)\n            state.pickle[LightTypeTagRef.Variance](value.variance)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.TypeParam = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = LightTypeTagRef.TypeParam(state.unpickle[LightTypeTagRef.AbstractReference], state.unpickle[LightTypeTagRef.Variance])\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.TypeParam](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val union: Pickler[UnionReference] = new boopickle.Pickler[LightTypeTagRef.UnionReference] {\n      override def pickle(value: LightTypeTagRef.UnionReference)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[ArraySeqLike[LightTypeTagRef.AppliedReference]](LightTypeTagRef.refSetToSortedArray[AppliedReference](value.refs))\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.UnionReference = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val refs0 = state.unpickle[HashSet[AppliedReference]]\n          val refs = refs0.flatMap {\n            case u: UnionReference => u.decomposeUnion\n            case other: AppliedReferenceExceptUnion => Set(other)\n          }\n          val value = LightTypeTagRef.UnionReference(refs)\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.UnionReference](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val intersection: Pickler[IntersectionReference] = new boopickle.Pickler[LightTypeTagRef.IntersectionReference] {\n      override def pickle(value: LightTypeTagRef.IntersectionReference)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[ArraySeqLike[LightTypeTagRef.AppliedReference]](LightTypeTagRef.refSetToSortedArray[AppliedReference](value.refs))\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.IntersectionReference = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val refs0 = state.unpickle[HashSet[AppliedReference]]\n          val refs = refs0.flatMap {\n            case u: IntersectionReference => u.decompose\n            case other: AppliedReferenceExceptIntersection => Set(other)\n          }\n          val value = LightTypeTagRef.IntersectionReference(refs)\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.IntersectionReference](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val lambda: Pickler[LightTypeTagRef.Lambda] = new boopickle.Pickler[LightTypeTagRef.Lambda] {\n      override def pickle(value: LightTypeTagRef.Lambda)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            // After version 2.3.0 the Lambda format changed - we now use LambdaParamName not LambdaParameter for Lambda inputs\n            // Thankfully, boopickle's identity serialization only uses number range Int.MinValue..0,\n            // leaving us with all numbers above 0 to encode format variants.\n            state.enc.writeInt(1) // We use 1 instead of normal value 0\n            state.pickle[List[SymName.LambdaParamName]](value.input)\n            state.pickle[LightTypeTagRef.AbstractReference](value.output)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.Lambda = {\n        val ic = state.dec.readInt\n        if (ic == 0) { // Pre 2.3.0 format\n          object OldLambdaParameter {\n            type OldLambdaParameter <: String\n\n            implicit val oldLambdaParameterPickler: boopickle.Pickler[OldLambdaParameter] = new boopickle.Pickler[OldLambdaParameter] {\n              override def pickle(obj: OldLambdaParameter.OldLambdaParameter)(implicit state: PickleState): Unit = {\n                throw new RuntimeException(\"Impossible - old lambda parameter compat pickler should never be called to serialize - only to deserialize\")\n              }\n              override def unpickle(implicit state: UnpickleState): OldLambdaParameter.OldLambdaParameter = {\n                val ic = state.dec.readInt\n                if (ic == 0) {\n                  val value = state.unpickle[String]\n                  state.addIdentityRef(value)\n                  value.asInstanceOf[OldLambdaParameter]\n                } else if (ic < 0)\n                  state.identityFor[String](-ic).asInstanceOf[OldLambdaParameter]\n                else\n                  state.codingError(ic)\n              }\n            }\n          }\n\n          def convertPre230LambdaToNew(lambda: LightTypeTagRef.Lambda, paramMap: Map[String, SymName.LambdaParamName]): LightTypeTagRef.Lambda = {\n\n            def goReplaceBoundaries(boundaries: Boundaries): Boundaries = boundaries match {\n              case Boundaries.Defined(bottom, top) =>\n                Boundaries.Defined(goReplace(bottom), goReplace(top))\n              case Boundaries.Empty =>\n                Boundaries.Empty\n            }\n\n            def goReplaceSymName(symName: SymName): SymName = symName match {\n              case oldSymName @ SymTypeName(maybeLambdaParam) =>\n                paramMap.getOrElse(maybeLambdaParam, oldSymName)\n              case _ => symName\n            }\n\n            def goReplace[T <: AbstractReference](abstractReference: T): T = {\n              (abstractReference match {\n                case Lambda(input, output) =>\n                  // a lambda read by another codec must have already\n                  // been processed by conversion procedure, so it should\n                  // have no clashes in SymTypeName with old parameters\n                  // anymore and be safe to process\n                  Lambda(input, goReplace(output))\n\n                case IntersectionReference(refs) =>\n                  IntersectionReference(refs.map(goReplace))\n\n                case UnionReference(refs) =>\n                  UnionReference(refs.map(goReplace))\n\n                case WildcardReference(boundaries) =>\n                  WildcardReference(goReplaceBoundaries(boundaries))\n\n                case Refinement(reference, decls) =>\n                  Refinement(\n                    goReplace(reference),\n                    decls.map {\n                      case RefinementDecl.Signature(name, input, output) =>\n                        RefinementDecl.Signature(name, input.map(goReplace), goReplace(output))\n                      case RefinementDecl.TypeMember(name, ref) =>\n                        RefinementDecl.TypeMember(name, goReplace(ref))\n                    }\n                  )\n\n                case NameReference(ref, boundaries, prefix) =>\n                  NameReference(goReplaceSymName(ref), goReplaceBoundaries(boundaries), prefix.map(goReplace))\n\n                case FullReference(symName, parameters, prefix) =>\n                  FullReference(\n                    goReplaceSymName(symName),\n                    parameters.map {\n                      case TypeParam(ref, variance) => TypeParam(goReplace(ref), variance)\n                    },\n                    prefix.map(goReplace)\n                  )\n              }).asInstanceOf[T]\n            }\n\n            val LightTypeTagRef.Lambda(convertedParams, oldResult) = lambda\n            LightTypeTagRef.Lambda(convertedParams, goReplace(oldResult))\n          }\n\n          import OldLambdaParameter.{OldLambdaParameter, oldLambdaParameterPickler}\n\n          val oldParams = state.unpickle[List[OldLambdaParameter]]\n          val lambdaResult = state.unpickle[LightTypeTagRef.AbstractReference]\n\n          val convertedParams = oldParams.map(SymName.bincompatForceCreateLambdaParamNameFromString(_))\n          val paramMap = oldParams.iterator.zip(convertedParams.iterator).toMap[String, SymName.LambdaParamName]\n\n          val oldLambda = LightTypeTagRef.Lambda(convertedParams, lambdaResult)\n          val value = convertPre230LambdaToNew(oldLambda, paramMap)\n          state.addIdentityRef(value)\n          value\n        } else if (ic == 1) { // Post 2.3.0\n          val value = LightTypeTagRef.Lambda(\n            state.unpickle[List[SymName.LambdaParamName]],\n            state.unpickle[LightTypeTagRef.AbstractReference]\n          )\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.Lambda](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val lambdaParameter: Pickler[SymName.LambdaParamName] = new boopickle.Pickler[SymName.LambdaParamName] {\n      override def pickle(value: SymName.LambdaParamName)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[Int](value.index)\n            state.pickle[Int](value.depth)\n            state.pickle[Int](value.arity)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): SymName.LambdaParamName = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = SymName.LambdaParamName(state.unpickle[Int], state.unpickle[Int], state.unpickle[Int])\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[SymName.LambdaParamName](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val refinement: Pickler[Refinement] = new boopickle.Pickler[LightTypeTagRef.Refinement] {\n      override def pickle(value: LightTypeTagRef.Refinement)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[LightTypeTagRef.AppliedReference](value.reference)\n            state.pickle[ArraySeqLike[LightTypeTagRef.RefinementDecl]](LightTypeTagRef.refinementDeclSetToSortedArray(value.decls))\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.Refinement = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = LightTypeTagRef.Refinement(state.unpickle[LightTypeTagRef.AppliedReference], state.unpickle[HashSet[LightTypeTagRef.RefinementDecl]])\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.Refinement](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val refinementDecl: boopickle.CompositePickler[LightTypeTagRef.RefinementDecl] = new boopickle.CompositePickler[LightTypeTagRef.RefinementDecl] {\n      addConcreteType[LightTypeTagRef.RefinementDecl.Signature]\n      addConcreteType[LightTypeTagRef.RefinementDecl.TypeMember]\n    }\n\n    implicit lazy val typeMember: Pickler[RefinementDecl.TypeMember] = new boopickle.Pickler[LightTypeTagRef.RefinementDecl.TypeMember] {\n      override def pickle(value: LightTypeTagRef.RefinementDecl.TypeMember)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[String](value.name)\n            state.pickle[LightTypeTagRef.AbstractReference](value.ref)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.RefinementDecl.TypeMember = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = LightTypeTagRef.RefinementDecl.TypeMember(state.unpickle[String], state.unpickle[LightTypeTagRef.AbstractReference])\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.RefinementDecl.TypeMember](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val signature: Pickler[RefinementDecl.Signature] = new boopickle.Pickler[LightTypeTagRef.RefinementDecl.Signature] {\n      override def pickle(value: LightTypeTagRef.RefinementDecl.Signature)(implicit state: boopickle.PickleState): Unit = {\n        {\n          val ref = state.identityRefFor(value)\n          if (ref.isDefined) state.enc.writeInt(-ref.get)\n          else {\n            state.enc.writeInt(0)\n            state.pickle[String](value.name)\n            state.pickle[List[LightTypeTagRef.AppliedReference]](value.input)\n            state.pickle[LightTypeTagRef.AppliedReference](value.output)\n            state.addIdentityRef(value)\n          }\n        }\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTagRef.RefinementDecl.Signature = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = LightTypeTagRef\n            .RefinementDecl.Signature(\n              state.unpickle[String],\n              state.unpickle[List[LightTypeTagRef.AppliedReference]],\n              state.unpickle[LightTypeTagRef.AppliedReference]\n            )\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTagRef.RefinementDecl.Signature](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    implicit lazy val dbsSerializer: Pickler[SubtypeDBs] = new boopickle.Pickler[LightTypeTag.ParsedLightTypeTag.SubtypeDBs] {\n      override def pickle(value: LightTypeTag.ParsedLightTypeTag.SubtypeDBs)(implicit state: boopickle.PickleState): Unit = {\n\n        val ref = state.identityRefFor(value)\n        if (ref.isDefined) state.enc.writeInt(-ref.get)\n        else {\n          state.enc.writeInt(0)\n          state.pickle[Map[LightTypeTagRef.AbstractReference, Set[LightTypeTagRef.AbstractReference]]](value.bases)\n          state.pickle[Map[LightTypeTagRef.NameReference, Set[LightTypeTagRef.NameReference]]](value.idb)\n          state.addIdentityRef(value)\n        }\n\n        ()\n      }\n\n      override def unpickle(implicit state: boopickle.UnpickleState): LightTypeTag.ParsedLightTypeTag.SubtypeDBs = {\n        val ic = state.dec.readInt\n        if (ic == 0) {\n          val value = LightTypeTag\n            .ParsedLightTypeTag.SubtypeDBs.make(\n              state.unpickle[Map[LightTypeTagRef.AbstractReference, Set[LightTypeTagRef.AbstractReference]]],\n              state.unpickle[Map[LightTypeTagRef.NameReference, Set[LightTypeTagRef.NameReference]]]\n            )\n          state.addIdentityRef(value)\n          value\n        } else if (ic < 0)\n          state.identityFor[LightTypeTag.ParsedLightTypeTag.SubtypeDBs](-ic)\n        else\n          state.codingError(ic)\n      }\n    }\n\n    // false positive unused warnings\n    // lazy val _ = (symTypeName, symTermName, symName, appliedRefSerializer, nameRefSerializer, abstractRefSerializer)\n\n    (tagref, dbsSerializer)\n  }\n\n  private[macrortti] def mergeIDBs[T](self: Map[T, Set[T]], other: Map[T, Set[T]]): Map[T, Set[T]] = {\n    mergeIDBs(self.iterator ++ other.iterator)\n  }\n\n  private[macrortti] def mergeIDBs[T](self: Map[T, Set[T]], others: Iterator[Map[T, Set[T]]]): Map[T, Set[T]] = {\n    mergeIDBs(self.iterator ++ others.flatMap(_.iterator))\n  }\n\n  private[macrortti] def mergeIDBs[T](bases: Iterator[(T, Set[T])]): Map[T, Set[T]] = {\n    import izumi.reflect.internal.fundamentals.collections.IzCollections._\n    bases.toMultimap.map {\n      case (k, v) =>\n        (k, v.flatten.filterNot(_ == k))\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/LightTypeTagInheritance.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.internal.fundamentals.collections.ImmutableMultiMap\nimport izumi.reflect.internal.fundamentals.platform.basics.IzBoolean._\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger.Config\nimport izumi.reflect.macrortti.LightTypeTagInheritance._\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.SymTypeName\nimport izumi.reflect.macrortti.LightTypeTagRef._\n\nimport scala.collection.mutable\n\nobject LightTypeTagInheritance {\n  private[reflect] final val tpeNothing = NameReference(SymTypeName(\"scala.Nothing\"))\n  private[reflect] final val tpeNull = NameReference(SymTypeName(\"scala.Null\"))\n\n  private[reflect] final val tpeAny = NameReference(SymTypeName(\"scala.Any\"))\n  private[reflect] final val tpeAnyRef = NameReference(SymTypeName(\"scala.AnyRef\"))\n\n  private[reflect] final val tpeMatchable = NameReference(SymTypeName(\"scala.Matchable\"))\n  private[reflect] final val tpeObject = NameReference(SymTypeName(classOf[Object].getName))\n\n  private final case class Ctx(\n    logger: TrivialLogger,\n    self: LightTypeTagInheritance\n  ) {\n    def next(): Ctx = Ctx(logger.sub(), self)\n  }\n  private implicit final class CtxExt(private val ctx: Ctx) extends AnyVal {\n    def isChild(selfT0: LightTypeTagRef, thatT0: LightTypeTagRef): Boolean = ctx.self.isChild(ctx.next())(selfT0, thatT0)\n  }\n}\n\nfinal class LightTypeTagInheritance(self: LightTypeTag, other: LightTypeTag) {\n  private[this] lazy val basesdb: ImmutableMultiMap[AbstractReference, AbstractReference] = LightTypeTag.mergeIDBs(self.basesdb, other.basesdb)\n  private[this] lazy val idb: ImmutableMultiMap[NameReference, NameReference] = LightTypeTag.mergeIDBs(self.idb, other.idb)\n\n  def isChild(): Boolean = {\n    val st = self.ref\n    val ot = other.ref\n    val logger = TrivialLogger.make[this.type](config = Config.console)\n\n    logger.log(s\"\"\"⚙️ Inheritance check: ${self.repr} <?< ${other.repr}\n                  |⚡️bases: ${LTTRenderables.Long.renderDb(basesdb)}\n                  |⚡️inheritance: ${LTTRenderables.Long.renderDb(idb)}\"\"\".stripMargin)\n\n    isChild(Ctx(logger, this))(st, ot)\n  }\n\n  private def isChild(ctx: Ctx)(selfT: LightTypeTagRef, thatT: LightTypeTagRef): Boolean = {\n    import ctx._\n    logger.log(s\"✴️ isChild: `${selfT.repr}` <:< `${thatT.repr}`, context = $ctx\")\n\n    val result = (selfT, thatT) match {\n      case (s, t) if s == t =>\n        true\n      case (s, _) if s == tpeNothing =>\n        true\n      case (s, _) if s == tpeNull =>\n        // TODO: we may want to check that in case of anyref target type is not a primitve (though why?)\n        true\n      case (_, t) if t == tpeAny || t == tpeAnyRef || t == tpeObject || t == tpeMatchable =>\n        // TODO: we may want to check that in case of anyref target type is not a primitve (though why?)\n        true\n\n      case (s: WildcardReference, t: WildcardReference) =>\n        s.boundaries match {\n          case Boundaries.Defined(_, top) =>\n            compareBounds(ctx)(top, t.boundaries)\n          case Boundaries.Empty =>\n            t.boundaries match {\n              case Boundaries.Defined(_, _) =>\n                false\n              case Boundaries.Empty =>\n                true\n            }\n        }\n      case (s: AppliedNamedReference, t: WildcardReference) =>\n        compareBounds(ctx)(s, t.boundaries)\n      case (s: Lambda, t: WildcardReference) =>\n        isChild(ctx.next())(s.output, t)\n      case (s: WildcardReference, t) =>\n        s.boundaries match {\n          case Boundaries.Defined(_, top) =>\n            ctx.next().isChild(top, t)\n          case Boundaries.Empty =>\n            s == t\n        }\n      // parameterized type\n      case (s: FullReference, t: FullReference) =>\n        compareParameterizedRefs(ctx)(s, t)\n\n      case (s: FullReference, t: NameReference) =>\n        any(\n          oneOfParameterizedParentsIsInheritedFrom(ctx)(s, t),\n          all(\n            compareBounds(ctx)(s, t.boundaries),\n            any(\n              oneOfUnparameterizedParentsIsInheritedFrom(ctx)(s.asName, t), // constructor inherits from rhs, where rhs is an unparameterized type\n//              outerLambdaParams.map(_.name).contains(t.ref.name), // lambda parameter may accept anything within bounds      // UNSOUND-LAMBDA-COMPARISON\n//              t.ref.maybeName.exists(outerDecls.map(_.name).contains), // refinement type decl may accept anything within bounds,\n              isInBoundsOfAnEqualBoundedAbstractType(s, t) // equal-bounded abstract type\n            )\n          )\n        )\n\n      case (s: NameReference, t: FullReference) =>\n        oneOfParameterizedParentsIsInheritedFrom(ctx)(s, t)\n\n      // unparameterized type\n      case (s: NameReference, t: NameReference) =>\n        val boundIsOk = compareBounds(ctx)(s, t.boundaries)\n        any(\n          boundIsOk && any(\n            oneOfParameterizedParentsIsInheritedFrom(ctx)(s, t),\n            oneOfUnparameterizedParentsIsInheritedFrom(ctx)(s, t),\n            // outerLambdaParams.map(_.name).contains(t.ref.name), // lambda parameter may accept anything within bounds       // UNSOUND-LAMBDA-COMPARISON\n//            t.ref.maybeName.exists(outerDecls.map(_.name).contains), // refinement decl may accept anything within bounds\n            isInBoundsOfAnEqualBoundedAbstractType(s, t) // equal-bounded abstract type\n          ),\n          s.boundaries match {\n            case Boundaries.Defined(_, sUp) =>\n              ctx.isChild(sUp, t)\n            case Boundaries.Empty =>\n              false\n          }\n        )\n\n      // lambdas\n      case (s: AppliedNamedReference, t: Lambda) =>\n        isChild(ctx.next())(s, t.output)\n      case (s: Lambda, t: AppliedNamedReference) =>\n        isChild(ctx.next())(s.output, t)\n      case (s: Lambda, o: Lambda) =>\n        (s.input.size == o.input.size\n          && isChild(ctx.next())(s.normalizedOutput, o.normalizedOutput))\n\n      // intersections\n      case (s: IntersectionReference, t: IntersectionReference) =>\n        // yeah, this shit is quadratic\n        t.refs.forall {\n          p =>\n            s.refs.exists {\n              c =>\n                ctx.isChild(c, p)\n            }\n        }\n      case (s: IntersectionReference, t: LightTypeTagRef) =>\n        s.refs.exists(c => ctx.isChild(c, t))\n      case (s: LightTypeTagRef, o: IntersectionReference) =>\n        o.refs.forall(t => ctx.isChild(s, t))\n\n      // unions\n      case (s: UnionReference, t: UnionReference) =>\n        // yeah, this shit is quadratic\n        s.refs.forall {\n          c =>\n            t.refs.exists {\n              p =>\n                ctx.isChild(c, p)\n            }\n        }\n      case (s: UnionReference, t: LightTypeTagRef) =>\n        s.refs.forall(c => ctx.isChild(c, t))\n      case (s: LightTypeTagRef, o: UnionReference) =>\n        o.refs.exists(t => ctx.isChild(s, t))\n\n      // refinements\n      case (s: Refinement, t: Refinement) =>\n        ctx.isChild(s.reference, t.reference) && compareDecls(ctx.next())(s.decls, t.decls)\n      case (s: Refinement, t: LightTypeTagRef) =>\n        ctx.isChild(s.reference, t)\n      case (s: AbstractReference, t: Refinement) =>\n        oneOfParameterizedParentsIsInheritedFrom(ctx)(s, t)\n    }\n    logger.log(s\"${if (result) \"✅\" else \"⛔️\"} isChild: `${selfT.repr}` <:< `${thatT.repr}` == $result\")\n    result\n  }\n\n  private def compareBounds(ctx: Ctx)(s: AbstractReference, t: Boundaries): Boolean = {\n    t match {\n      case Boundaries.Defined(tLow, tUp) =>\n        ctx.isChild(s, tUp) && ctx.isChild(tLow, s)\n      case Boundaries.Empty =>\n        true\n    }\n  }\n\n  private def compareDecls(ctx: Ctx)(sDecls: Set[RefinementDecl], tDecls: Set[RefinementDecl]): Boolean = {\n    val s = sDecls.groupBy(_.name)\n    // for every decl on the right there's a <: decl on the left\n    tDecls.forall {\n      r =>\n        val lOverrides = s.get(r.name).toSet.flatten\n        lOverrides.exists(compareDecl(ctx)(_, r))\n    }\n  }\n\n  private def compareDecl(ctx: Ctx)(s: RefinementDecl, t: RefinementDecl): Boolean = (s, t) match {\n    case (\n          RefinementDecl.TypeMember(ln, lref),\n          RefinementDecl.TypeMember(rn, NameReference(SymName.SymTypeName(rn1), rBounds, None))\n        ) if rn == rn1 =>\n      // we're comparing two abstract types type X = X|>:A<:B|\n      // We know that the type is abstract if its name matches the type member's name\n      ln == rn && compareBounds(ctx)(lref, rBounds)\n    case (RefinementDecl.TypeMember(ln, lref), RefinementDecl.TypeMember(rn, rref)) =>\n      // if the rhs type is not abstract (has form `type X = Int`), then lhs must be exactly equal to it, not <:\n      ln == rn && lref == rref\n    case (RefinementDecl.Signature(ln, lins, lout), RefinementDecl.Signature(rn, rins, rout)) =>\n      (ln == rn\n        && lins.iterator.zipAll(rins.iterator, null, null).forall {\n          case (null, _) => false\n          case (_, null) => false\n          case (l, r) => ctx.isChild(r, l) // contravariant\n        }\n        && ctx.isChild(lout, rout)) // covariant\n    case _ =>\n      false\n  }\n\n  private def compareParameterizedRefs(ctx: Ctx)(self: FullReference, that: FullReference): Boolean = {\n\n    def parametersConform: Boolean = {\n      self.parameters.zipAll(that.parameters, null, null).forall {\n        case (ps, pt) =>\n          (ps ne null) && (pt ne null) && (pt.variance match {\n            case Variance.Invariant =>\n              pt.ref match {\n                case wc: LightTypeTagRef.WildcardReference =>\n                  compareBounds(ctx)(ps.ref, wc.boundaries)\n                case _ =>\n                  ps.ref == pt.ref\n              }\n\n            case Variance.Contravariant =>\n              pt.ref match {\n                case wc: LightTypeTagRef.WildcardReference =>\n                  wc.boundaries match {\n                    case Boundaries.Defined(bottom, _) =>\n                      ctx.isChild(bottom, ps.ref)\n\n                    case Boundaries.Empty =>\n                      true\n                  }\n                case _ =>\n                  ctx.isChild(pt.ref, ps.ref)\n              }\n\n            case Variance.Covariant =>\n              pt.ref match {\n                case wc: LightTypeTagRef.WildcardReference =>\n                  wc.boundaries match {\n                    case Boundaries.Defined(_, top) =>\n                      ctx.isChild(ps.ref, top)\n\n                    case Boundaries.Empty =>\n                      true\n                  }\n                case _ =>\n                  ctx.isChild(ps.ref, pt.ref)\n              }\n          })\n      }\n    }\n\n    val selfNameRef = self.asName\n    val thatNameRef = that.asName\n\n    ctx\n      .logger.log(\n        s\"⚠️ comparing parameterized references: `${self.repr}` <:< `${that.repr}`, paramsOk = $parametersConform, ctorsOk = ${selfNameRef == thatNameRef}, sameArity = ${self.parameters.size == that.parameters.size}, context = $ctx\"\n      )\n\n    if (selfNameRef == thatNameRef) {\n      parametersConform\n    } else if (oneOfParameterizedParentsIsInheritedFrom(ctx)(self, that)) {\n      true\n    } else {\n      val selfNormalizedLambdaParamsSize = {\n        // 0 unless we're in a lambda vs. lambda comparison (s.normalizedOutput <:< t.normalizedOutput)\n        self.parameters.count(p => isFakeParam(p.ref))\n      }\n      val appliedLambdaParents = basesdb\n        .iterator.collect {\n          case (l: Lambda, lparents) if isSameNamedRef(l.output, selfNameRef) =>\n            lparents.flatMap {\n              case lp: Lambda =>\n                val scala2FullDbFormLambda = {\n                  if (lp.input.size == self.parameters.size) {\n                    List(lp.combine(self.parameters.map(_.ref)))\n                  } else {\n                    Nil\n                  }\n                }\n                val scala3FullDbFormLambda = if (lp.input.size == selfNormalizedLambdaParamsSize) {\n                  val ps = self.parameters.collect { case FakeParam(pRef) => pRef }\n                  val selfPs = ps.sortBy(_.ref.asInstanceOf[SymName.LambdaParamName].index)\n                  val res = lp.combine(selfPs)\n                  List(res)\n                } else Nil\n                scala2FullDbFormLambda ++ scala3FullDbFormLambda\n              case _ =>\n                Nil\n            }\n        }.flatten.toList\n      ctx.logger.log {\n        s\"ℹ️ checking applied lambda parents of self=`${self.repr}`: parents=${appliedLambdaParents.map(_.repr)} <:< that=`${that.repr}`\"\n      }\n      appliedLambdaParents.exists(ctx.isChild(_, that))\n    }\n  }\n\n  private def isSameNamedRef(a: AbstractReference, b: AbstractReference): Boolean = {\n    (a, b) match {\n      case (an: AppliedNamedReference, ab: AppliedNamedReference) =>\n        an.asName == ab.asName\n      case _ =>\n        false\n    }\n  }\n\n  def isFakeParam(reference: LightTypeTagRef.AbstractReference): Boolean = reference match {\n    case reference: NameReference =>\n      reference.symName match {\n        case l: SymName.LambdaParamName if l.depth == LightTypeTagRef.LambdaConstants.lambdaFakeParamDepth => true\n        case _ => false\n      }\n    case _ => false\n  }\n\n  object FakeParam {\n    def unapply(tparam: TypeParam): Option[LightTypeTagRef.NameReference] = {\n      if (isFakeParam(tparam.ref)) Some(tparam.ref.asInstanceOf[NameReference]) else None\n    }\n  }\n\n  private def parameterizedParentsOf(t: AbstractReference): Set[AbstractReference] = {\n    val basesDbParents = basesdb.getOrElse(t, Set.empty)\n    val withBoundaryParents = t match {\n      case NameReference(_, b: Boundaries.Defined, _) =>\n        basesDbParents + b.top\n      case WildcardReference(b: Boundaries.Defined) =>\n        basesDbParents + b.top\n      case _ =>\n        basesDbParents\n    }\n    withBoundaryParents\n  }\n\n  private def oneOfParameterizedParentsIsInheritedFrom(ctx: Ctx)(child: AbstractReference, parent: AbstractReference): Boolean = {\n//    ctx.logger.log(s\"Checking if ${parameterizedParentsOf(child)} has a parent of $parent\")\n    val parents = parameterizedParentsOf(child)\n    ctx.logger.log(s\"Looking up parameterized parents of $child => $parents\")\n    parents.exists(ctx.isChild(_, parent))\n  }\n\n  private def oneOfUnparameterizedParentsIsInheritedFrom(ctx: Ctx)(child: NameReference, parent: NameReference): Boolean = {\n    val parents = unparameterizedParentsOf(child)\n    ctx.logger.log(s\"Looking up unparameterized parents of $child => $parents\")\n    parents.exists(ctx.isChild(_, parent))\n  }\n\n  private def isInBoundsOfAnEqualBoundedAbstractType(child: AbstractReference, parent: NameReference): Boolean = {\n    parent.boundaries match {\n      case Boundaries.Defined(bottom, top) if top == bottom && top == child => true\n      case _ => false\n    }\n  }\n\n  private def unparameterizedParentsOf(t: NameReference): mutable.HashSet[NameReference] = {\n    def parentsOf(t: NameReference, out: mutable.HashSet[NameReference], tested: mutable.HashSet[NameReference]): Unit = {\n      val direct = idb.get(t).toSet.flatten\n      tested += t\n      out ++= direct\n\n      val nextNames = direct.map(_.asName)\n      nextNames\n        .diff(tested)\n        .foreach {\n          b =>\n            parentsOf(b.asName, out, tested)\n        }\n    }\n\n    val out = mutable.HashSet[NameReference]()\n    val tested = mutable.HashSet[NameReference]()\n    parentsOf(t, out, tested)\n    out\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/LightTypeTagRef.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.macrortti.LightTypeTagRef.{AbstractReference, AppliedReference}\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.{LambdaParamName, SymTypeName}\n\nimport scala.runtime.AbstractFunction3\nimport scala.util.hashing.MurmurHash3\nimport scala.util.{Failure, Success, Try}\n\nsealed trait LightTypeTagRef extends LTTSyntax with Serializable {\n\n  // bincompat with versions before 2.3.0\n  final def combine(args: Seq[LightTypeTagRef]): AbstractReference = this.combineImpl(args)\n  final def combineNonPos(args: Seq[Option[LightTypeTagRef]]): AbstractReference = this.combineNonPosImpl(args)\n  final def withoutArgs: AbstractReference = this.withoutArgsImpl\n  /** Render to string, omitting package names */\n  override final def toString: String = this.toStringImpl\n  /** Fully-qualified rendering of a type, including packages and prefix types.\n    * Use [[toString]] for a rendering that omits package names\n    */\n  final def repr: String = this.reprImpl\n  final def scalaStyledRepr: String = this.scalaStyledReprImpl\n  @deprecated(\"Renamed to scalaStyledRepr\", \"3.0.8\")\n  final def scalaStyledName: String = this.scalaStyledReprImpl\n  final def shortName: String = this.shortNameImpl\n  final def longNameWithPrefix: String = this.longNameWithPrefixImpl\n  final def longNameInternalSymbol: String = this.longNameInternalSymbolImpl\n  @deprecated(\n    \"Produces Scala version dependent output, with incorrect prefixes for types with value prefixes. Use `longNameWithPrefix` instead, or `longNameInternalSymbol` for old behavior\",\n    \"2.2.2\"\n  )\n  final def longName: String = this.longNameInternalSymbolImpl\n  final def getPrefix: Option[AppliedReference] = this.getPrefixImpl\n  final def typeArgs: List[AbstractReference] = this.typeArgsImpl\n  /** decompose intersection type */\n  final def decompose: Set[LightTypeTagRef.AppliedReferenceExceptIntersection] = this.decomposeImpl\n  final def decomposeUnion: Set[LightTypeTagRef.AppliedReferenceExceptUnion] = this.decomposeUnionImpl\n\n}\n\nobject LightTypeTagRef extends LTTOrdering {\n  import LTTRenderables.Short._\n//  import LTTRenderables.Long._\n\n  sealed trait AbstractReference extends LightTypeTagRef\n\n  // bincompat only\n  private[macrortti] sealed abstract class LambdaParameter {\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    private[macrortti] def name: String\n  }\n  @deprecated(\"bincompat only\", \"20.02.2023\")\n  private[macrortti] object LambdaParameter extends (String => LambdaParameter) {\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    def apply(name: String): LambdaParameter = {\n      SymName.bincompatForceCreateLambdaParamNameFromString(name)\n    }\n  }\n\n  final case class Lambda(input: List[SymName.LambdaParamName], output: AbstractReference) extends AbstractReference {\n    override def hashCode(): Int = {\n      normalizedOutput.hashCode()\n    }\n\n    lazy val inputSize: Int = input.size\n    lazy val paramRefs: Set[NameReference] = input\n      .iterator.map {\n        n =>\n          // No boundary on paramRefs\n          // FIXME LambdaParameter should contain bounds and NameReference shouldn't\n          //       (Except possibly lower bound of an abstract/opaque type member)\n          NameReference(n)\n      }.toSet\n    lazy val referenced: Set[NameReference] = RuntimeAPI.unpack(this)\n    def allArgumentsReferenced: Boolean = paramRefs.diff(referenced).isEmpty\n    lazy val someArgumentsReferenced: Boolean = {\n      val unusedParamsSize = paramRefs.diff(referenced).size\n      unusedParamsSize < paramRefs.size\n    }\n\n    lazy val normalizedParams: List[NameReference] = makeFakeParams.map(_._2)\n    lazy val normalizedOutput: AbstractReference = RuntimeAPI.applyLambda(this, makeFakeParams)\n\n    override def equals(obj: Any): Boolean = {\n      obj match {\n        case l: Lambda =>\n          inputSize == l.inputSize &&\n          (normalizedOutput == l.normalizedOutput)\n\n        case _ =>\n          false\n      }\n    }\n\n    private[this] def makeFakeParams: List[(LambdaParamName, NameReference)] = {\n      input.zipWithIndex.map {\n        case (p, idx) =>\n          p -> NameReference(SymName.LambdaParamName(idx, LightTypeTagRef.LambdaConstants.lambdaFakeParamDepth, inputSize)) // s\"!FAKE_$idx\"\n      }\n    }\n  }\n\n  object LambdaConstants {\n    final val defaultContextId = -1\n    final val lambdaFakeParamDepth: Int = -2 // depth is always positive, unless fake\n    final val tagMacro = -3\n  }\n\n  sealed trait AppliedReference extends AbstractReference\n\n  sealed trait AppliedReferenceExceptIntersection extends AppliedReference\n  sealed trait AppliedReferenceExceptUnion extends AppliedReference\n\n  final case class IntersectionReference(refs: Set[AppliedReferenceExceptIntersection]) extends AppliedReferenceExceptUnion {\n    override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this)\n  }\n\n  final case class WildcardReference(boundaries: Boundaries) extends AppliedReferenceExceptIntersection with AppliedReferenceExceptUnion\n\n  final case class UnionReference(refs: Set[AppliedReferenceExceptUnion]) extends AppliedReferenceExceptIntersection {\n    override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this)\n  }\n\n  final case class Refinement(reference: AppliedReference, decls: Set[RefinementDecl]) extends AppliedReferenceExceptIntersection with AppliedReferenceExceptUnion {\n    override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this)\n  }\n\n  def isIgnored[T <: AbstractReference](t: T): Boolean = {\n    t match {\n      case a: AppliedReference =>\n        ignored.contains(a)\n      case _: Lambda =>\n        false\n    }\n  }\n\n  private[reflect] def ignored[T >: NameReference]: Set[T] = ignored0.asInstanceOf[Set[T]]\n  private[this] val ignored0: Set[NameReference] = Set[NameReference](\n    LightTypeTagInheritance.tpeAny,\n    LightTypeTagInheritance.tpeMatchable,\n    LightTypeTagInheritance.tpeAnyRef,\n    LightTypeTagInheritance.tpeObject\n  )\n\n  def maybeIntersection(refs0: Iterator[_ <: LightTypeTagRef]): AppliedReference = {\n    val refs = refs0.flatMap(_.decompose).toSet // flatten nested intersections\n    if (refs.size == 1) {\n      refs.head\n    } else {\n      val normalized = refs.diff(ignored)\n      if (normalized.isEmpty) {\n        LightTypeTagInheritance.tpeAny\n      } else if (normalized.size == 1) {\n        normalized.head\n      } else {\n        IntersectionReference(normalized)\n      }\n    }\n  }\n\n  def maybeUnion(refs0: Iterator[_ <: LightTypeTagRef]): AppliedReference = {\n    val refs = refs0.flatMap(_.decomposeUnion).toSet // flatten nested unions\n    val normalized = refs -- Set(LightTypeTagInheritance.tpeNothing, LightTypeTagInheritance.tpeNull)\n    val superTypes = normalized.intersect(ignored)\n    if (superTypes.nonEmpty) {\n      if (normalized.contains(LightTypeTagInheritance.tpeAny)) LightTypeTagInheritance.tpeAny\n      else if (normalized.contains(LightTypeTagInheritance.tpeMatchable)) LightTypeTagInheritance.tpeMatchable\n      else if (normalized.contains(LightTypeTagInheritance.tpeAnyRef)) LightTypeTagInheritance.tpeAnyRef\n      else if (normalized.contains(LightTypeTagInheritance.tpeObject)) LightTypeTagInheritance.tpeObject\n      else superTypes.head\n    } else {\n      if (normalized.isEmpty) {\n        LightTypeTagInheritance.tpeNothing\n      } else if (normalized.size == 1) {\n        normalized.head\n      } else {\n        UnionReference(normalized)\n      }\n    }\n  }\n\n  def maybeIntersection(r: Set[_ <: LightTypeTagRef]): AppliedReference = maybeIntersection(r.iterator)\n  def maybeUnion(r: Set[_ <: LightTypeTagRef]): AppliedReference = maybeUnion(r.iterator)\n\n  sealed trait AppliedNamedReference extends AppliedReferenceExceptIntersection with AppliedReferenceExceptUnion {\n    def asName: NameReference\n    def symName: SymName\n    def prefix: Option[AppliedReference]\n  }\n\n  final case class NameReference(\n    ref: SymName,\n    boundaries: Boundaries = Boundaries.Empty, // Quirk, we only need it to use NameReferences as Lambda parameters\n    prefix: Option[AppliedReference] = None\n  ) extends AppliedNamedReference {\n    override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this)\n\n    override def asName: NameReference = this\n    override def symName: SymName = ref\n  }\n  object NameReference {\n    @deprecated(\"Use SymName explicitly\", \"20.02.2023\")\n    private[NameReference] def apply(tpeName: String): NameReference = NameReference(SymTypeName(tpeName))\n  }\n\n  final case class FullReference(\n    symName: SymName,\n    parameters: List[TypeParam],\n    prefix: Option[AppliedReference] = None\n  ) extends AppliedNamedReference {\n    override lazy val hashCode: Int = scala.runtime.ScalaRunTime._hashCode(this)\n\n    override def asName: NameReference = NameReference(symName, boundaries = Boundaries.Empty, prefix = prefix)\n\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    private[LightTypeTagRef] def ref: String = SymName.forceName(symName)\n\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    private[LightTypeTagRef] def this(ref: String, parameters: List[TypeParam], prefix: Option[AppliedReference]) = {\n      this(SymName.SymTypeName(ref), parameters, prefix)\n    }\n\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    private[LightTypeTagRef] def copy(ref: String, parameters: List[TypeParam], prefix: Option[AppliedReference]): FullReference = {\n      this.copy(SymName.SymTypeName(ref), parameters, prefix)\n    }\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    private[LightTypeTagRef] def copy$default$1: String = ref\n\n    def copy(symName: SymName = symName, parameters: List[TypeParam] = parameters, prefix: Option[AppliedReference] = prefix): FullReference = {\n      new FullReference(symName, parameters, prefix)\n    }\n\n  }\n  object FullReference extends /*bincompat*/ AbstractFunction3[String, List[TypeParam], Option[AppliedReference], FullReference] {\n    @deprecated(\"bincompat only\", \"20.02.2023\")\n    override def apply(ref: String, parameters: List[TypeParam], prefix: Option[AppliedReference]): FullReference = {\n      new FullReference(SymName.SymTypeName(ref), parameters, prefix)\n    }\n  }\n\n  final case class TypeParam(\n    ref: AbstractReference,\n    variance: Variance // Quirk, we only need it to simplify/speedup inheritance checks\n  ) {\n    override def toString: String = this.render()\n  }\n\n  sealed trait RefinementDecl {\n    def name: String\n  }\n  object RefinementDecl {\n    final case class Signature(name: String, input: List[AppliedReference], output: AppliedReference) extends RefinementDecl\n    final case class TypeMember(name: String, ref: AbstractReference) extends RefinementDecl\n  }\n\n  sealed trait Variance {\n    override final def toString: String = this.render()\n  }\n  object Variance {\n    case object Invariant extends Variance\n    case object Contravariant extends Variance\n    case object Covariant extends Variance\n  }\n\n  sealed trait Boundaries {\n    override final def toString: String = this.render()\n  }\n  object Boundaries {\n    final case class Defined(bottom: AbstractReference, top: AbstractReference) extends Boundaries\n    case object Empty extends Boundaries\n  }\n\n  // this name isn't correct anymore but we keep it here for historical reasons. In fact that should be Symbol or SymRef\n  sealed trait SymName {\n    // bincompat only\n    private[macrortti] def name: String\n  }\n  object SymName {\n    final case class LambdaParamName(index: Int, depth: Int, arity: Int) extends LambdaParameter with SymName {\n      @deprecated(\"bincompat only\", \"20.02.2023\")\n      private[macrortti] override def name: String = SymName.forceName(this)\n    }\n\n    sealed trait NamedSymbol extends SymName {\n      def name: String\n    }\n    final case class SymTermName(name: String) extends NamedSymbol\n    final case class SymTypeName(name: String) extends NamedSymbol\n    final case class SymLiteral(name: String) extends NamedSymbol\n\n    object SymLiteral {\n      def apply(c: Any): SymLiteral = {\n        val constant = c match {\n          case s: String => \"\\\"\" + s + \"\\\"\"\n          case o => o.toString\n        }\n        SymLiteral(constant)\n      }\n    }\n\n    implicit final class SymNameExt(private val name: SymName) extends AnyVal {\n      def maybeName: Option[String] = name match {\n        case symbol: SymName.NamedSymbol => Some(symbol.name)\n        case _: SymName.LambdaParamName => None\n      }\n    }\n\n    private[macrortti] def forceName(symName: SymName): String = {\n      symName match {\n        case symbol: SymName.NamedSymbol => symbol.name\n        case lpn: LambdaParamName => LTTRenderables.Long.r_LambdaParameterName.render(lpn)\n      }\n    }\n\n    private[macrortti] def bincompatForceCreateLambdaParamNameFromString(str: String): LambdaParamName = {\n      val (numericIndexFromString, numericContextFromString) = {\n        val parts = str.split(':')\n        val fst = Try(parts(0).toInt)\n        val snd = Try(parts(1).toInt)\n        (fst, snd) match {\n          case (Success(idx), Failure(_)) =>\n            (idx, -10)\n          case (Success(ctx), Success(idx)) =>\n            (idx, ctx)\n          case _ =>\n            // use MurmurHash as it promises 'high-quality'\n            (MurmurHash3.stringHash(str), -10)\n        }\n      }\n      LambdaParamName(numericIndexFromString, numericContextFromString, -10)\n    }\n\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala/izumi/reflect/macrortti/RuntimeAPI.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.internal.NowarnCompat\nimport izumi.reflect.internal.fundamentals.platform.language.unused\nimport izumi.reflect.macrortti.LightTypeTagRef._\n\nobject RuntimeAPI {\n\n  def unpack(ref: AbstractReference): Set[NameReference] = {\n    def unpackBoundaries(b: Boundaries): Set[NameReference] = {\n      b match {\n        case Boundaries.Defined(bottom, top) =>\n          unpack(bottom) ++ unpack(top)\n        case Boundaries.Empty =>\n          Set.empty\n      }\n    }\n\n    ref match {\n      case Lambda(_, output) =>\n        unpack(output)\n      case reference: AppliedReference =>\n        reference match {\n          case reference: AppliedNamedReference =>\n            reference match {\n              case n: NameReference =>\n                Set(n.copy(prefix = None, boundaries = Boundaries.Empty)) ++ n.prefix.toSet.flatMap(unpack) ++ unpackBoundaries(n.boundaries)\n              case f: FullReference =>\n                f.parameters.iterator.map(_.ref).flatMap(unpack).toSet ++ f.prefix.toSet.flatMap(unpack) + f.asName\n            }\n          case _: WildcardReference =>\n            Set.empty\n          case IntersectionReference(refs) =>\n            refs.flatMap(unpack)\n          case UnionReference(refs) =>\n            refs.flatMap(unpack)\n          case Refinement(reference, decls) =>\n            unpack(reference) ++ decls.flatMap(\n              d =>\n                d match {\n                  case RefinementDecl.Signature(_, input, output) =>\n                    unpack(output) ++ input.flatMap(unpack)\n                  case RefinementDecl.TypeMember(_, ref) =>\n                    unpack(ref)\n                }\n            )\n        }\n    }\n  }\n\n  def applyLambda(lambda: Lambda, parameters: Seq[(SymName.LambdaParamName, AbstractReference)]): AbstractReference = {\n\n    val paramMap = parameters.toMap\n\n    val rewriter = new Rewriter(paramMap)\n    val replaced = rewriter.replaceRefs(lambda.output)\n\n    // fix for #82, #83\n    // the old logic was ill, it was causing incorrect replacements when names from substitutions were clashing with replacement map\n    // in fact that was a broken workaround for the lack of recursion in Rewriter\n\n    //    val replaced = parameters.foldLeft(lambda.output) {\n    //      case (acc, p) =>\n    //        val rewriter = new Rewriter(Map(p))\n    //        rewriter.replaceRefs(acc)\n    //    }\n\n    val newParams = lambda.input.filterNot(paramMap.contains)\n    val res = if (newParams.isEmpty) {\n      replaced\n    } else {\n      val out = Lambda(newParams, replaced)\n      // assert(out.allArgumentsReferenced, s\"bad lambda: $out, ${out.paramRefs}, ${out.referenced}\")\n      // such lambdas are legal: see \"regression test: combine Const Lambda to TagK\"\n      out\n    }\n\n    res\n  }\n\n  final class Rewriter(_rules: Map[SymName.LambdaParamName, AbstractReference]) {\n    private val rules: Map[SymName, AbstractReference] = _rules.toMap\n\n    def complete(@unused context: AppliedNamedReference, ref: AbstractReference): AbstractReference = {\n      ref\n    }\n\n    @NowarnCompat.nowarn(\"msg=deprecated\")\n    def replaceRefs(reference: AbstractReference): AbstractReference = {\n      reference match {\n        case l: Lambda =>\n          val bad = l.input.iterator.toSet\n          val fixed = new Rewriter(_rules.filterKeys(!bad.contains(_)).iterator.toMap).replaceRefs(l.output)\n          l.copy(output = fixed)\n\n        case o: AppliedReference =>\n          replaceApplied(o)\n      }\n    }\n\n    def replacePrefix(prefix: Option[AppliedReference]): Option[AppliedReference] = {\n      prefix.map(p => ensureApplied(p, replaceApplied(p)))\n    }\n\n    def replaceBoundaries(boundaries: Boundaries): Boundaries = {\n      boundaries match {\n        case Boundaries.Defined(bottom, top) =>\n          Boundaries.Defined(replaceRefs(bottom), replaceRefs(top))\n        case Boundaries.Empty =>\n          boundaries\n      }\n    }\n\n    private def replaceApplied(reference: AppliedReference): AbstractReference = {\n      reference match {\n        case IntersectionReference(refs) =>\n          val replaced = refs.map(replaceApplied).map(ensureApplied(reference, _))\n          maybeIntersection(replaced)\n        case UnionReference(refs) =>\n          val replaced = refs.map(replaceApplied).map(ensureApplied(reference, _))\n          maybeUnion(replaced)\n        case WildcardReference(boundaries) =>\n          WildcardReference(replaceBoundaries(boundaries))\n        case Refinement(base, decls) =>\n          val rdecls = decls.map {\n            case RefinementDecl.Signature(name, input, output) =>\n              RefinementDecl.Signature(name, input.map(p => ensureApplied(reference, replaceRefs(p))), ensureApplied(reference, replaceRefs(output))): RefinementDecl\n            case RefinementDecl.TypeMember(name, ref) =>\n              RefinementDecl.TypeMember(name, replaceRefs(ref)): RefinementDecl\n          }\n\n          Refinement(ensureApplied(base, replaceApplied(base)), rdecls)\n        case n: AppliedNamedReference =>\n          replaceNamed(n)\n      }\n    }\n\n    private def replaceNamed(reference: AppliedNamedReference): AbstractReference = {\n      def returnFullRef(fixedRef: SymName, parameters: List[TypeParam], prefix: Option[AppliedReference]): FullReference = {\n        val p = parameters.map {\n          case TypeParam(pref, variance) =>\n            TypeParam(replaceRefs(pref), variance)\n        }\n        FullReference(fixedRef, p, prefix)\n      }\n\n      reference match {\n        case n @ NameReference(ref, boundaries, prefix) =>\n          rules.get(ref) match {\n            case Some(value) =>\n              complete(n, value)\n            case None =>\n              NameReference(ref, replaceBoundaries(boundaries), replacePrefix(prefix))\n          }\n\n        case f @ FullReference(ref, parameters, prefix) =>\n          rules.get(ref) match {\n            case Some(value) =>\n              complete(f, value) match {\n                case out: Lambda =>\n                  val refs = parameters.map(_.ref)\n                  val res = replaceRefs(out.applySeq(refs)) // fix for #82, #83\n                  res\n\n                case n: NameReference =>\n                  // we need this to support fakes only (see LightTypeTagRef#makeFakeParams)\n                  returnFullRef(n.ref, parameters, prefix)\n\n                case out =>\n                  throw new IllegalStateException(s\"Lambda expected for context-bound $f, but got $out\")\n\n              }\n            case None =>\n              returnFullRef(ref, parameters, prefix)\n          }\n\n      }\n    }\n\n    private def ensureApplied(context: AbstractReference, ref: AbstractReference): AppliedReference = {\n      ref match {\n        case reference: AppliedReference =>\n          reference\n        case o =>\n          throw new IllegalStateException(s\"Expected applied reference but got $o while processing $context\")\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/AnnotationTools.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport scala.reflect.api.Universe\n\nprivate[reflect] object AnnotationTools {\n  def findArgument[A](ann: Universe#Annotation)(matcher: PartialFunction[Universe#Tree, A]): Option[A] =\n    ann.tree.children.tail.collectFirst(matcher)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/ReflectionUtil.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\n\nimport scala.annotation.tailrec\nimport scala.reflect.api.Universe\n\nprivate[reflect] object ReflectionUtil {\n\n  /** Mini `normalize`. `normalize` is deprecated and we don't want to do scary things such as evaluate type-lambdas anyway.\n    * And AFAIK the only case that can make us confuse a type-parameter for a non-parameter is an empty refinement `T {}`.\n    * So we just strip it when we get it.\n    */\n  // ReflectionUtil.norm but with added logging\n  @tailrec @inline\n  def norm(u: Universe, logger: TrivialLogger)(x: u.Type): u.Type = {\n    import u._\n    x match {\n      case RefinedType(t :: Nil, m) if m.isEmpty =>\n        logger.log(s\"Stripped empty refinement of type $t. member scope $m\")\n        norm(u, logger)(t)\n      case AnnotatedType(_, t) =>\n        norm(u, logger)(t)\n      case _ =>\n        x\n    }\n  }\n\n  def allPartsStrong(tpe: Universe#Type): Boolean = {\n    allPartsStrong(Set.empty, tpe)\n  }\n\n  def allPartsStrong(outerTypeParams: Set[Universe#Symbol], tpeRaw: Universe#Type): Boolean = {\n    val dealiased = tpeRaw.dealias\n    val selfStrong = isSelfStrong(outerTypeParams, dealiased) || outerTypeParams.contains(dealiased.typeSymbol)\n\n    dealiased match {\n      case t: Universe#RefinedTypeApi =>\n        t.parents.forall(allPartsStrong(outerTypeParams, _)) &&\n        t.decls.toSeq.forall((s: Universe#Symbol) => s.isTerm || allPartsStrong(outerTypeParams, s.asType.typeSignature.dealias))\n      case e: Universe#ExistentialTypeApi =>\n        allPartsStrong(outerTypeParams, e.underlying) &&\n        e.underlying.typeArgs.forall(\n            t =>\n              t.typeSymbol.typeSignature match {\n                case tb: Universe#TypeBoundsApi => allPartsStrong(outerTypeParams, tb.hi) && allPartsStrong(outerTypeParams, tb.lo)\n                case _ => allPartsStrong(outerTypeParams, t)\n              }\n          ) &&\n        e.quantified.forall((s: Universe#Symbol) => allPartsStrong(outerTypeParams, s.asType.typeSignature.dealias))\n      case _ =>\n        val resType = dealiased.finalResultType\n        if (dealiased.takesTypeArgs && !dealiased.typeParams.forall(outerTypeParams.contains)) {\n          allPartsStrong(outerTypeParams ++ dealiased.typeParams, resType)\n        } else {\n\n          def typeCtorStrong: Boolean = {\n            val ctor = resType.typeConstructor\n            (resType == dealiased) || (ctor == dealiased) || (ctor == tpeRaw) ||\n            outerTypeParams.contains(ctor.typeSymbol) || allPartsStrong(outerTypeParams, ctor)\n          }\n\n          def argsStrong: Boolean = {\n            resType.typeArgs.forall {\n              arg =>\n                outerTypeParams.contains(arg.typeSymbol) || allPartsStrong(outerTypeParams, arg)\n            }\n          }\n\n          selfStrong && /*prefixStrong &&*/ typeCtorStrong && argsStrong\n        }\n    }\n  }\n\n  def isSelfStrong(outerTypeParams: Set[Universe#Symbol], tpe: Universe#Type): Boolean = {\n    // FIXME: strengthening check to capture `IntersectionBlockingIO` test case causes StackOverflow during implicit search\n//    def intersectionMembersStrong = {\n//      tpe match {\n//        case t: Universe#RefinedTypeApi =>\n//          t.parents.forall(isSelfStrong)\n//        case _ => true\n//      }\n//    }\n\n    def prefixStrong: Boolean = {\n      tpe match {\n        case t: Universe#TypeRefApi =>\n          allPartsStrong(outerTypeParams, t.pre.dealias)\n        case _ =>\n          true\n      }\n    }\n\n    (prefixStrong && !(tpe.typeSymbol.isParameter || (\n      // we regard abstract types like T in trait X { type T; Tag[this.T] } - when we are _inside_ the definition template\n      // as 'type parameters' too. So that you could define `implicit def tagForT: Tag[this.T]` and the tag would be resolved\n      // to this implicit correctly, instead of generating a useless `X::this.type::T` tag.\n      isAbstractType(tpe) &&\n      tpe.asInstanceOf[Universe#TypeRefApi].pre.isInstanceOf[Universe#ThisTypeApi]\n    ))) /*&& intersectionMembersStrong*/ ||\n    isIdentityLikeTypeLambda(tpe)\n  }\n\n  def isAbstractType(tpe: Universe#Type): Boolean = {\n    tpe.isInstanceOf[Universe#TypeRefApi] && tpe.typeSymbol.isAbstract && !tpe.typeSymbol.isClass && isNotDealiasedFurther(tpe)\n  }\n\n  def isIdentityLikeTypeLambda(tpe: Universe#Type): Boolean = {\n    tpe.typeParams.exists { // is identity\n      t =>\n        t == tpe.typeSymbol ||\n        t.typeSignature == tpe.typeSymbol.typeSignature ||\n        (t.name eq tpe.typeSymbol.name)\n    }\n  }\n\n  def isNotDealiasedFurther(tpe: Universe#Type): Boolean = {\n    val u: Universe = null\n    val tpe1: u.Type = tpe.asInstanceOf[u.Type]\n    tpe1.dealias =:= tpe1\n  }\n\n  /** Represents the kind of a type, including bounds.\n    * @param params nested kinds for each type parameter\n    * @param bounds optional type bounds (None for default bounds Nothing..Any)\n    * @param symbol original type parameter symbol (for substitution during type construction)\n    */\n  final case class KindInfo[+U <: Universe](params: List[KindInfo[U]], bounds: Option[U#TypeBoundsApi], symbol: U#Symbol)\n  object KindInfo {\n    def ofType[U <: Universe with Singleton](tpe: U#Type): KindInfo[U] = {\n      KindInfo.of(tpe, tpe.typeSymbol)\n    }\n    def ofSymbol[U <: Universe with Singleton](sym: U#Symbol): KindInfo[U] = {\n      KindInfo.of(sym.typeSignature, sym)\n    }\n    def of[U <: Universe with Singleton](tpe: U#Type, sym: U#Symbol): KindInfo[U] = {\n      val bounds: Option[U#TypeBoundsApi] = tpe match {\n        case tb: U#TypeBoundsApi => Some(tb)\n        case pt: U#PolyTypeApi =>\n          pt.resultType match {\n            case tb: U#TypeBoundsApi => Some(tb)\n            case _ => None\n          }\n        case _ => None\n      }\n      KindInfo[U](tpe.typeParams.map(KindInfo.ofSymbol), bounds, sym)\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/ScalacSink.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport izumi.reflect.internal.fundamentals.platform.console.AbstractStringTrivialSink\n\nimport scala.reflect.macros.blackbox\n\nprivate[reflect] final class ScalacSink(c: blackbox.Context) extends AbstractStringTrivialSink {\n  override def flush(value: => String): Unit = {\n    c.info(c.enclosingPosition, value, force = true)\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/TagMacro.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport izumi.reflect.ReflectionUtil.KindInfo\nimport izumi.reflect.TagMacro._\nimport izumi.reflect.internal.NowarnCompat\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\nimport izumi.reflect.macrortti.LightTypeTagRef._\nimport izumi.reflect.macrortti.{LightTypeTag, LightTypeTagMacro0, LightTypeTagRef}\n\nimport scala.annotation.implicitNotFound\nimport scala.collection.immutable.ListMap\nimport scala.reflect.api.Universe\nimport scala.reflect.macros.{TypecheckException, blackbox, whitebox}\n\n// TODO: benchmark difference between searching all arguments vs. merge strategy\n// TODO: benchmark ProviderMagnet vs. identity macro vs. normal function\n@NowarnCompat.nowarn(\"msg=deprecated\")\nclass TagMacro(val c: blackbox.Context) {\n\n  import c.universe._\n\n  protected[this] val logger: TrivialLogger = TrivialMacroLogger.make[this.type](c)\n  private[this] val ltagMacro = new LightTypeTagMacro0[c.type](c)(logger)\n\n  // workaround for a scalac bug - `Nothing` type is lost when two implicits for it are summoned from one implicit as in:\n  //  implicit final def tagFromTypeTag[T](implicit t: TypeTag[T], l: LTag[T]): Tag[T] = Tag(t, l.fullLightTypeTag)\n  // https://github.com/scala/bug/issues/11715\n  final def makeTag[T: c.WeakTypeTag]: c.Expr[Tag[T]] = {\n    val tpe = weakTypeOf[T]\n    if (ReflectionUtil.allPartsStrong(tpe.dealias)) {\n      makeStrongTagImpl[T](tpe, implicitly[c.WeakTypeTag[T]])\n    } else {\n      makeWeakTagImpl[T](tpe, implicitly[c.WeakTypeTag[T]])\n    }\n  }\n\n  final def makeStrongTag[T: c.WeakTypeTag]: c.Expr[Tag[T]] = {\n    val tpe = weakTypeOf[T]\n    assert(ReflectionUtil.allPartsStrong(tpe.dealias))\n    makeStrongTagImpl[T](tpe, implicitly[c.WeakTypeTag[T]])\n  }\n\n  final def makeWeakTag[T: c.WeakTypeTag]: c.Expr[Tag[T]] = {\n    val tpe = weakTypeOf[T]\n    assert(!ReflectionUtil.allPartsStrong(tpe.dealias))\n    makeWeakTagImpl[T](tpe, implicitly[c.WeakTypeTag[T]])\n  }\n\n  @inline final def makeHKTagMaterializer[ArgStruct: c.WeakTypeTag]: c.Expr[HKTagMaterializer[ArgStruct]] = {\n    c.Expr[HKTagMaterializer[ArgStruct]](q\"new ${weakTypeOf[HKTagMaterializer[ArgStruct]]}(${makeHKTag[ArgStruct]})\")\n  }\n\n  @inline final def makeHKTag[ArgStruct](implicit argStructTag: c.WeakTypeTag[ArgStruct]): c.Expr[HKTag[ArgStruct]] = {\n    val argStruct = weakTypeOf[ArgStruct]\n    val ctor = ltagMacro.unpackArgStruct(argStruct)\n    if (ReflectionUtil.allPartsStrong(ctor)) {\n      logger.log(s\"HK: found Strong ctor=$ctor in ArgStruct, returning $argStruct\")\n      makeHKTagFromStrongTpe[ArgStruct](ctor)\n    } else {\n      makeHKTagImpl(ctor, argStructTag)\n    }\n  }\n\n  private def makeStrongTagImpl[T](tpe: c.Type, tag: c.WeakTypeTag[T]): c.Expr[Tag[T]] = {\n    logger.log(s\"Got strong tag, generating LTT right away: ${tag.tpe}\")\n    val ltag = ltagMacro.makeParsedLightTypeTagImpl(tpe)\n    val cls = closestClass(tpe)\n\n    {\n      // compiler always inserts WeakTypeTag, by passing it explicitly we slightly reduce fragility\n      implicit val itag: c.WeakTypeTag[T] = tag\n      c.Expr[Tag[T]] {\n        q\"_root_.izumi.reflect.Tag.apply[$tpe]($cls, $ltag)\"\n      }\n    }\n  }\n\n  private def makeWeakTagImpl[T](tpe: c.Type, tag: c.WeakTypeTag[T]): c.Expr[Tag[T]] = {\n    if (getImplicitError().endsWith(\":\")) { // yep\n      logger.log(s\"Got continuation implicit error: ${getImplicitError()}\")\n    } else {\n      resetImplicitError(tpe)\n      addImplicitError(\"\\n\\n<trace>: \")\n    }\n\n    val tgt = ReflectionUtil.norm(c.universe: c.universe.type, logger)(tpe.dealias)\n\n    logger.log(s\"Got non-strong tag: $tpe, dealiased: $tgt\")\n\n    addImplicitError(s\"  deriving Tag for $tpe, dealiased: $tgt:\")\n\n    val res = tgt match {\n      case RefinedType(intersection, _) =>\n        mkRefined[T](intersection, tgt, tag)\n      case _ =>\n        mkTagWithTypeParameters[T](tgt, tag)\n    }\n\n    addImplicitError(s\"  succeeded for: $tgt\")\n\n    logger.log(s\"Final code of Tag[$tpe] (dealiased $tgt):\\n ${showCode(res.tree)}\")\n\n    res\n  }\n\n  // FIXME: nearly a copypaste of mkTagWithTypeParameters, deduplicate?\n  private[this] def makeHKTagImpl[ArgStruct](outerLambda: Type, tag: c.WeakTypeTag[ArgStruct]): c.Expr[HKTag[ArgStruct]] = {\n    logger.log(s\"Got unresolved HKTag summon: ${tagFormat(outerLambda)} from ArgStruct: ${tag.tpe}\")\n\n    def isLambdaParamOf(arg: Type, lam: Type): Boolean = {\n      lam.typeParams.contains(arg.typeSymbol)\n    }\n\n    val lambdaResult = outerLambda.finalResultType\n    val ctorTpe = lambdaResult.typeConstructor\n    val typeArgsTpes = lambdaResult.typeArgs\n\n    val isSimplePartialApplication = {\n      // all parameters are consumed exactly once, in left-to-right order,\n      // but there could be type arguments applied to the left of parameters\n      typeArgsTpes\n        .map(_.typeSymbol)\n        .filter(outerLambda.typeParams.contains) == outerLambda.typeParams\n    }\n\n    val constructorTag: c.Expr[HKTag[_]] = {\n      // outer lambda is just a forwarding lambda `[A, B, C] =>> F[A, B, C]`, exactly equivalent to `F` itself\n      val outerLambdaEqualsCtorEtaExpand = {\n        isSimplePartialApplication &&\n        typeArgsTpes.corresponds(outerLambda.typeParams)(_.typeSymbol == _)\n      }\n\n      getCtorKindInfoIfCtorIsTypeParameter(ctorTpe) match {\n        // type constructor of this type is not a type parameter\n        // BUT can be an intersection type\n        // some of its arguments are type parameters that we should resolve\n        case None =>\n          logger.log(s\"HK type A ctor=$ctorTpe sym=${ctorTpe.typeSymbol}\")\n          makeHKTagFromStrongTpe[Any](ctorTpe)\n\n        // outerLambda is a simple forwarder `[A, B, C] =>> F[A, B, C]` AND `F` is a type parameter\n        // We can't progress here: we must find HKTag[F] to progress, but we ARE in the process of\n        // deriving HKTag[F], which means it doesn't already exist.\n        case Some(_) if outerLambdaEqualsCtorEtaExpand =>\n          logger.log(s\"HK type B (error) $ctorTpe ${ctorTpe.typeSymbol} - can't find tag for ctor=${showRaw(ctorTpe)}, etaExpand=${showRaw(outerLambda)}\")\n          val msg = s\"  could not find implicit value for ${tagFormat(lambdaResult)}: $lambdaResult is a type parameter without an implicit Tag!\"\n          addImplicitError(msg)\n          abortWithImplicitError()\n\n        // type constructor is a type parameter AND has type arguments\n        // we should resolve type constructor separately from an HKTag\n        case Some(hktKind) =>\n          logger.log(s\"HK type C $ctorTpe ${ctorTpe.typeSymbol}\")\n          summonHKTag(ctorTpe, hktKind)\n      }\n    }\n\n    val res = {\n      if (isSimplePartialApplication) {\n        val embeddedMaybeNonParamTypeArgs = typeArgsTpes.map {\n          arg => if (!isLambdaParamOf(arg, outerLambda)) Some(arg) else None\n        }\n        val argTags = {\n          // FIXME: create LTT in-place instead of summoning Tag if typeArg is Strong\n          logger.log(s\"HK Now summoning tags for args=$embeddedMaybeNonParamTypeArgs\")\n          val argExprs = embeddedMaybeNonParamTypeArgs.map(_.map {\n            t =>\n              val dealiased = ReflectionUtil.norm(c.universe: c.universe.type, logger)(t.dealias)\n              summonLightTypeTagOfAppropriateKind(dealiased)\n          })\n          c.Expr[List[Option[LightTypeTag]]](q\"$argExprs\")\n        }\n\n        {\n          // compiler always inserts WeakTypeTag, by passing it explicitly we slightly reduce fragility. quasiquotes implicitly use WTT\n          implicit val itag: c.WeakTypeTag[ArgStruct] = tag\n          reify {\n            HKTag.appliedTagNonPos[ArgStruct](constructorTag.splice, argTags.splice)\n          }\n        }\n      } else {\n        // warn if constructor is an intersection type, as they don't work properly in this position right now\n        lambdaResult match {\n          case t: RefinedTypeApi if t.parents.size > 1 =>\n            // info instead of warning because warnings are suppressed by Scala 2 inside implicit macros for some reason\n            c.info(\n              c.enclosingPosition,\n              s\"\"\"TODO: Pathological intersection refinement result in lambda being reconstructed result=`$lambdaResult` in the rhs of type lambda lam=`$outerLambda`\n                 |Only simple applied types of form F[A] are supported in results of type lambdas. The generated tag may not work correctly.\"\"\".stripMargin,\n              force = true\n            )\n          case _ =>\n        }\n\n        val PolyType(outerLambdaParamArgsSyms, _) = outerLambda: @unchecked\n\n        val distinctNonParamArgsTypes = typeArgsTpes.filter(!isLambdaParamOf(_, outerLambda)).distinct\n\n        val arity = distinctNonParamArgsTypes.size + outerLambdaParamArgsSyms.size + 1\n\n        val typeArgToLambdaParameterMap: Map[Either[Type, Symbol], SymName.LambdaParamName] =\n          // for non-lambda arguments the types are unique, but symbols are not, for lambda arguments the symbols are unique but types are not.\n          // it's very confusing.\n          (distinctNonParamArgsTypes.map(Left(_)) ++ outerLambdaParamArgsSyms.map(Right(_)))\n            .distinct.iterator.zipWithIndex.map {\n              case (argTpeOrSym, idx) =>\n                val idxPlusOne = idx + 1\n                val lambdaParameter = SymName.LambdaParamName(idxPlusOne, LightTypeTagRef.LambdaConstants.tagMacro, arity)\n                argTpeOrSym -> lambdaParameter\n            }.toMap\n\n        def getFromMap(k1: Either[Type, Symbol], k2: Either[Type, Symbol]): SymName.LambdaParamName = {\n          typeArgToLambdaParameterMap.getOrElse(\n            k1,\n            typeArgToLambdaParameterMap.getOrElse(\n              k2, {\n                val msg = s\"Problem: couldn't get a lambda parameter idx for k1=$k1 k2=$k2 in $typeArgToLambdaParameterMap\"\n                logger.log(msg)\n                c.abort(c.enclosingPosition, msg)\n              }\n            )\n          )\n        }\n\n        val usageOrderDistinctNonLambdaArgs = distinctNonParamArgsTypes.map(t => getFromMap(Left(t), Right(t.typeSymbol)))\n        val declarationOrderLambdaParamArgs = outerLambdaParamArgsSyms.map(sym => getFromMap(Right(sym), Left(sym.typeSignature)))\n\n        val usages = typeArgsTpes.map(t => TypeParam(NameReference(getFromMap(Left(t), Right(t.typeSymbol))), Variance.Invariant))\n\n        // we give a distinct lambda parameter to the constructor, even if constructor is one of the type parameters\n        val firstParamIdx = 0\n        val ctorLambdaParameter = SymName.LambdaParamName(firstParamIdx, LightTypeTagRef.LambdaConstants.tagMacro, arity)\n\n        val ctorApplyingLambda = LightTypeTagRef.Lambda(\n          ctorLambdaParameter :: usageOrderDistinctNonLambdaArgs ::: declarationOrderLambdaParamArgs,\n          FullReference(ctorLambdaParameter, usages)\n        )\n\n        logger.log(s\"\"\"HK non-trivial lambda construction:\n                      |ctorApplyingLambda=$ctorApplyingLambda\n                      |usageOrderNonLambdaArgs=$usageOrderDistinctNonLambdaArgs\n                      |declarationOrderLambdaParamArgs=$declarationOrderLambdaParamArgs\n                      |\"\"\".stripMargin)\n\n        val argTagsExceptCtor = {\n          val nonParamArgsDealiased = distinctNonParamArgsTypes.map(t => ReflectionUtil.norm(c.universe: c.universe.type, logger)(t.dealias))\n          logger.log(s\"HK COMPLEX Now summoning tags for args=$nonParamArgsDealiased outerLambdaParams=$outerLambdaParamArgsSyms\")\n\n          c.Expr[List[Option[LightTypeTag]]] {\n            q\"${nonParamArgsDealiased.map(t => Some(summonLightTypeTagOfAppropriateKind(t))) ++ outerLambdaParamArgsSyms.map(_ => None)}\"\n          }\n        }\n\n        val outerLambdaReprTag = ltagMacro.makeParsedLightTypeTagImpl(LightTypeTag(ctorApplyingLambda, Map.empty, Map.empty))\n\n        {\n          // compiler always inserts WeakTypeTag, by passing it explicitly we slightly reduce fragility. quasiquotes implicitly use WTT\n          implicit val itag: c.WeakTypeTag[ArgStruct] = tag\n          reify {\n            val ctorTag = constructorTag.splice\n            HKTag.appliedTagNonPosAux[ArgStruct](ctorTag.closestClass, outerLambdaReprTag.splice, Some(ctorTag.tag) :: argTagsExceptCtor.splice)\n          }\n        }\n      }\n    }\n\n    logger.log(s\"Final code of ${tagFormat(outerLambda)}:\\n ${showCode(res.tree)}\")\n\n    res\n  }\n\n  private[this] def makeHKTagFromStrongTpe[ArgStruct: c.WeakTypeTag](strongCtorType: Type): c.Expr[HKTag[ArgStruct]] = {\n    val ltag = ltagMacro.makeParsedLightTypeTagImpl(strongCtorType)\n    val cls = closestClass(strongCtorType)\n    c.Expr[HKTag[ArgStruct]] {\n      q\"_root_.izumi.reflect.HKTag.apply($cls, $ltag)\"\n    }\n  }\n\n  @inline\n  protected[this] def mkRefined[T](intersection: List[Type], originalRefinement: Type, tag: c.WeakTypeTag[T]): c.Expr[Tag[T]] = {\n    val summonedIntersectionTags = intersection.map {\n      t0 =>\n        val t = ReflectionUtil.norm(c.universe: c.universe.type, logger)(t0.dealias)\n        summonLightTypeTagOfAppropriateKind(t)\n    }\n    val intersectionTags = c.Expr[List[LightTypeTag]](Liftable.liftList[c.Expr[LightTypeTag]].apply(summonedIntersectionTags))\n    val (structTag, additionalTypeMembers) = mkStruct(intersection, originalRefinement)\n    val cls = closestClass(originalRefinement)\n\n    {\n      // compiler always inserts WeakTypeTag, by passing it explicitly we slightly reduce fragility\n      implicit val itag: c.WeakTypeTag[T] = tag\n      reify {\n        Tag.refinedTag[T](cls.splice, intersectionTags.splice, structTag.splice, additionalTypeMembers.splice)\n      }\n\n    }\n  }\n\n  @inline\n  protected[this] def mkStruct(intersection: List[Type], originalRefinement: Type): (c.Expr[LightTypeTag], c.Expr[Map[String, LightTypeTag]]) = {\n    val (strongDecls, weakDecls) = originalRefinement\n      .decls\n      .partition {\n        symbol =>\n          // skip resolution for types in methods/vals (that would need a new runtime constructor, `methodTag`, like `refinedTag` for the case & dealing with method type parameters may be non-trivial)\n          // also skip resolution for \"strong\" type members\n          // see: \"progression test: can't handle parameters in defs/vals in structural types\"\n          symbol.isTerm ||\n          ReflectionUtil.allPartsStrong(Set.empty, symbol.info)\n      }\n\n    val strongDeclsTpe = internal.refinedType(intersection, originalRefinement.typeSymbol.owner, internal.newScopeWith(strongDecls.toSeq: _*))\n\n    val resolvedTags = weakDecls.map {\n      symbol =>\n        symbol.name.decodedName.toString -> summonLightTypeTagOfAppropriateKind(symbol.info)\n    }.toMap\n    val resolvedTagsExpr = c.Expr[Map[String, LightTypeTag]](Liftable.liftMap[String, Expr[LightTypeTag]].apply(resolvedTags))\n\n    (ltagMacro.makeParsedLightTypeTagImpl(strongDeclsTpe), resolvedTagsExpr)\n  }\n\n  // we need to handle three cases – type args, refined types and type bounds (we don't handle type bounds currently)\n  @inline\n  protected[this] def mkTagWithTypeParameters[T](tpe: Type, tag: c.WeakTypeTag[T]): c.Expr[Tag[T]] = {\n    val constructorTag: c.Expr[HKTag[_]] = {\n      val ctor = tpe.typeConstructor\n      getCtorKindInfoIfCtorIsTypeParameter(ctor) match {\n        // type constructor of this type is not a type parameter\n        // AND not an intersection type\n        // some of its arguments are type parameters that we should resolve\n        case None =>\n          logger.log(s\"type A $ctor  ${ctor.typeSymbol}\")\n          makeHKTagFromStrongTpe[Any](ctor)\n\n        // error: the entire type is just a proper type parameter with no type arguments\n        case Some(k) if k.params.isEmpty =>\n          logger.log(s\"type B $ctor ${ctor.typeSymbol}\")\n          val msg = s\"  could not find implicit value for ${tagFormat(tpe)}: $tpe is a type parameter without an implicit Tag!\"\n          addImplicitError(msg)\n          abortWithImplicitError()\n\n        // type constructor is a type parameter AND has type arguments\n        // we should resolve type constructor separately from an HKTag\n        case Some(hktKind) =>\n          logger.log(s\"type C $ctor ${ctor.typeSymbol}\")\n          summonHKTag(ctor, hktKind)\n      }\n    }\n    val argTags = {\n      val args = tpe match {\n        // preserve wildcards in type arguments\n        case e: ExistentialTypeApi =>\n          val exts = e.quantified.toSet\n          e.underlying.typeArgs.map {\n            t =>\n              if (exts.contains(t.typeSymbol)) {\n                /// generate top-level existential type for LightTypeTagImpl macro\n                t.typeSymbol.typeSignature match {\n                  case tb: TypeBounds =>\n                    val lo = tb.lo\n                    val hi = tb.hi\n                    val loTag = summonLightTypeTagOfAppropriateKind(lo)\n                    val hiTag = summonLightTypeTagOfAppropriateKind(hi)\n                    reify {\n                      LightTypeTag.wildcardType(loTag.splice, hiTag.splice)\n                    }\n                  case _ =>\n                    summonLightTypeTagOfAppropriateKind(c.internal.existentialType(List(t.typeSymbol), t))\n                }\n              } else {\n                summonLightTypeTagOfAppropriateKind(ReflectionUtil.norm(c.universe: c.universe.type, logger)(t.dealias))\n              }\n          }\n        case _ =>\n          tpe.typeArgs.map(t => summonLightTypeTagOfAppropriateKind(ReflectionUtil.norm(c.universe: c.universe.type, logger)(t.dealias)))\n      }\n      logger.log(s\"Now summoning tags for args=$args\")\n      c.Expr[List[LightTypeTag]](Liftable.liftList[c.Expr[LightTypeTag]].apply(args))\n    }\n\n    {\n      // compiler always inserts WeakTypeTag, by passing it explicitly we slightly reduce fragility\n      implicit val itag: c.WeakTypeTag[T] = tag\n      reify {\n        Tag.appliedTag[T](constructorTag.splice, argTags.splice)\n      }\n    }\n  }\n\n  @inline\n  private[this] final def closestClass(properTypeStrongCtor: Type): c.Expr[Class[_]] = {\n    // unfortunately .erasure returns trash for intersection types\n    val tpeLub = ReflectionUtil.norm(c.universe: c.universe.type, logger)(properTypeStrongCtor.dealias) match {\n      case r: RefinedTypeApi => lub(r.parents)\n      case o => o\n    }\n    val tpeErased = tpeLub.erasure\n    // and for Scala varargs (Scala by names and Java varargs are fine)\n    val tpeFixed = if (tpeErased.typeSymbol eq definitions.RepeatedParamClass) {\n      typeOf[scala.Seq[Any]].dealias\n    } else if (tpeErased.typeSymbol eq definitions.ArrayClass) {\n      // workaround for a crash that happens when .erasure misfires on Array in case `Tag[Array[List[X]]]`\n      // and produces a tree `classOf[Array[List]]` which fails to compile.\n      // Array is the only type that needs to be parameterized after erasure and stripping its parameters via .erasure\n      // actually breaks it, so we skip this step for Arrays.\n      tpeLub.dealias\n    } else {\n      tpeErased\n    }\n    c.Expr[Class[_]](q\"${Literal(Constant(tpeFixed))}.asInstanceOf[_root_.java.lang.Class[_]]\")\n  }\n\n  @inline\n  private[this] final def getCtorKindInfoIfCtorIsTypeParameter(tpe: Type): Option[KindInfo[c.universe.type]] = {\n    if (!ReflectionUtil.isSelfStrong(Set.empty, tpe)) Some(KindInfo.ofType(tpe))\n    else None\n  }\n\n  protected[this] def mkTypeParameter(owner: Symbol, kindInfo: KindInfo[c.universe.type]): Symbol = {\n    import internal.reificationSupport._\n    import internal.{polyType, typeBounds}\n\n    val sym = newNestedSymbol(owner, freshTypeName(\"\"), NoPosition, Flag.PARAM | Flag.DEFERRED, isClass = false)\n    val origInner = kindInfo.params.map(_.symbol)\n\n    def mkBounds(tb: Option[TypeBoundsApi], subst: List[Symbol] = Nil) = tb match {\n      case Some(b) =>\n        val (lo, hi) = (b.lo, b.hi)\n        if (subst.nonEmpty) {\n          val newLo = lo.substituteSymbols(origInner, subst)\n          val newHi = hi.substituteSymbols(origInner, subst)\n          typeBounds(newLo, newHi)\n        } else typeBounds(lo, hi)\n      case None => typeBounds(definitions.NothingTpe, definitions.AnyTpe)\n    }\n\n    val tpe = if (kindInfo.params.nonEmpty) {\n      val params = kindInfo.params.map(mkTypeParameter(sym, _))\n      polyType(params, mkBounds(kindInfo.bounds, params))\n    } else mkBounds(kindInfo.bounds)\n\n    setInfo(sym, tpe)\n    sym\n  }\n\n  @inline\n  protected[this] def mkHKTagArgStruct(tpe: Type, kindInfo: KindInfo[c.universe.type]): Type = {\n    import internal.reificationSupport._\n\n    val staticOwner = c.prefix.tree.symbol.owner\n\n    logger.log(s\"staticOwner: $staticOwner\")\n\n    val parents = List(definitions.AnyRefTpe)\n    val mutRefinementSymbol: Symbol = newNestedSymbol(staticOwner, TypeName(\"<refinement>\"), NoPosition, FlagsRepr(0L), isClass = true)\n\n    val mutArg: Symbol = newNestedSymbol(mutRefinementSymbol, TypeName(\"Arg\"), NoPosition, FlagsRepr(0L), isClass = false)\n\n    val isTypeParameter = !ReflectionUtil.isSelfStrong(Set.empty, tpe)\n    val polyType = if (isTypeParameter && tpe.takesTypeArgs) {\n      logger.log(s\"mkHKTagArgStruct: using etaExpand for type parameter $tpe\")\n      tpe.etaExpand\n    } else {\n      val params = kindInfo.params.map(mkTypeParameter(mutArg, _))\n      mkPolyType(tpe, params)\n    }\n\n    setInfo(mutArg, polyType)\n\n    val scope = newScopeWith(mutArg)\n\n    setInfo[Symbol](mutRefinementSymbol, RefinedType(parents, scope, mutRefinementSymbol))\n\n    RefinedType(parents, scope, mutRefinementSymbol)\n  }\n\n  @inline\n  protected[this] def mkPolyType(tpe: Type, params: List[c.Symbol]): Type = {\n    val rhsParams = params.map(symbol => internal.typeRef(NoPrefix, symbol, Nil))\n\n    internal.polyType(params, appliedType(tpe, rhsParams))\n  }\n\n  private[this] def summonLightTypeTagOfAppropriateKind(tpe: Type): c.Expr[LightTypeTag] = {\n    lttFromTag(summonTagForKind(tpe, KindInfo.ofType(tpe)))\n  }\n\n  private[this] def summonHKTag(tpe: Type, kindInfo: KindInfo[c.universe.type]): c.Expr[HKTag[_]] = {\n    c.Expr[HKTag[_]](summonTagForKind(tpe, kindInfo))\n  }\n\n  @inline\n  protected[this] def summonTagForKind(tpe: c.Type, kindInfo: KindInfo[c.universe.type]): c.Tree = {\n    try {\n      if (kindInfo.params.isEmpty) {\n        c.inferImplicitValue(appliedType(weakTypeOf[Tag[Nothing]].typeConstructor, tpe), silent = false)\n      } else {\n        val ArgStruct = mkHKTagArgStruct(tpe, kindInfo)\n        logger.log(s\"Created implicit Arg: $ArgStruct\")\n        c.inferImplicitValue(appliedType(weakTypeOf[HKTag[Nothing]].typeConstructor, ArgStruct), silent = false)\n      }\n    } catch {\n      case _: TypecheckException =>\n        val error = hktagSummonHelpfulErrorMessage(tpe, TagMacro.kindOf(kindInfo))\n        val msg = s\"  could not find implicit value for ${tagFormat(tpe)}$error\"\n        addImplicitError(msg)\n        abortWithImplicitError()\n    }\n  }\n\n  @inline\n  private[this] final def lttFromTag(tagTree: Tree): c.Expr[LightTypeTag] = {\n    c.Expr[LightTypeTag](q\"$tagTree.tag\")\n  }\n\n  def getImplicitError(): String = {\n    val annotations = symbolOf[Tag[Any]].annotations\n    annotations\n      .headOption.flatMap(\n        AnnotationTools.findArgument(_) {\n          case Literal(Constant(s: String)) => s\n        }\n      ).getOrElse(defaultTagImplicitError)\n  }\n\n  def abortWithImplicitError(): Nothing = {\n    c.abort(c.enclosingPosition, getImplicitError())\n  }\n\n  @inline\n  protected[this] def addImplicitError(err: String): Unit = {\n    setImplicitError(s\"${getImplicitError()}\\n$err\")\n  }\n\n  @inline\n  protected[this] def resetImplicitError(tpe: Type): Unit = {\n    setImplicitError(defaultTagImplicitError.replace(\"${T}\", tpe.toString))\n  }\n\n  @inline\n  protected[this] def setImplicitError(err: String): Unit = {\n    import internal.decorators._\n\n    symbolOf[Tag[Any]].setAnnotations(\n      Annotation(typeOf[implicitNotFound], List[Tree](Literal(Constant(err))), ListMap.empty)\n    )\n    ()\n  }\n\n  @inline\n  private[this] final def hktagSummonHelpfulErrorMessage(tpe: Type, kind: Kind): String = {\n    tagFormatMap.get(kind) match {\n      case Some(_) => \"\"\n      case None =>\n        val (typaramsWithKinds, appliedParams) = kind\n          .params.zipWithIndex.map {\n            case (k, i) =>\n              val name = s\"T${i + 1}\"\n              k.format(name) -> name\n          }.unzip\n        s\"\"\"\n           |$tpe is of a kind $kind, which doesn't have a tag name. Please create a tag synonym as follows:\n           |\n           |  type TagXYZ[${kind.format(typeName = \"K\")}] = HKTag[ { type Arg[${typaramsWithKinds.mkString(\", \")}] = K[${appliedParams.mkString(\", \")}] } ]\n           |\n           |And use it in your context bound, as in def x[$tpe: TagXYZ] = ...\n           |OR use Tag.auto.T macro, as in def x[$tpe: Tag.auto.T] = ...\"\"\".stripMargin\n    }\n  }\n\n}\n\nprivate object TagMacro {\n  final val defaultTagImplicitError =\n    \"could not find implicit value for izumi.reflect.Tag[${T}]. Did you forget to put on a Tag, TagK or TagKK context bound on one of the parameters in ${T}? e.g. def x[T: Tag, F[_]: TagK] = ...\"\n\n  def kindOf(tpe: Universe#Type): Kind = {\n    Kind(tpe.typeParams.map(t => kindOf(t.typeSignature)))\n  }\n  def kindOf(kindInfo: KindInfo[Universe]): Kind = {\n    Kind(kindInfo.params.map(kindOf))\n  }\n\n  final case class Kind(params: List[Kind]) {\n    def format(typeName: String) = s\"$typeName${if (params.nonEmpty) params.mkString(\"[\", \", \", \"]\") else \"\"}\"\n    override def toString: String = format(\"_\")\n  }\n  object Kind {\n    val proper: Kind = Kind(Nil)\n  }\n\n  final def tagFormatMap: Map[Kind, String] = {\n    Map(\n      Kind.proper -> \"Tag\",\n      Kind(Kind.proper :: Nil) -> \"TagK\",\n      Kind(Kind.proper :: Kind.proper :: Nil) -> \"TagKK\",\n      Kind(Kind.proper :: Kind.proper :: Kind.proper :: Nil) -> \"TagK3\",\n      Kind(Kind(Kind.proper :: Nil) :: Nil) -> \"TagT\",\n      Kind(Kind(Kind.proper :: Nil) :: Kind.proper :: Nil) -> \"TagTK\",\n      Kind(Kind(Kind.proper :: Nil) :: Kind.proper :: Kind.proper :: Nil) -> \"TagTKK\",\n      Kind(Kind(Kind.proper :: Nil) :: Kind.proper :: Kind.proper :: Kind.proper :: Nil) -> \"TagTK3\"\n    )\n  }\n\n  final def tagFormat(tpe: Universe#Type): String = {\n    val kind = kindOf(tpe)\n    tagFormatMap.get(kind) match {\n      case Some(t) => s\"$t[$tpe]\"\n      case _ => s\"HKTag for $tpe of kind $kind\"\n    }\n  }\n}\n\n@NowarnCompat.nowarn(\"msg=deprecated\")\nclass TagLambdaMacro(override val c: whitebox.Context) extends TagMacro(c) {\n\n  import c.universe._\n  import c.universe.internal.decorators._\n\n  def lambdaImpl: c.Tree = {\n    val pos = c.macroApplication.pos\n\n    val targetTpe = c\n      .enclosingUnit.body.collect {\n        case AppliedTypeTree(t, arg :: _) if t.exists(_.pos == pos) =>\n          c.typecheck(\n            tree = arg,\n            mode = c.TYPEmode,\n            pt = c.universe.definitions.NothingTpe,\n            silent = false,\n            withImplicitViewsDisabled = true,\n            withMacrosDisabled = true\n          ).tpe\n      }.headOption match {\n      case None =>\n        c.abort(\n          c.enclosingPosition,\n          \"Couldn't find the tree of the type that `Tag.auto.T` macro was applied to, please make sure you use the correct syntax, as in `def tagk[F[_]: Tag.auto.T]: TagK[T] = implicitly[Tag.auto.T[F]]`\"\n        )\n      case Some(t) =>\n        t\n    }\n\n    val kind = KindInfo.ofType[c.universe.type](targetTpe)\n\n    logger.log(s\"Found position $pos, target type $targetTpe, target kind $kind\")\n\n    val ctorParam = mkTypeParameter(NoSymbol, kind)\n    val ArgStruct = mkHKTagArgStruct(ctorParam.asType.toType, kind)\n\n    val resultType = c\n      .typecheck(\n        tq\"{ type T[${c.internal.typeDef(ctorParam)}] = _root_.izumi.reflect.HKTag[$ArgStruct] }\",\n        c.TYPEmode,\n        c.universe.definitions.NothingTpe,\n        silent = false,\n        withImplicitViewsDisabled = true,\n        withMacrosDisabled = true\n      ).tpe\n\n    val res = Literal(Constant(())).setType(resultType)\n\n    logger.log(s\"final result: $resultType\")\n\n    res\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/Tags.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport izumi.reflect.macrortti.{LTag, LightTypeTag}\n\nimport scala.annotation.implicitNotFound\nimport scala.language.experimental.macros\n\ntrait AnyTag extends Serializable {\n  def tag: LightTypeTag\n\n  /**\n    * Closest class found for the type or for a LUB of all intersection\n    * members in case of an intersection type.\n    *\n    * A Scala type may not have an associated JVM class, as such\n    * this class may not be sufficient to create instances of `T`\n    *\n    * Only if `tag.hasPreciseClass` returns true\n    * it may be safe to reflect on `closestClass`\n    */\n  def closestClass: Class[_]\n\n  final def hasPreciseClass: Boolean = {\n    try tag.shortName == closestClass.getSimpleName\n    catch {\n      case i: InternalError if i.getMessage == \"Malformed class name\" => false\n    }\n  }\n\n  final def =:=(that: AnyTag): Boolean = {\n    tag =:= that.tag\n  }\n\n  final def <:<(that: AnyTag): Boolean = {\n    tag <:< that.tag\n  }\n\n  override final def equals(that: Any): Boolean = that match {\n    case that: AnyTag => this.tag == that.tag\n    case _ => false\n  }\n\n  override final def hashCode(): Int = tag.hashCode()\n\n  override def toString: String = s\"AnyTag[$tag]\"\n}\n\n/**\n  * Like [[scala.reflect.api.TypeTags.TypeTag]], but supports higher-kinded type tags via `TagK` type class.\n  *\n  * In context of DI this lets you define modules parameterized by higher-kinded type parameters.\n  * This is especially helpful for applying [[https://www.beyondthelines.net/programming/introduction-to-tagless-final/ `tagless final` style]]\n  *\n  * Example:\n  * {{{\n  * import distage.ModuleDef\n  *\n  * class MyModule[F[_]: Monad: TagK] extends ModuleDef {\n  *   make[MyService[F]]\n  *   make[F[Int]].named(\"lucky-number\").from(Monad[F].pure(7))\n  * }\n  * }}}\n  *\n  * Without a `TagK` constraint above, this example would fail with `no TypeTag available for MyService[F]` error\n  *\n  * Currently some limitations apply as to when a `Tag` will be correctly constructed:\n  *   * Type Parameters do not yet resolve in structural refinement methods, e.g. T in {{{ Tag[{ def x: T}] }}}\n  *     They do resolve in refinement type members however, e.g. {{{ Tag[ Any { type Out = T } ] }}}\n  *   * TagK* does not resolve for constructors with bounded parameters, e.g. S in {{{ class Abc[S <: String]; TagK[Abc] }}}\n  *     (You can still have a bound in partial application: e.g. {{{ class Abc[S <: String, A]; TagK[Abc[\"hi\", _]] }}}\n  *   * Further details at [[https://github.com/7mind/izumi/issues/374]]\n  *\n  * @see \"Lightweight Scala Reflection and why Dotty needs TypeTags reimplemented\" https://blog.7mind.io/lightweight-reflection.html\n  *\n  * @see [[izumi.reflect.macrortti.LTag]] - summoner for [[izumi.reflect.macrortti.LightTypeTag]] that does not resolve type parameters\n  * @see [[izumi.reflect.macrortti.LTag.Weak]] - summoner for [[izumi.reflect.macrortti.LightTypeTag]] that does not resolve type parameters and allows unresolved (\"weak\") type parameters to be part of a tag\n  */\n@implicitNotFound(\n  \"could not find implicit value for izumi.reflect.Tag[${T}]. Did you forget to put on a Tag, TagK or TagKK context bound on one of the parameters in ${T}? e.g. def x[T: Tag, F[_]: TagK] = ...\"\n)\ntrait Tag[T] extends AnyTag {\n  def tag: LightTypeTag\n  def closestClass: Class[_]\n\n  override final def toString: String = s\"Tag[$tag]\"\n}\n\nobject Tag {\n\n  /**\n    * Use `Tag.auto.T[TYPE_PARAM]` syntax to summon a `Tag` for a type parameter of any kind:\n    *\n    * {{{\n    *   def module1[F[_]: Tag.auto.T] = new ModuleDef {\n    *     ...\n    *   }\n    *\n    *   def module2[F[_, _]: Tag.auto.T] = new ModuleDef {\n    *     ...\n    *   }\n    * }}}\n    *\n    * {{{\n    *   def y[K[_[_, _], _[_], _[_[_], _, _, _]](implicit ev: Tag.auto.T[K]): Tag.auto.T[K] = ev\n    * }}}\n    *\n    * {{{\n    *   def x[K[_[_, _], _[_], _[_[_], _, _, _]: Tag.auto.T]: Tag.auto.T[K] = implicitly[Tag.auto.T[K]]\n    * }}}\n    */\n  def auto: Any = macro TagLambdaMacro.lambdaImpl\n\n  @inline def apply[T: Tag]: Tag[T] = implicitly\n\n  def apply[T](cls: Class[_], tag0: LightTypeTag): Tag[T] = {\n    new Tag[T] {\n      override val tag: LightTypeTag = tag0\n      override val closestClass: Class[_] = cls\n    }\n  }\n\n  /**\n    * Create a Tag of a type formed by applying the type in `tag` to `args`.\n    *\n    * Example:\n    * {{{\n    *   implicit def tagFromTagTAKA[T[_, _[_], _]: TagK3, K[_]: TagK, A0: Tag, A1: Tag]: Tag[T[A0, K, A1]] =\n    *     Tag.appliedTag(TagK3[T].tag, List(Tag[A0].tag, TagK[K].tag, Tag[A1].tag))\n    * }}}\n    */\n  def appliedTag[R](tag: HKTag[_], args: List[LightTypeTag]): Tag[R] = {\n    Tag(tag.closestClass, tag.tag.combine(args: _*))\n  }\n\n  /**\n    * Create a Tag of a type formed from an `intersection` of types (A with B) with a structural refinement taken from `structType`\n    *\n    * `structType` is assumed to be a weak type of the entire type, e.g.\n    * {{{\n    *   Tag[A with B {def abc: Unit}] == refinedTag(classOf[Any], List(LTag[A].tag, LTag[B].tag), LTag.Weak[A with B { def abc: Unit }].tag, Map.empty)\n    * }}}\n    */\n  def refinedTag[R](lubClass: Class[_], intersection: List[LightTypeTag], structType: LightTypeTag, additionalTypeMembers: Map[String, LightTypeTag]): Tag[R] = {\n    Tag(lubClass, LightTypeTag.refinedType(intersection, structType, additionalTypeMembers))\n  }\n\n  @deprecated(\"Binary compatibility for 1.0.0-M6+\", \"1.0.0-M6\")\n  private[Tag] def refinedTag[R](lubClass: Class[_], intersection: List[LightTypeTag], structType: LightTypeTag): Tag[R] = {\n    refinedTag(lubClass, intersection, structType, Map.empty)\n  }\n\n  implicit final def tagFromTagMacro[T]: Tag[T] = macro TagMacro.makeTag[T]\n}\n\n/**\n  * Internal unsafe API representing a poly-kinded, higher-kinded type tag.\n  *\n  * To create a Tag* implicit for an arbitrary kind use the following syntax:\n  *\n  * {{{\n  *   type TagK5[K[_, _, _, _, _]] = HKTag[ { type Arg[A, B, C, D, E] = K[A, B, C, D, E] } ]\n  * }}}\n  *\n  * As an argument to HKTag, you should specify the type variables your type parameter will take and apply them to it, in order.\n  *\n  * {{{\n  *   type TagFGC[K[_[_, _], _[_], _[_[_], _, _, _]] = HKTag[ { type Arg[A[_, _], B[_], C[_[_], _, _, _]] = K[A, B, C] } ]\n  * }}}\n  *\n  * A convenience macro `Tag.auto.T` is available to automatically create a type lambda for a type of any kind:\n  *\n  * {{{\n  *   def x[K[_[_, _], _[_], _[_[_], _, _, _]: Tag.auto.T]: Tag.auto.T[K] = implicitly[Tag.auto.T[K]]\n  * }}}\n  */\ntrait HKTag[T] extends AnyTag {\n  /** Internal `LightTypeTag` holding the `typeConstructor` of type `T` */\n  def tag: LightTypeTag\n  def closestClass: Class[_]\n\n  override final def toString: String = s\"HKTag[$tag]\"\n}\n\nobject HKTag {\n  def apply[T](cls: Class[_], lightTypeTag: LightTypeTag): HKTag[T] = new HKTag[T] {\n    override val tag: LightTypeTag = lightTypeTag\n    override val closestClass: Class[_] = cls\n  }\n\n  def appliedTagNonPos[R](tag: HKTag[_], args: List[Option[LightTypeTag]]): HKTag[R] = {\n    HKTag(tag.closestClass, tag.tag.combineNonPos(args: _*))\n  }\n\n  def appliedTagNonPosAux[R](cls: Class[_], ctor: LightTypeTag, args: List[Option[LightTypeTag]]): HKTag[R] = {\n    HKTag(cls, ctor.combineNonPos(args: _*))\n  }\n\n  @inline implicit final def hktagFromTagMacro[T](implicit materializer: HKTagMaterializer[T]): HKTag[T] = materializer.value\n}\n\n/**\n  * Force eager expansion for all recursive implicit searches inside TagMacro\n  * by introducing a proxy implicit to display better error messages\n  *\n  * @see test ResourceEffectBindingsTest.\"Display tag macro stack trace when ResourceTag is not found\"\n  */\nfinal class HKTagMaterializer[T](val value: HKTag[T]) extends AnyVal\nobject HKTagMaterializer {\n  // FIXME: TagK construction macro\n  implicit def materializeHKTag[T]: HKTagMaterializer[T] = macro TagMacro.makeHKTagMaterializer[T]\n}\n\n// Workaround needed specifically to support generic methods in factories, see `GenericAssistedFactory` and related tests\n//\n// We need to construct a SafeType signature for a generic method, but generic parameters have no type tags\n// So we resort to weak type parameters and pointer equality\ntrait WeakTag[T] extends AnyTag {\n  def tag: LightTypeTag\n  def closestClass: Class[_]\n\n  override final def toString: String = s\"WeakTag[$tag]\"\n}\n\nobject WeakTag extends WeakTagInstances1 {\n  def apply[T: WeakTag]: WeakTag[T] = implicitly\n\n  def apply[T](cls: Class[_], l: LightTypeTag): WeakTag[T] = {\n    new WeakTag[T] {\n      override val tag: LightTypeTag = l\n      override val closestClass: Class[_] = cls\n    }\n  }\n\n  implicit def weakTagFromTag[T: Tag]: WeakTag[T] = WeakTag(Tag[T].closestClass, Tag[T].tag)\n}\nprivate[reflect] trait WeakTagInstances1 {\n  implicit def weakTagFromWeakTypeTag[T](implicit l: LTag.Weak[T]): WeakTag[T] = WeakTag(classOf[Any], l.tag)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/TrivialMacroLogger.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger.Config\n\nimport scala.reflect.ClassTag\nimport scala.reflect.macros.blackbox\n\n/**\n  * To see macro debug output during compilation, set `-Dizumi.reflect.debug.macro.rtti=true` java property! e.g.\n  *\n  * {{{\n  * sbt -Dizumi.reflect.debug.macro.rtti=true compile\n  * }}}\n  *\n  * @see [[DebugProperties]]\n  */\nprivate[reflect] object TrivialMacroLogger {\n  def make[T: ClassTag](c: blackbox.Context): TrivialLogger = {\n    TrivialLogger.make[T](config = Config(sink = new ScalacSink(c), forceLog = false))\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/macrortti/LTag.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport scala.language.experimental.macros\n\nfinal case class LTag[T](tag: LightTypeTag)\n\n/**\n  * these are different summoners for light tags, it's fine for them to be the same structurally\n  */\nobject LTag {\n  def apply[T: LTag]: LTag[T] = implicitly\n\n  implicit def materialize[T]: LTag[T] = macro LightTypeTagMacro.makeStrongTag[T]\n\n  final case class Weak[T](tag: LightTypeTag)\n  object Weak {\n    def apply[T: LTag.Weak]: LTag.Weak[T] = implicitly\n\n    implicit def materialize[T]: LTag.Weak[T] = macro LightTypeTagMacro.makeWeakTag[T]\n  }\n\n  final case class StrongHK[T](tag: LightTypeTag)\n  object StrongHK {\n    implicit def materialize[T]: LTag.StrongHK[T] = macro LightTypeTagMacro.makeStrongHKTag[T]\n  }\n\n  final case class WeakHK[T](tag: LightTypeTag)\n  object WeakHK {\n    implicit def materialize[T]: LTag.WeakHK[T] = macro LightTypeTagMacro.makeWeakHKTag[T]\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/macrortti/LightTypeTagImpl.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.internal.{CollectionCompat, NowarnCompat}\nimport izumi.reflect.internal.fundamentals.collections.IzCollections._\nimport izumi.reflect.internal.fundamentals.platform.assertions.IzAssert\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger.Config\nimport izumi.reflect.internal.fundamentals.platform.strings.IzString._\nimport izumi.reflect.macrortti.LightTypeTagImpl.{Broken, globalCache}\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.{SymLiteral, SymTermName, SymTypeName}\nimport izumi.reflect.macrortti.LightTypeTagRef._\nimport izumi.reflect.{DebugProperties, ReflectionUtil}\n\nimport scala.annotation.tailrec\nimport scala.collection.mutable\nimport scala.language.reflectiveCalls\nimport scala.reflect.api.Universe\n\nobject LightTypeTagImpl {\n  private lazy val globalCache = new java.util.WeakHashMap[Any, AbstractReference]\n\n  /** caching is enabled by default for runtime light type tag creation */\n  private[this] lazy val runtimeCacheEnabled: Boolean = {\n    System\n      .getProperty(DebugProperties.`izumi.reflect.rtti.cache.runtime`).asBoolean()\n      .getOrElse(true)\n  }\n\n  /** Create a LightTypeTag at runtime for a reflected type */\n  def makeLightTypeTag(u: Universe)(typeTag: u.Type): LightTypeTag = {\n    ReflectionLock.synchronized {\n      val logger = TrivialLogger.make[this.type](config = Config.console)\n      new LightTypeTagImpl[u.type](u, withCache = runtimeCacheEnabled, logger).makeFullTagImpl(typeTag)\n    }\n  }\n\n  private[this] object ReflectionLock\n\n  private sealed trait Broken[T, S] {\n    def intersectionComponents: Set[T]\n    def decls: Set[S]\n    def maybeUnbrokenType: Option[T]\n  }\n\n  private object Broken {\n\n    final case class Single[T, S](t: T) extends Broken[T, S] {\n      override def intersectionComponents: Set[T] = Set(t)\n      override def decls: Set[S] = Set.empty\n      override def maybeUnbrokenType: Option[T] = Some(t)\n    }\n\n    final case class Compound[T, S](intersectionComponents: Set[T], decls: Set[S]) extends Broken[T, S] {\n      override def maybeUnbrokenType: Option[T] = None\n    }\n\n  }\n\n}\n\nfinal class LightTypeTagImpl[U <: Universe with Singleton](val u: U, withCache: Boolean, logger: TrivialLogger) {\n\n  import u._\n\n  @inline private[this] final val any = definitions.AnyTpe\n  @inline private[this] final val obj = definitions.ObjectTpe\n  @inline private[this] final val nothing = definitions.NothingTpe\n  @inline private[this] final val ignored = Set(any, obj, nothing)\n\n  def makeFullTagImpl(tpe0: Type): LightTypeTag = {\n    val tpe = Dealias.fullNormDealias(tpe0)\n\n    logger.log(s\"Initial mainTpe=$tpe:${tpe.getClass} beforeDealias=$tpe0:${tpe0.getClass}\")\n\n    val lttRef = makeRef(tpe)\n\n    val allReferenceComponents = mutable\n      .LinkedHashSet\n      .newBuilder[Type]\n      .++= {\n        allTypeReferencesWithBases(tpe, mutable.HashSet.empty, onlyIndirect = false)\n      }.result()\n\n    val fullDb = makeFullDb(tpe, allReferenceComponents).toMultimap\n    val unappliedDb = makeClassOnlyInheritanceDb(tpe, allReferenceComponents.iterator)\n\n    LightTypeTag(lttRef, fullDb, unappliedDb)\n  }\n\n  private[this] def allTypeReferencesWithBases(tpe0: Type, basesTermination: mutable.HashSet[Symbol], onlyIndirect: Boolean): Iterator[Type] = {\n    val allReferenceComponents = allTypeReferences(tpe0, basesTermination, onlyIndirect)\n    allReferenceComponents.iterator.flatMap {\n      component =>\n        if (component.typeSymbol != NoSymbol) {\n          basesTermination += component.typeSymbol\n        }\n\n        Iterator.single(component) ++ tpeBases(component).flatMap {\n          case t if basesTermination(t.typeSymbol) => Nil\n          case t =>\n            allTypeReferencesWithBases(t, basesTermination, onlyIndirect = true)\n        }\n    }\n  }\n\n  // FIXME `allTypeReferences` & `makeRef` should be merged together,\n  //  since they both pass over all visible components of a type in a similar way\n  private[this] def allTypeReferences(mainTpe: Type, basesTermination: mutable.HashSet[Symbol], onlyIndirect: Boolean): collection.Set[Type] = {\n\n    @NowarnCompat.nowarn(\"msg=deprecated\")\n    @inline def result(): collection.Set[Type] = {\n      val tpeDealiased = dealiasPrepare(mainTpe).maybeUnbrokenType.getOrElse(NoType)\n\n      val inh = mutable.LinkedHashSet.empty[Type]\n      extractComponents(mainTpe, inh)\n\n      logger.log(s\"Extracted all type references for mainTpe=$mainTpe parts=${inh.iterator.map(t => (t, t.getClass.asInstanceOf[Class[Any]])).toMap.niceList()}\")\n\n      if (onlyIndirect) {\n        inh.retain {\n          t => t != mainTpe && t != tpeDealiased && !basesTermination(t.typeSymbol)\n        }\n      }\n\n      inh\n    }\n\n    @inline def dealiasPrepare(t0: Type): Broken[Type, Symbol] = {\n      UniRefinement.breakRefinement(t0, squashHKTRefToPolyTypeResultType = false)\n    }\n\n    def extractComponents(tpeRaw0: Type, inh: mutable.LinkedHashSet[Type]): Unit = {\n      val breakResult = dealiasPrepare(tpeRaw0)\n      val current = breakResult.maybeUnbrokenType\n      inh ++= current\n\n      val intersectionExpansionsArgsBoundsIter: Iterator[Type] = breakResult.intersectionComponents.iterator.flatMap(collectArgsAndBounds)\n      val refinementDeclMembersIter: Iterator[Type] = breakResult.decls.iterator.flatMap {\n        sym =>\n          if (sym.isMethod) {\n            val m = sym.asMethod\n            m.returnType :: m.paramLists.iterator.flatten.map(UniRefinement.typeOfParam).toList\n          } else if (sym.isType) {\n            UniRefinement.concreteTypesOfTypeMemberOnly(sym)\n          } else Nil\n      }\n\n      val indirectComponents = intersectionExpansionsArgsBoundsIter ++ refinementDeclMembersIter\n\n      indirectComponents.foreach(t => if (!current.contains(t) && !inh(t) && !ignored(t)) extractComponents(t, inh))\n    }\n\n    def collectArgsAndBounds(tpeUnexpanded0: Type): Iterator[Type] = {\n      // unexpanded: Either\n      val tpeUnexpanded = Dealias.fullNormDealias(tpeUnexpanded0)\n      // polyType: [L,R]Either[L,R]\n      // polyTypeResult: Either[L,R] where L,R are trash symbols\n\n      // we need to use tpe.etaExpand but 2.13 has a bug: https://github.com/scala/bug/issues/11673#\n      // tpe.etaExpand.resultType.dealias.typeArgs.flatMap(_.dealias.resultType.typeSymbol.typeSignature match {\n\n      def doExtractNonParamTypeArgs(t: Type): List[Type] = {\n        val tpePolyTypeResultType = Dealias.fullNormDealiasSquashHKTToPolyTypeResultType(t)\n\n        logger.log(\n          s\"\"\"Got tpeUnexpanded=$tpeUnexpanded:${tpeUnexpanded.getClass} args=${tpeUnexpanded.typeArgs} params=${tpeUnexpanded.typeParams}\n             |tpePolyTypeResultType=$tpePolyTypeResultType:${tpePolyTypeResultType.getClass} args=${tpePolyTypeResultType.typeArgs} params=${tpePolyTypeResultType.typeParams}\"\"\".stripMargin\n        )\n\n        tpePolyTypeResultType.typeArgs.flatMap {\n          targ0 =>\n            val targ = Dealias.fullNormDealias(targ0)\n            val targSym = targ.typeSymbol\n            targSym.typeSignature match {\n              case t: TypeBoundsApi =>\n                Seq(t.hi, t.lo).filterNot(ignored)\n              case _ =>\n                if (!targSym.isParameter) {\n                  Seq(targ0)\n                } else {\n                  Seq.empty\n                }\n            }\n        }\n      }\n\n      val tparamTypeBoundsAndTypeArgs = tpeUnexpanded match {\n        case e: ExistentialTypeApi =>\n          doExtractNonParamTypeArgs(e.underlying)\n        case o =>\n          doExtractNonParamTypeArgs(o)\n      }\n\n      logger.log(s\"tparamTypeBoundsAndTypeArgs of $tpeUnexpanded=$tparamTypeBoundsAndTypeArgs\")\n\n      /**\n        * Don't do this:\n        *  Iterator.single(tpePolyTypeResultType) -- produces trash symbols out of skolems\n        *  tpePolyTypeResultType.typeArgs.iterator -- just redundant, included in `tparamTypeBoundsAndTypeArgs`\n        */\n      Iterator.single(tpeUnexpanded) ++\n      tpeUnexpanded.typeArgs.iterator ++\n      tparamTypeBoundsAndTypeArgs.iterator\n    }\n\n    result()\n  }\n\n  private[this] def makeFullDb(tpe: Type, allReferenceComponents: Iterable[Type]): Iterator[(AbstractReference, AbstractReference)] = {\n    val stableBases = makeAppliedBases(tpe, allReferenceComponents.iterator)\n    val basesAsLambdas = makeLambdaOnlyBases(tpe, allReferenceComponents.iterator)\n    basesAsLambdas.iterator ++ stableBases.iterator\n  }\n\n  private[this] def makeAppliedBases(mainTpe: Type, allReferenceComponents: Iterator[Type]): List[(AbstractReference, AbstractReference)] = {\n\n    val appliedBases = allReferenceComponents\n      .filterNot(isHKTOrPolyTypeOrResultTypeArtifact) // remove PolyTypes, only process applied types in this inspection\n      .filterNot(isExistentialArtifact) // remove forSome artifacts in Scala 2.11 && 2.12\n      .flatMap {\n        component =>\n          val tparams = component.etaExpand.typeParams\n          val lambdaParams = makeLambdaParams(None, tparams).toMap\n\n          val appliedParents = tpeBases(component).filterNot(isHKTOrPolyTypeOrResultTypeArtifact)\n          val componentRef = makeRef(component)\n\n          appliedParents.map {\n            parentTpe =>\n              val parentRef = makeRefTop(parentTpe, terminalNames = lambdaParams, isLambdaOutput = lambdaParams.nonEmpty) match {\n                case unapplied: Lambda =>\n                  if (unapplied.someArgumentsReferenced) {\n                    unapplied\n                  } else {\n                    logger.log(\n                      s\"No arguments referenced in l=$unapplied, parentTpe=$parentTpe(etaExpand:${parentTpe.etaExpand}), tparams=$tparams, mainTpe=$mainTpe(etaExpand:${mainTpe.etaExpand})\"\n                    )\n                    unapplied.output\n                  }\n                case applied: AppliedReference =>\n                  applied\n              }\n              (componentRef, parentRef)\n          }\n      }\n      .filterNot {\n        case (t, parent) =>\n          // IzAssert(parent != t, parent -> t) // 2.11/2.12 fail this\n          parent == t\n      }\n      .toList\n    logger.log(s\"Computed applied bases for tpe=$mainTpe appliedBases=${appliedBases.toMultimap.niceList()}\")\n    appliedBases\n  }\n\n  private[this] def makeLambdaOnlyBases(mainTpe: Type, allReferenceComponents: Iterator[Type]): List[(AbstractReference, AbstractReference)] = {\n\n    @inline def result(): List[(AbstractReference, AbstractReference)] = {\n      val unappliedBases = allReferenceComponents.flatMap(processLambdasReturningRefinements).toList\n      logger.log(s\"Computed lambda only bases for tpe=$mainTpe lambdaBases=${unappliedBases.toMultimap.niceList()}\")\n      unappliedBases\n    }\n\n    def processLambdasReturningRefinements(tpeRaw0: Type): List[(AbstractReference, AbstractReference)] = {\n      val componentsOfPolyTypeResultType = UniRefinement.breakRefinement(tpeRaw0, squashHKTRefToPolyTypeResultType = true)\n\n      IzAssert(\n        assertion = {\n          if (componentsOfPolyTypeResultType.maybeUnbrokenType.isEmpty) {\n            !componentsOfPolyTypeResultType.intersectionComponents.exists(_.takesTypeArgs)\n          } else {\n            true\n          }\n        },\n        clue = {\n          s\"\"\"Unexpected intersection contains a PolyType:\n             |tpeRaw0 = $tpeRaw0\n             |components = ${componentsOfPolyTypeResultType.intersectionComponents.niceList(prefix = \"*\")}\n             |takesTypeArgs = ${componentsOfPolyTypeResultType.intersectionComponents.map(_.takesTypeArgs).niceList(prefix = \"*\")}\n             |etaExpand = ${componentsOfPolyTypeResultType.intersectionComponents.map(_.etaExpand).niceList(prefix = \"+\")}\n             |tparams = ${componentsOfPolyTypeResultType.intersectionComponents.map(_.etaExpand.typeParams).niceList(prefix = \"-\")}\n             |\"\"\".stripMargin\n        }\n      )\n\n      componentsOfPolyTypeResultType\n        .intersectionComponents.iterator.flatMap {\n          component =>\n            val componentAsPolyType = component.etaExpand\n            val tparams = componentAsPolyType.typeParams\n\n            if (tparams.isEmpty) {\n              Nil\n            } else {\n              makeLambda(componentAsPolyType, tparams)\n            }\n        }.toList\n    }\n\n    def makeLambda(componentAsPolyType: Type, tparams: List[Symbol]): List[(AbstractReference, AbstractReference)] = {\n      val lambdaParams = makeLambdaParams(None, tparams)\n      val parentLambdas = makeLambdaParents(componentAsPolyType, lambdaParams)\n\n      val componentLambda = makeRef(componentAsPolyType) // : LightTypeTagRef.Lambda\n      IzAssert(componentLambda.isInstanceOf[Lambda])\n\n      parentLambdas.map(componentLambda -> _)\n    }\n\n    def makeLambdaParents(componentPolyType: Type, lambdaParams: List[(String, SymName.LambdaParamName)]): List[AbstractReference] = {\n      val allBaseTypes = tpeBases(componentPolyType)\n\n      val paramMap = lambdaParams.toMap\n      lazy val lambdaParamsUnpacked = lambdaParams.map(_._2)\n\n      allBaseTypes.map {\n        parentTpe =>\n          val reference = makeRefTop(parentTpe, terminalNames = paramMap, isLambdaOutput = false)\n          reference match {\n            case l: Lambda =>\n              l\n            case applied: AppliedReference =>\n              val l = Lambda(lambdaParamsUnpacked, applied)\n//              Some(l).filter(_.allArgumentsReferenced) // do not include non-lambda parents such as Product into lambda's inheritance tree\n              // No, include ALL bases for lambdas (this should be more correct since lambda is a template for a full parameterized db after combine)\n              if (l.someArgumentsReferenced) l else applied\n          }\n      }\n    }\n\n    result()\n  }\n\n  private[this] def makeClassOnlyInheritanceDb(mainTpe: Type, allReferenceComponents: Iterator[Type]): Map[NameReference, Set[NameReference]] = {\n    val baseclassReferences = allReferenceComponents\n      .flatMap {\n        // squash all type lambdas and get the intersection of their results\n        // because we don't care about type parameters at all in this inspection\n        UniRefinement.breakRefinement(_, squashHKTRefToPolyTypeResultType = true).intersectionComponents\n      }\n      .flatMap {\n        component =>\n          val prefix = makePrefixReference(component)\n          val componentRef = makeNameReference(component, component.typeSymbol, Boundaries.Empty, prefix)\n          val appliedBases = tpeBases(component).filterNot(isHKTOrPolyType)\n          appliedBases.map(componentRef -> makeRef(_))\n      }\n\n    val unparameterizedInheritanceData = baseclassReferences\n      .toMultimap\n      .map {\n        case (t, parents) =>\n          t -> parents\n            .collect {\n              case r: AppliedNamedReference =>\n                r.asName\n            }\n            .filterNot {\n              parent =>\n                // IzAssert(parent != t, parent -> t) // 2.11/2.12 fail this\n                parent == t\n            }\n      }\n      .filterNot(_._2.isEmpty)\n\n    logger.log(s\"Computed unparameterized inheritance data for tpe=$mainTpe unappliedBases=${unparameterizedInheritanceData.toMultimap.niceList()}\")\n\n    unparameterizedInheritanceData\n  }\n\n  private[this] def tpeBases(t0: Type): List[Type] = {\n    // val tpef = Dealias.fullNormDealiasResultType(t0, squashHKTRefToPolyTypeResultType = false)\n    // no PolyTypes passed to here [but actually we should preserve polyTypes]\n    val tpe = Dealias.fullNormDealias(t0)\n    val upperBound = {\n      val tpeSig = tpe.typeSymbol.typeSignature\n      tpeSig.finalResultType match {\n        // handle abstract higher-kinded type members specially,\n        // move their upper bound into inheritance db, because they\n        // will lose it after application. (Unlike proper type members)\n        case b: TypeBoundsApi if tpeSig.takesTypeArgs =>\n          List(b.hi)\n        case _ =>\n          Nil\n      }\n    }\n\n    (upperBound.iterator ++ tpe\n      .baseClasses\n      .iterator\n      .map(tpe.baseType))\n      .filterNot(ignored)\n      .filterNot(if (isSingletonType(tpe)) _ => false else _.typeSymbol.fullName == tpe.typeSymbol.fullName)\n      .filterNot(_ =:= tpe) // 2.11/2.12 fail this\n      .toList\n  }\n\n  private[this] def makeRef(tpe: Type): AbstractReference = {\n    if (withCache) {\n      globalCache.synchronized(globalCache.get(tpe)) match {\n        case null =>\n          val ref = makeRefTop(tpe, terminalNames = Map.empty, isLambdaOutput = false)\n          globalCache.synchronized(globalCache.put(tpe, ref))\n          ref\n        case ref =>\n          ref\n      }\n    } else {\n      makeRefTop(tpe, terminalNames = Map.empty, isLambdaOutput = false)\n    }\n  }\n\n  private[this] def makeRefTop(tpe: Type, terminalNames: Map[String, SymName.LambdaParamName], isLambdaOutput: Boolean): AbstractReference = {\n    this.makeRefImpl(0, nestedIn = Set(tpe), terminalNames, Set.empty)(tpe, isLambdaOutput)\n  }\n\n  private[this] def makeRefImpl(\n    level: Int,\n    nestedIn: Set[Type],\n    terminalNames: Map[String, SymName.LambdaParamName],\n    knownWildcards: Set[Symbol]\n  )(tpe0: Type,\n    isLambdaOutput: Boolean\n  ): AbstractReference = {\n\n    def makeBoundaries(t: Type): Boundaries = {\n      val tOrTypeSymBounds = t match {\n        case b: TypeBoundsApi => b\n        case _ => t.typeSymbol.typeSignature\n      }\n      tOrTypeSymBounds match {\n        case b: TypeBoundsApi =>\n          if ((b.lo =:= nothing && b.hi =:= any) ||\n            // prevent recursion\n            (nestedIn.contains(b.lo) || nestedIn.contains(b.hi))) {\n            Boundaries.Empty\n          } else {\n            val lo = makeRefSub(b.lo, Map.empty, Set.empty)\n            val hi = makeRefSub(b.hi, Map.empty, Set.empty)\n            Boundaries.Defined(lo, hi)\n          }\n        case _ =>\n          Boundaries.Empty\n      }\n    }\n\n    def makeRefSub(tpe: Type, stop: Map[String, SymName.LambdaParamName], knownWildcardsSub: Set[Symbol]): AbstractReference = {\n      val allWildcards = knownWildcards ++ knownWildcardsSub\n      if (allWildcards.contains(tpe.typeSymbol)) {\n        WildcardReference(makeBoundaries(tpe0))\n      } else {\n        this.makeRefImpl(level + 1, nestedIn + tpe, terminalNames ++ stop, allWildcards)(tpe, isLambdaOutput = false)\n      }\n    }\n\n    val thisLevel = logger.sub(level)\n\n    def unpackLambda(t: TypeApi): AbstractReference = {\n      val polyType = t.etaExpand\n      val polyTypeResult = Dealias.fullNormDealiasSquashHKTToPolyTypeResultType(polyType)\n\n      val tparams = polyType.typeParams\n      val nestingLevel = if (level > 0) Some(level) else None\n      val lambdaParams = makeLambdaParams(nestingLevel, tparams)\n\n      thisLevel.log(s\"✴️ λ type $t has parameters $lambdaParams and result $polyTypeResult terminal names = $terminalNames\")\n      val reference = makeRefSub(polyTypeResult, lambdaParams.toMap, Set.empty)\n      val out = Lambda(lambdaParams.map(_._2), reference)\n      if (!out.allArgumentsReferenced) {\n        val kvParams = lambdaParams.map { case (k, v) => s\"$v = $k\" }\n        thisLevel.log(\n          s\"⚠️ unused 𝝺 args! type $t => $out, someReferenced: ${out.someArgumentsReferenced} context: $terminalNames, 𝝺 params: $kvParams, 𝝺 result: $polyTypeResult => $reference, referenced: ${out.referenced} \"\n        )\n      }\n\n      thisLevel.log(s\"✳️ Restored λ $t => ${out.longNameWithPrefix}\")\n      out\n    }\n\n    def unpackProperTypeRefinement(t0: Type, rules: Map[String, SymName.LambdaParamName]): AppliedReference = {\n      IzAssert(!isHKTOrPolyType(Dealias.fullNormDealias(t0)))\n\n      UniRefinement.breakRefinement(t0, squashHKTRefToPolyTypeResultType = false) match {\n        case Broken.Compound(components, decls) =>\n          val parts = components.map(unpackAsProperType(_, rules): AppliedReference)\n          val intersection = LightTypeTagRef.maybeIntersection(parts)\n          if (decls.nonEmpty) {\n            Refinement(intersection, decls.flatMap(convertDecl(_, rules)))\n          } else {\n            intersection\n          }\n\n        case Broken.Single(t) =>\n          unpackAsProperType(t, rules)\n      }\n    }\n\n    def unpackAsProperType(tpeRaw: Type, rules: Map[String, SymName.LambdaParamName]): AppliedNamedReference = {\n      val tpe = Dealias.fullNormDealias(tpeRaw)\n      val prefix = makePrefixReference(tpe)\n      val typeSymbol = tpe.typeSymbol\n\n      val boundaries = makeBoundaries(tpe)\n\n      val nameRef = rules.get(typeSymbol.fullName) match {\n        case Some(lambdaParameter) =>\n          // this is a previously encountered type variable\n          NameReference(lambdaParameter, boundaries, prefix)\n\n        case None =>\n          makeNameReference(tpe, typeSymbol, boundaries, prefix)\n      }\n\n      tpe.typeArgs match {\n        case Nil =>\n          nameRef\n\n        case args =>\n          val tparams = Dealias.fullNormDealias(tpeRaw).typeConstructor.typeParams\n\n          val refParams = tpeRaw match {\n            case t: ExistentialTypeApi =>\n              val quantifiedParams = t.quantified.toSet\n              t.underlying.typeArgs.zip(tparams).map {\n                case (arg, param) =>\n                  val paramRef =\n                    if (quantifiedParams.contains(arg.typeSymbol) && !rules.contains(arg.typeSymbol.fullName)) {\n                      WildcardReference(makeBoundaries(arg))\n                    } else {\n                      makeRefSub(arg, Map.empty, quantifiedParams)\n                    }\n                  TypeParam(paramRef, makeVariance(param.asType))\n              }\n            case _ =>\n              args.zip(tparams).map {\n                case (arg, param) =>\n                  val paramRef = makeRefSub(arg, Map.empty, Set.empty)\n                  TypeParam(paramRef, makeVariance(param.asType))\n              }\n          }\n\n          val res = FullReference(nameRef.asName.ref, refParams, prefix)\n          thisLevel.log(s\"Assembled FullReference=$res from args=$args and tparams=$tparams\")\n          res\n      }\n    }\n\n    def convertDecl(decl: Symbol, rules: Map[String, SymName.LambdaParamName]): CollectionCompat.IterableOnce[RefinementDecl] = {\n      if (decl.isMethod) {\n        val declMethod = decl.asMethod\n        val returnTpe = declMethod.returnType\n\n        val paramLists0 = declMethod\n          .paramLists.map(_.map {\n            param =>\n              val paramTpe = UniRefinement.typeOfParam(param)\n              makeRefSub(paramTpe, rules, Set.empty).asInstanceOf[AppliedReference]\n          })\n        val paramLists = if (paramLists0.nonEmpty) paramLists0 else List(Nil)\n\n        paramLists.map {\n          parameterList =>\n            RefinementDecl.Signature(declMethod.name.decodedName.toString, parameterList, makeRefSub(returnTpe, rules, Set.empty).asInstanceOf[AppliedReference])\n        }\n      } else if (decl.isType) {\n        val tpe = UniRefinement.typeOfTypeMember(decl)\n        val declName = decl.name.decodedName.toString\n        val ref = makeRefSub(tpe, rules, Set.empty) match {\n          // inspecting abstract type will always return a <none> NamedReference\n          case n @ NameReference(SymTypeName(\"<none>\"), _, _) => n.copy(ref = SymTypeName(declName))\n          case ref => ref\n        }\n        Some(RefinementDecl.TypeMember(declName, ref))\n      } else {\n        None\n      }\n    }\n\n    val out = tpe0 match {\n      case l if isLambdaOutput => // this is required for handling SwapF2, etc.\n        IzAssert(!isHKTOrPolyType(l), l -> l.getClass)\n        val out = Lambda(terminalNames.values.toList, unpackAsProperType(l, terminalNames))\n        out\n\n      case l: PolyTypeApi =>\n        val out = unpackLambda(l)\n        out\n\n      case l if l.takesTypeArgs =>\n        if (terminalNames.contains(l.typeSymbol.fullName)) {\n          val out = unpackAsProperType(l, terminalNames)\n          out\n        } else {\n          val out = unpackLambda(l)\n          out\n        }\n\n      // special case top-level existential type (may be generated by TagMacro)\n      case e: ExistentialType if e.quantified.headOption.contains(e.underlying.typeSymbol) =>\n        WildcardReference(makeBoundaries(e.underlying))\n\n      case c =>\n        unpackProperTypeRefinement(c, terminalNames)\n    }\n    out\n  }\n\n  private[this] def makeLambdaParams(ctxIdx: Option[Int], tparams: List[Symbol]): List[(String, SymName.LambdaParamName)] = {\n    tparams.zipWithIndex.map {\n      case (tparamSym, idx) =>\n        val fullName = tparamSym.fullName\n//        val idxStr = ctxIdx match {\n//          case Some(ctx) =>\n//            s\"$ctx:$idx\"\n//          case None =>\n//            idx.toString\n//        }\n        fullName -> SymName.LambdaParamName(idx, ctxIdx.getOrElse(LightTypeTagRef.LambdaConstants.defaultContextId), tparams.size)\n    }\n  }\n\n  private[this] def makeNameReference(originalType: Type, typeSymbol: Symbol, boundaries: Boundaries, prefix: Option[AppliedReference]): NameReference = {\n    originalType match {\n      case c: ConstantTypeApi =>\n        NameReference(SymLiteral(c.value.value), boundaries, None)\n\n      case s: SingleTypeApi if s.sym != NoSymbol =>\n        s.sym.info.finalResultType match { // finalResultType necessary to dereference NullaryMethodType (from vals in 2.13.10+)\n          case c: ConstantTypeApi =>\n            NameReference(SymLiteral(c.value.value), boundaries, None)\n\n          case _ =>\n            val (sym, _) = Dealias.dealiasSingletons(s.termSymbol, originalType)\n            val resultType = Dealias.fullNormDealias(sym.typeSignatureIn(s.pre).finalResultType)\n            val newPrefix = if (hasSingletonType(resultType.typeSymbol)) makePrefixReference(resultType) else prefix\n            NameReference(makeSymName(sym), boundaries, newPrefix)\n        }\n\n      case _ =>\n        NameReference(makeSymName(typeSymbol), boundaries, prefix)\n    }\n  }\n\n  private[this] def makePrefixReference(originalType: Type): Option[AppliedReference] = {\n\n    @tailrec def extractPrefix(t0: Type): Option[Type] = {\n      t0 match {\n        case t: TypeRefApi => Some(t.pre).filterNot(_ == NoPrefix)\n        case t: SingleTypeApi => Some(t.pre).filterNot(_ == NoPrefix)\n        case t: ExistentialTypeApi => extractPrefix(t.underlying)\n        case t: ThisTypeApi => extractPrefix(if (t.sym.isType) t.sym.asType.toType else t.sym.asTerm.typeSignature)\n        case _ => None\n      }\n    }\n\n    def unpackPrefix(pre: Type): Option[AppliedReference] = {\n      pre match {\n        case i if i.typeSymbol.isPackage =>\n          None\n        case k if k == NoPrefix =>\n          None\n        case k: ThisTypeApi =>\n          k.sym.asType.toType match {\n            // This case matches UniRefinement.unapply#it.RefinementTypeRef case\n            case UniRefinement(_, _) =>\n              None\n            case _ =>\n              if (originalType.termSymbol != NoSymbol) {\n                fromRef(originalType.termSymbol.owner.asType.toType)\n              } else {\n                fromRef(originalType.typeSymbol.owner.asType.toType)\n              }\n          }\n        case k if k.termSymbol != NoSymbol =>\n          handleSingletonType(k)\n        case o =>\n          fromRef(o)\n      }\n    }\n\n    def handleSingletonType(initType: Type): Some[NameReference] = {\n      def tryDealiasSingletons(tpe: Type): (Symbol, Type) = {\n        // Using `termSymbol` to convert from a type to a `Symbol` and then back to a type\n        // can be potentially lossy.\n        // This is relevant in cases where the type is a singleton for an effectively\n        // final definition, in which case the symbol we will get is dealiased to the symbol\n        // from the original base class:\n        // ```\n        // trait Base { object Inner }\n        // object Sub extends Base\n        // ```\n        // Calling `termSymbol` on `Sub.Inner.type` will produce `Base.Inner` since\n        // `Inner` is effectively final and `Sub.Inner` can be viewed as an alias for `Base.Inner`.\n        // When we go back to a type to continue building the prefix we will lose the original\n        // type information we started with.\n        // We want to avoid that and maintain the correct `Sub` prefix.\n        // As of writing the `dealiasSingletons` logic below is relevant only\n        // for `val` aliases. In other cases we want to avoid the lossy conversion.\n        // Here we check whether the symbol stands for an `object` (module) if so, we skip\n        // the dealiasing logic for singletons to avoid the potential loss of type information.\n        val termSym = tpe.termSymbol\n        val shouldDealias = !termSym.isModule\n\n        if (shouldDealias) {\n          Dealias.dealiasSingletons(termSym, tpe)\n        } else {\n          (termSym, tpe)\n        }\n      }\n\n      val (dealiasedSym, rawTpe0) = tryDealiasSingletons(initType)\n      val dealiasedTpe = Dealias.fullNormDealias(rawTpe0)\n\n      val name = makeSymName(dealiasedSym)\n      val prePrefix = makePrefixReference(dealiasedTpe)\n\n      Some(NameReference(name, Boundaries.Empty, prePrefix))\n    }\n\n    def fromRef(o: Type): Option[AppliedReference] = {\n      makeRef(o) match {\n        case a: AppliedReference =>\n          Some(a)\n        case o =>\n          throw new IllegalStateException(s\"Cannot extract prefix from $originalType: expected applied reference, but got $o\")\n      }\n    }\n\n    val prefix = extractPrefix(originalType)\n    val unpacked = prefix.flatMap(unpackPrefix)\n    unpacked\n  }\n\n  private[this] def makeSymName(sym: Symbol): SymName = {\n    val o = sym.owner\n    val base = if (o.asInstanceOf[{ def hasMeaninglessName: Boolean }].hasMeaninglessName) {\n      sym.name.decodedName.toString\n    } else {\n      sym.fullName\n    }\n\n    if (hasSingletonType(sym)) {\n      SymTermName(base)\n    } else {\n      SymTypeName(base)\n    }\n  }\n\n  private[this] def makeVariance(tpes: TypeSymbol): Variance = {\n    if (tpes.isCovariant) {\n      Variance.Covariant\n    } else if (tpes.isContravariant) {\n      Variance.Contravariant\n    } else {\n      Variance.Invariant\n    }\n  }\n\n  private[this] object UniRefinement {\n\n    def unapply(tpe: Type): Option[(List[Type], List[Symbol])] = {\n      (tpe: AnyRef) match {\n        case x: scala.reflect.internal.Types#RefinementTypeRef =>\n          Some((x.parents.asInstanceOf[List[Type]], x.decls.toList.asInstanceOf[List[Symbol]]))\n        case r: RefinedTypeApi @unchecked =>\n          Some((r.parents, r.decls.toList))\n        case _ =>\n          None\n      }\n    }\n\n    def breakRefinement(t0: Type, squashHKTRefToPolyTypeResultType: Boolean): Broken[Type, Symbol] = {\n      breakRefinement0(t0, squashHKTRefToPolyTypeResultType) match {\n        case (t, d) if d.isEmpty && t.size == 1 =>\n          Broken.Single(t.head)\n        case (t, d) =>\n          logger.log(s\"Found compound type parents=$t decls=$d\")\n          Broken.Compound(t, d)\n      }\n    }\n\n    private[this] def breakRefinement0(t0: Type, squashHKTRefToPolyTypeResultType: Boolean): (Set[Type], Set[Symbol]) = {\n      val normalized = if (squashHKTRefToPolyTypeResultType) {\n        Dealias.fullNormDealiasSquashHKTToPolyTypeResultType(t0)\n      } else {\n        Dealias.fullNormDealias(t0)\n      }\n      normalized match {\n        case UniRefinement(parents, decls) =>\n          val parts = parents.map(breakRefinement0(_, squashHKTRefToPolyTypeResultType))\n          val types = parts.flatMap(_._1)\n          val partsDecls = parts.flatMap(_._2)\n          (types.toSet, (decls ++ partsDecls).toSet)\n        case t =>\n          (Set(t), Set.empty)\n      }\n    }\n\n    def typeOfParam(p: Symbol): Type = {\n      p.typeSignature\n    }\n\n    def typeOfTypeMember(decl: Symbol): Type = {\n      if (decl.isAbstract) {\n        // Generate a type like {type F = F|<λ %2:0 → Nothing..λ %2:0 → Any>}\n        // on Scala 2 for abstract type lambdas like `type F[A] <: Any`\n        // This form is inferior to Scala 3's default {type F = F|<Nothing..λ %1:0 → Any>}\n        // But it's valid for comparisons\n        val invertTypeBoundsForPolyTypes = {\n          decl.typeSignature match {\n            case _: PolyTypeApi =>\n              internal.typeBounds(\n                lo = decl.typeSignature.map { case TypeBounds(lo, _) => lo; case t => t },\n                hi = decl.typeSignature.map { case TypeBounds(_, hi) => hi; case t => t }\n              )\n            case _ =>\n              decl.typeSignature\n          }\n        }\n\n        invertTypeBoundsForPolyTypes\n      } else {\n        decl.typeSignature\n      }\n    }\n\n    def concreteTypesOfTypeMemberOnly(decl: Symbol): List[Type] = {\n      if (decl.isAbstract) {\n        decl.typeSignature match {\n          case TypeBounds(lo, hi) => List(lo, hi)\n          case _ => Nil\n          // we ignore higher kinded type members like `type F[A] = A`\n          // because supporting them is highly non-straightforward (unlike on Scala 3)\n        }\n      } else {\n        List(decl.typeSignature)\n      }\n    }\n\n  }\n\n  private[this] object Dealias {\n\n    def fullNormDealiasSquashHKTToPolyTypeResultType(t0: Type): Type = {\n      var prev = null: Type\n      val t1 = fullNormDealias(t0)\n      var cur = if (t1.takesTypeArgs) t1.etaExpand else t1\n\n      while (cur ne prev) {\n        prev = cur\n        cur = norm(prev).dealias.resultType\n      }\n      cur\n    }\n\n    def fullNormDealias(t0: Type): Type = {\n      scala211ExistentialDealiasWorkaround(t0)\n    }\n\n    // On Scala 2.12+ .dealias automatically destroys wildcards by using TypeMaps#ExistentialExtrapolation on dealiased existential output\n    // This is kinda bad. But whatever, we're stuck with this behavior for this moment, so we should emulate it on 2.11 to make it work too.\n    @tailrec\n    private[this] def scala211ExistentialDealiasWorkaround(t0: Type): Type = {\n      t0 match {\n        case existential: ExistentialTypeApi =>\n          internal.existentialType(existential.quantified, scala211ExistentialDealiasWorkaroundLoop(existential.underlying.dealias))\n        // internal.existentialAbstraction(existential.quantified, existential.underlying.dealias)\n        case t =>\n          val next = norm(t).dealias\n          if (next eq t) {\n            t\n          } else {\n            scala211ExistentialDealiasWorkaround(next)\n          }\n      }\n    }\n\n    private[this] def scala211ExistentialDealiasWorkaroundLoop(t0: Type): Type = scala211ExistentialDealiasWorkaround(t0)\n\n    @tailrec\n    def dealiasSingletons(termSymbol: Symbol, termSymbolTpe: Type): (Symbol, Type) = {\n      val resultTermTpe = termSymbol.typeSignature.finalResultType\n      val resultTerm = resultTermTpe.termSymbol\n\n      if (hasSingletonType(resultTerm)) {\n        dealiasSingletons(resultTerm, resultTermTpe)\n      } else {\n        (termSymbol, termSymbolTpe)\n      }\n    }\n\n    @inline def norm(x: Type): Type = {\n      ReflectionUtil.norm(u: u.type, logger)(x)\n    }\n\n  }\n\n  private[this] def isHKTOrPolyTypeOrResultTypeArtifact(tpe: Type): Boolean = {\n    isHKTOrPolyType(tpe) || (!ReflectionUtil.isAbstractType(tpe) && tpe.typeArgs.exists {\n      targ =>\n        val tSym = targ.typeSymbol\n        targ.isInstanceOf[Universe#TypeRefApi] && tSym.isParameter && tSym.isType && !ReflectionUtil.isIdentityLikeTypeLambda(targ)\n    })\n  }\n\n  private[this] def isHKTOrPolyType(tpe: Type): Boolean = {\n    tpe.takesTypeArgs || tpe.isInstanceOf[PolyTypeApi]\n  }\n\n  private[this] def isExistentialArtifact(tpe: Type): Boolean = {\n    tpe.typeArgs.exists {\n      targ =>\n        val tSym = targ.typeSymbol\n        tSym.isType && tSym.asType.isExistential\n    }\n  }\n\n  private[this] def hasSingletonType(sym: Symbol): Boolean = {\n    sym.isTerm || sym.isModuleClass || isSingletonType(sym.typeSignature)\n  }\n\n  @inline private[this] def isSingletonType(tpe: Type): Boolean = {\n    tpe.isInstanceOf[SingletonTypeApi] && !tpe.isInstanceOf[ThisTypeApi]\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/macrortti/LightTypeTagMacro.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\nimport izumi.reflect.{DebugProperties, ReflectionUtil, TrivialMacroLogger}\n\nimport scala.reflect.macros.blackbox\n\nfinal class LightTypeTagMacro(override val c: blackbox.Context)\n  extends LightTypeTagMacro0[blackbox.Context](c)(\n    logger = TrivialMacroLogger.make[LightTypeTagMacro](c)\n  )\n\nprivate[reflect] class LightTypeTagMacro0[C <: blackbox.Context](val c: C)(logger: TrivialLogger) {\n\n  import c.universe._\n\n  protected final def cacheEnabled: Boolean = !c.settings.contains(s\"${DebugProperties.`izumi.reflect.rtti.cache.compile`}=false\")\n  protected final val impl = new LightTypeTagImpl[c.universe.type](c.universe, withCache = cacheEnabled, logger)\n\n  final def makeStrongHKTag[ArgStruct: c.WeakTypeTag]: c.Expr[LTag.StrongHK[ArgStruct]] = {\n    val tpe = unpackArgStruct(weakTypeOf[ArgStruct])\n    if (ReflectionUtil.allPartsStrong(tpe)) {\n      c.Expr[LTag.StrongHK[ArgStruct]](q\"new ${weakTypeOf[LTag.StrongHK[ArgStruct]]}(${makeParsedLightTypeTagImpl(tpe)})\")\n    } else {\n      c.abort(c.enclosingPosition, s\"Can't materialize LTag.StrongHKTag[$tpe]: found unresolved type parameters in $tpe\")\n    }\n  }\n\n  final def makeWeakHKTag[ArgStruct: c.WeakTypeTag]: c.Expr[LTag.WeakHK[ArgStruct]] = {\n    c.Expr[LTag.WeakHK[ArgStruct]](q\"new ${weakTypeOf[LTag.WeakHK[ArgStruct]]}(${makeParsedLightTypeTagImpl(unpackArgStruct(weakTypeOf[ArgStruct]))})\")\n  }\n\n  final def makeStrongTag[T: c.WeakTypeTag]: c.Expr[LTag[T]] = {\n    val tpe = weakTypeOf[T]\n    if (ReflectionUtil.allPartsStrong(tpe.dealias)) {\n      val res = makeParsedLightTypeTagImpl(tpe)\n      c.Expr[LTag[T]](q\"new ${weakTypeOf[LTag[T]]}($res)\")\n    } else {\n      c.abort(c.enclosingPosition, s\"Can't materialize LTag[$tpe]: found unresolved type parameters in $tpe\")\n    }\n  }\n\n  final def makeWeakTag[T: c.WeakTypeTag]: c.Expr[LTag.Weak[T]] = {\n    val res = makeParsedLightTypeTagImpl(weakTypeOf[T])\n    c.Expr[LTag.Weak[T]](q\"new ${weakTypeOf[LTag.Weak[T]]}($res)\")\n  }\n\n  final def makeParsedLightTypeTag[T: c.WeakTypeTag]: c.Expr[LightTypeTag] = {\n    makeParsedLightTypeTagImpl(weakTypeOf[T])\n  }\n\n  final def makeParsedLightTypeTagImpl(tpe: Type): c.Expr[LightTypeTag] = {\n    val res = impl.makeFullTagImpl(tpe)\n    makeParsedLightTypeTagImpl(res)\n  }\n\n  final def makeParsedLightTypeTagImpl(ltt: LightTypeTag): c.Expr[LightTypeTag] = {\n    logger.log(s\"LightTypeTagImpl: created LightTypeTag: $ltt\")\n\n    val serialized = ltt.serialize()\n    val hashCodeRef = serialized.hash\n    val strRef = serialized.ref\n    val strDBs = serialized.databases\n\n    c.Expr[LightTypeTag](\n      q\"_root_.izumi.reflect.macrortti.LightTypeTag.parse($hashCodeRef: _root_.scala.Int, $strRef : _root_.java.lang.String, $strDBs : _root_.java.lang.String, ${LightTypeTag.currentBinaryFormatVersion}: _root_.scala.Int)\"\n    )\n  }\n\n  @inline final def unpackArgStruct(t: Type): Type = {\n    def badShapeError() = {\n      c.abort(\n        c.enclosingPosition,\n        s\"Expected type shape RefinedType `{ type Arg[A] = X[A] }` for summoning `LTag.StrongHK/WeakHK[X]`, but got $t (raw: ${showRaw(t)} ${t.getClass})\"\n      )\n    }\n    t match {\n      case r: RefinedTypeApi =>\n        r.decl(TypeName(\"Arg\")) match {\n          case sym: TypeSymbolApi =>\n            sym.info.typeConstructor\n          case _ => badShapeError()\n        }\n      case _ => badShapeError()\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/macrortti/package.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport scala.language.experimental.macros\n\npackage object macrortti {\n  type LWeakTag[T] = LTag.Weak[T]\n  object LWeakTag {\n    def apply[T: LWeakTag]: LWeakTag[T] = implicitly\n  }\n\n  type LTagK[K[_]] = LTag.StrongHK[{ type Arg[A] = K[A] }]\n  type LTagKK[K[_, _]] = LTag.StrongHK[{ type Arg[A, B] = K[A, B] }]\n  type LTagK3[K[_, _, _]] = LTag.StrongHK[{ type Arg[A, B, C] = K[A, B, C] }]\n\n  type LTagT[K[_[_]]] = LTag.StrongHK[{ type Arg[A[_]] = K[A] }]\n  type LTagTK[K[_[_], _]] = LTag.StrongHK[{ type Arg[A[_], B] = K[A, B] }]\n  type LTagTKK[K[_[_], _, _]] = LTag.StrongHK[{ type Arg[A[_], B, C] = K[A, B, C] }]\n  type LTagTK3[K[_[_], _, _, _]] = LTag.StrongHK[{ type Arg[A[_], B, C, D] = K[A, B, C, D] }]\n\n  object LTagK {\n    /**\n      * Construct a type tag for a higher-kinded type `K[_]`\n      *\n      * Example:\n      * {{{\n      *     LTagK[Option]\n      * }}}\n      */\n    def apply[K[_]: LTagK]: LTagK[K] = implicitly\n  }\n\n  object LTagKK {\n    def apply[K[_, _]: LTagKK]: LTagKK[K] = implicitly\n  }\n\n  object LTagK3 {\n    def apply[K[_, _, _]: LTagK3]: LTagK3[K] = implicitly\n  }\n\n  object LTagT {\n    def apply[K[_[_]]: LTagT]: LTagT[K] = implicitly\n  }\n\n  object LTagTK {\n    def apply[K[_[_], _]: LTagTK]: LTagTK[K] = implicitly\n  }\n\n  object LTagTKK {\n    def apply[K[_[_], _, _]: LTagTKK]: LTagTKK[K] = implicitly\n  }\n\n  object LTagTK3 {\n    def apply[K[_[_], _, _, _]: LTagTK3]: LTagTK3[K] = implicitly\n  }\n\n  // simple materializers\n  def LTT[T]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T]\n  def `LTT[_]`[T[_]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[+_]`[T[+_]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[A,B,_>:B<:A]`[A, B <: A, T[_ >: B <: A]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[A[_],_[_[x] <: A[x]]`[A[_], T[B[x] <: A[x]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_[_]]`[T[_[_]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_[+_]]`[T[_[+_]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_[+_[_]]]`[T[_[+_[_]]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_[_[_]]]`[T[_[_[_]]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_,_]`[T[_, _]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing, Nothing]]\n  def `LTT[_[_,_]]`[T[_[_, _]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_[+_,+_]]`[T[_[+_, +_]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n  def `LTT[_[_,_],_,_]`[T[_[_, _], _, _]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing, Nothing, Nothing]]\n  def `LTT[_[+_,+_],_,_]`[T[_[+_, +_], _, _]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing, Nothing, Nothing]]\n  def `LTT[_[_],_[_]]`[T[_[_], _[_]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing, Nothing]]\n  def `LTT[_[_[_],_[_]]]`[T[_[_[_], _[_]]]]: LightTypeTag = macro LightTypeTagMacro.makeParsedLightTypeTag[T[Nothing]]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2/izumi/reflect/package.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi\n\npackage object reflect {\n\n  /**\n    * `TagK` is like a [[scala.reflect.api.TypeTags.TypeTag]] but for higher-kinded types.\n    *\n    * Example:\n    * {{{\n    * def containerTypesEqual[F[_]: TagK, K[_]: TagK]): Boolean = TagK[F].tag.tpe =:= TagK[K].tag.tpe\n    *\n    * containerTypesEqual[Set, collection.immutable.Set] == true\n    * containerTypesEqual[Array, List] == false\n    * }}}\n    */\n  type TagK[K[_]] = HKTag[{ type Arg[A] = K[A] }]\n  type TagKK[K[_, _]] = HKTag[{ type Arg[A, B] = K[A, B] }]\n  type TagK3[K[_, _, _]] = HKTag[{ type Arg[A, B, C] = K[A, B, C] }]\n\n  type TagT[K[_[_]]] = HKTag[{ type Arg[A[_]] = K[A] }]\n  type TagTK[K[_[_], _]] = HKTag[{ type Arg[A[_], B] = K[A, B] }]\n  type TagTKK[K[_[_], _, _]] = HKTag[{ type Arg[A[_], B, C] = K[A, B, C] }]\n  type TagTK3[K[_[_], _, _, _]] = HKTag[{ type Arg[A[_], B, C, D] = K[A, B, C, D] }]\n\n  object TagK {\n    /**\n      * Construct a type tag for a higher-kinded type `K[_]`\n      *\n      * Example:\n      * {{{\n      *     TagK[Option]\n      * }}}\n      */\n    @inline def apply[K[_]: TagK]: TagK[K] = implicitly\n  }\n\n  object TagKK {\n    @inline def apply[K[_, _]: TagKK]: TagKK[K] = implicitly\n  }\n\n  object TagK3 {\n    @inline def apply[K[_, _, _]: TagK3]: TagK3[K] = implicitly\n  }\n\n  object TagT {\n    @inline def apply[K[_[_]]: TagT]: TagT[K] = implicitly\n  }\n\n  object TagTK {\n    @inline def apply[K[_[_], _]: TagTK]: TagTK[K] = implicitly\n  }\n\n  object TagTKK {\n    @inline def apply[K[_[_], _, _]: TagTKK]: TagTKK[K] = implicitly\n  }\n\n  object TagTK3 {\n    @inline def apply[K[_[_], _, _, _]: TagTK3]: TagTK3[K] = implicitly\n  }\n\n  type TagK4[K[_, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3] = K[A0, A1, A2, A3] }]\n  type TagK5[K[_, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4] = K[A0, A1, A2, A3, A4] }]\n  type TagK6[K[_, _, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4, A5] = K[A0, A1, A2, A3, A4, A5] }]\n  type TagK7[K[_, _, _, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6] = K[A0, A1, A2, A3, A4, A5, A6] }]\n  type TagK8[K[_, _, _, _, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7] = K[A0, A1, A2, A3, A4, A5, A6, A7] }]\n  type TagK9[K[_, _, _, _, _, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8] }]\n  type TagK10[K[_, _, _, _, _, _, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9] }]\n  type TagK11[K[_, _, _, _, _, _, _, _, _, _, _]] = HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] }]\n  type TagK12[K[_, _, _, _, _, _, _, _, _, _, _, _]] =\n    HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] }]\n  type TagK13[K[_, _, _, _, _, _, _, _, _, _, _, _, _]] =\n    HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12] }]\n  type TagK14[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _]] =\n    HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13] }]\n  type TagK15[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] =\n    HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14] }]\n  type TagK16[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] =\n    HKTag[{ type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15] }]\n  type TagK17[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = HKTag[{\n    type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16] = K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16]\n  }]\n  type TagK18[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = HKTag[{\n    type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17] =\n      K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17]\n  }]\n  type TagK19[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = HKTag[{\n    type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18] =\n      K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18]\n  }]\n  type TagK20[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = HKTag[{\n    type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19] =\n      K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19]\n  }]\n  type TagK21[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = HKTag[{\n    type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20] =\n      K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20]\n  }]\n  type TagK22[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = HKTag[{\n    type Arg[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21] =\n      K[A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21]\n  }]\n\n// TODO\n//  type TagKUBound[U, K[_ <: U]] = HKTag[{ type Arg[A <: U] = K[A] }]\n//  object TagKUBound {\n//    def apply[U, K[_ <: U]](implicit ev: TagKUBound[U, K]): TagKUBound[U, K] = implicitly\n//  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.11/izumi/reflect/internal/NowarnCompat/nowarn.scala",
    "content": "package izumi.reflect.internal.NowarnCompat\n\nprivate[reflect] class nowarn(value: String = \"\") extends scala.annotation.ClassfileAnnotation\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.12+/izumi/reflect/internal/NowarnCompat.scala",
    "content": "package izumi.reflect.internal\n\nprivate[reflect] object NowarnCompat {\n  private[reflect] final type nowarn = scala.annotation.nowarn\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.12-/izumi/reflect/internal/CollectionCompat.scala",
    "content": "package izumi.reflect.internal\n\nprivate[reflect] object CollectionCompat {\n  private[reflect] final type IterableOnce[+A] = scala.collection.TraversableOnce[A]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.12-/izumi/reflect/internal/OrderingCompat.scala",
    "content": "package izumi.reflect.internal\n\nimport scala.collection.mutable\n\nprivate[reflect] object OrderingCompat {\n  @inline private[reflect] def listOrdering[A](ordering: Ordering[A]): Ordering[List[A]] = {\n    Ordering.Implicits.seqDerivedOrdering(ordering)\n  }\n  @inline private[reflect] def arrayOrdering[A](ordering: Ordering[A]): Ordering[Array[A]] = {\n    Ordering.Implicits.seqDerivedOrdering[ArraySeqLike, A](ordering).on(array => array)\n  }\n  private[reflect] final type ArraySeqLike[A] = mutable.WrappedArray[A]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.12-/izumi/reflect/internal/fundamentals/platform/language/unused.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.platform.language\n\nprivate[reflect] final class unused extends deprecated(\"unused\", \"unused\")\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.13+/izumi/reflect/internal/CollectionCompat.scala",
    "content": "package izumi.reflect.internal\n\nprivate[reflect] object CollectionCompat {\n  private[reflect] final type IterableOnce[+A] = scala.collection.IterableOnce[A]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.13+/izumi/reflect/internal/OrderingCompat.scala",
    "content": "package izumi.reflect.internal\n\nimport scala.collection.mutable\n\nprivate[reflect] object OrderingCompat {\n  @inline private[reflect] def listOrdering[A](ordering: Ordering[A]): Ordering[List[A]] = {\n    Ordering.Implicits.seqOrdering(ordering)\n  }\n  @inline private[reflect] def arrayOrdering[A](ordering: Ordering[A]): Ordering[Array[A]] = {\n    Ordering.Implicits.seqOrdering[ArraySeqLike, A](ordering).on(array => array)\n  }\n  private[reflect] final type ArraySeqLike[A] = mutable.ArraySeq[A]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-2.13+/izumi/reflect/internal/fundamentals/platform/language/package.scala",
    "content": "package izumi.reflect.internal.fundamentals.platform\n\npackage object language {\n  private[reflect] type unused = scala.annotation.unused\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/TagMacro.scala",
    "content": "package izumi.reflect\n\nimport scala.quoted.{Expr, Quotes, Type, Varargs}\nimport izumi.reflect.macrortti.{LightTypeTag, LightTypeTagRef}\nimport izumi.reflect.dottyreflection.{Inspect, InspectorBase, ReflectionUtil}\nimport izumi.reflect.macrortti.LightTypeTagRef.{FullReference, NameReference, SymName, TypeParam, Variance}\n\nimport scala.collection.mutable\n\nobject TagMacro {\n  def createTagExpr[A <: AnyKind: Type](using Quotes): Expr[Tag[A]] =\n    new TagMacro().createTagExpr[A]\n}\n\nfinal class TagMacro(using override val qctx: Quotes) extends InspectorBase {\n  import qctx.reflect._\n\n  override def shift: Int = 0\n\n  private val tagSymbol = Symbol.requiredClass(\"izumi.reflect.Tag\")\n  private val tagSymbolTypeRef = tagSymbol.typeRef\n\n  private val tagObjSymbol = Symbol.requiredModule(\"izumi.reflect.Tag\")\n  private val tagObjApplyMethodSym = tagObjSymbol.declaredMethod(\"apply\").find(_.paramSymss(1).size == 2).get\n\n  private lazy val tagWildCardTpe = Type.of[Tag[?]]\n\n  def createTagExpr[A <: AnyKind: Type]: Expr[Tag[A]] = {\n    val owners = getClassDefOwners(Symbol.spliceOwner)\n    val typeRepr = TypeRepr.of[A]._dealiasSimplifiedFull\n    if (allPartsStrong(owners, typeRepr)) {\n      createTag[A](typeRepr)\n    } else {\n      summonCombinedTag[A](owners, typeRepr)\n    }\n  }\n\n  private def createTag[A <: AnyKind](typeRepr0: TypeRepr): Expr[Tag[A]] = {\n    val typeRepr = typeRepr0._etaExpandTypeRef // convert HKT type refs to type lambdas manually as an optimization. This required an additional splice level before.\n    val ltt = Inspect.inspectTypeRepr(typeRepr)\n    val cls = closestClassOfTypeRepr(typeRepr)\n    Apply(\n      fun = TypeApply(\n        fun = Select(qualifier = Ref.term(tagObjSymbol.termRef), symbol = tagObjApplyMethodSym),\n        args = List(Inferred(typeRepr))\n      ),\n      args = List(cls.asTerm, ltt.asTerm)\n    ).asExpr.asInstanceOf[Expr[Tag[A]]]\n  }\n\n  private def summonCombinedTag[T <: AnyKind: Type](owners: Set[Symbol], typeReprDealiased: TypeRepr): Expr[Tag[T]] = {\n\n    def summonLTT(typeRepr: TypeRepr): Expr[LightTypeTag] = {\n      typeRepr match {\n        case TypeBounds(low, high) =>\n          val lowTag = summonTag[T](low)\n          val highTag = summonTag[T](high)\n          '{ LightTypeTag.wildcardType($lowTag.tag, $highTag.tag) }\n        case _ =>\n          val result = summonTag[T](typeRepr)\n          '{ $result.tag }\n      }\n    }\n\n    def summonIfNotLambdaParamOf(typeRepr: TypeRepr, lam: TypeRepr): Expr[Option[LightTypeTag]] = {\n      if (isLambdaParamOf(typeRepr, lam)) {\n        '{ None }\n      } else {\n        val tag = summonLTT(typeRepr)\n        '{ Some($tag) }\n      }\n    }\n\n    def isLambdaParamOf(typeRepr: TypeRepr, lam: TypeRepr): Boolean = {\n      typeRepr match {\n        case ref: ParamRef if ref.binder == lam => true\n        case _ => false\n      }\n    }\n\n    typeReprDealiased match {\n      case outerLambda: TypeLambda =>\n        outerLambda.resType match {\n          case AppliedType(ctorTpe, typeArgsTpes) =>\n            val paramsRange = 0 until outerLambda.paramNames.size\n            val isSimpleApplication = typeArgsTpes.collect {\n              case ref: ParamRef if ref.binder == outerLambda => ref.paramNum\n            } == paramsRange\n\n            val constructorTag = summonTag[T](ctorTpe)\n            if (isSimpleApplication) {\n              val argsTags = Expr.ofList(typeArgsTpes.map(a => summonIfNotLambdaParamOf(a, outerLambda)))\n              '{ Tag.appliedTagNonPos[T](${ constructorTag }, ${ argsTags }) }\n            } else {\n              val distinctNonParamArgsTypes = typeArgsTpes.filter(!isLambdaParamOf(_, outerLambda)).distinct\n              val outerLambdaParamArgsTypeParamRefs = paramsRange.map(outerLambda.param(_)).toList\n\n              val arity = 1 + distinctNonParamArgsTypes.size + outerLambdaParamArgsTypeParamRefs.size\n              val fullParamTail = (distinctNonParamArgsTypes ++ outerLambdaParamArgsTypeParamRefs)\n                .iterator.distinct.zipWithIndex\n              val typeArgToLambdaParameterMap = fullParamTail.map {\n                case (argTpe, idx) =>\n                  val idxPlusOne = idx + 1\n                  val lambdaParameter = SymName.LambdaParamName(idxPlusOne, LightTypeTagRef.LambdaConstants.tagMacro, arity)\n                  argTpe -> lambdaParameter\n              }.toMap\n\n              val usageOrderDistinctNonLambdaArgs = distinctNonParamArgsTypes.map(t => typeArgToLambdaParameterMap(t))\n              val declarationOrderLambdaParamArgs = outerLambdaParamArgsTypeParamRefs.map(t => typeArgToLambdaParameterMap(t))\n              val completeTail = usageOrderDistinctNonLambdaArgs ::: declarationOrderLambdaParamArgs\n\n              val usages = typeArgsTpes.map(t => TypeParam(NameReference(typeArgToLambdaParameterMap(t)), Variance.Invariant))\n\n              // we give a distinct lambda parameter to the constructor, even if constructor is one of the type parameters\n              val firstParamIdx = 0\n              assert(completeTail.size + 1 == arity)\n              val ctorLambdaParameter = SymName.LambdaParamName(firstParamIdx, LightTypeTagRef.LambdaConstants.tagMacro, arity)\n\n              val ctorApplyingLambda =\n                LightTypeTagRef.Lambda(\n                  ctorLambdaParameter :: completeTail,\n                  FullReference(ctorLambdaParameter, usages)\n                )\n\n              log(s\"\"\"HK non-trivial lambda construction:\n                     |ctorApplyingLambda=$ctorApplyingLambda\n                     |usageOrderNonLambdaArgs=$usageOrderDistinctNonLambdaArgs\n                     |declarationOrderLambdaParamArgs=$declarationOrderLambdaParamArgs\n                     |\"\"\".stripMargin)\n\n              val argTagsExceptCtor = {\n                val nonParamArgsDealiased = distinctNonParamArgsTypes.map(_._dealiasSimplifiedFull)\n                log(s\"HK COMPLEX Now summoning tags for args=$nonParamArgsDealiased outerLambdaParams=$outerLambdaParamArgsTypeParamRefs\")\n                Expr.ofList(\n                  nonParamArgsDealiased.map(t => '{ Some(${ summonLTT(t) }) }) ++ outerLambdaParamArgsTypeParamRefs.map(_ => '{ None })\n                )\n              }\n\n              val outerLambdaReprTag = Inspect.makeParsedLightTypeTagImpl(LightTypeTag(ctorApplyingLambda, Map.empty, Map.empty))\n              '{\n                val ctorTag = ${ constructorTag }.asInstanceOf[Tag[Any]]\n                Tag.appliedTagNonPosAux[T](ctorTag.closestClass, ${ outerLambdaReprTag }, Some(ctorTag.tag) :: ${ argTagsExceptCtor })\n              }\n            }\n\n          case other =>\n            // TODO add support for and/or/refinement, see test with `IntersectionBlockingIO`\n            report.warning(\n              s\"\"\"TODO: Pathological intersection refinement result in lambda being reconstructed result=`${other.show}` in the rhs of type lambda lam=`${outerLambda.show}`\n                 |Only simple applied types of form F[A] are supported in results of type lambdas. The generated tag will not work correctly.\"\"\".stripMargin\n            )\n            createTag[T](outerLambda)\n        }\n\n      case AppliedType(ctor, args) =>\n        val ctorTag = summonTag[T](ctor)\n        val argsTags = Expr.ofList(args.map(summonLTT))\n        '{ Tag.appliedTag[T](${ ctorTag }, ${ argsTags }) }\n\n      case andType: AndType =>\n        val tpes = flattenAnd(andType)\n        val ltts: Expr[List[LightTypeTag]] = Expr.ofList(tpes.map(summonLTT))\n        val cls = Literal(ClassOfConstant(lubClassOf(typeReprDealiased, tpes))).asExpr.asInstanceOf[Expr[Class[?]]]\n        val dummyAnyStructLtt = {\n          // FIXME add constructor for intersections without the unused on Scala 3 struct type\n          Inspect.inspectAny[Any]\n        }\n        '{ Tag.refinedTag[T](${ cls }, ${ ltts }, ${ dummyAnyStructLtt }, Map.empty) }\n\n      case orType: OrType =>\n        val tpes = flattenOr(orType)\n        val ltts: Expr[List[LightTypeTag]] = Expr.ofList(tpes.map(summonLTT))\n        val cls = Literal(ClassOfConstant(lubClassOf(typeReprDealiased, tpes))).asExpr.asInstanceOf[Expr[Class[?]]]\n        '{ Tag.unionTag[T](${ cls }, ${ ltts }) }\n\n      case refinement: Refinement =>\n        val (members, parent) = flattenRefinements(refinement)\n        val cls = closestClassOfTypeRepr(parent)\n        val parentLtt = summonLTT(parent)\n\n        val (allTypeMembers, termMembers) = members.partitionMap {\n          case (s, n, tb: TypeBounds) if allPartsStrong(owners, tb) => Left(Left((n, tb)))\n          case (_, n, TypeBounds(lo, hi)) if lo == hi => Left(Right((n, hi)))\n          case (_, _, tb @ TypeBounds(lo, hi)) =>\n            report.errorAndAbort(\n              s\"TagMacro: resolving type parameters inside type bounds is not supported, got weak types in bounds=${tb.show}, in type=$typeReprDealiased\"\n            )\n          case x => Right(x)\n        }\n        val (strongTypeBounds, weakTypeMembers) = allTypeMembers.partitionMap(identity)\n        // FIXME: once we add resolution for method/val members too, not just type members\n        //  this struct will no longer be 'weak'. In fact we'll want to add a new constructor\n        //  instead of `refinedTag` that will be better suited to fully resolved struct tags\n        val termAndStrongTpesOnlyWeakStructLtt = {\n          val termOnlyRefinementTypeRepr = termMembers.foldRight(defn.AnyRefClass.typeRef: TypeRepr) {\n            case ((_, name, tpe), refinement) =>\n              Refinement(parent = refinement, name = name, info = tpe)\n          }\n          val withStrongTpesRefinementTypeRepr = strongTypeBounds.foldRight(termOnlyRefinementTypeRepr) {\n            case ((name, tpe), refinement) =>\n              Refinement(parent = refinement, name = name, info = tpe)\n          }\n          Inspect.inspectTypeRepr(withStrongTpesRefinementTypeRepr)\n        }\n        val resolvedTypeMemberLtts = weakTypeMembers.map {\n          case (name, tpe) => '{ (${ Expr(name) }, ${ summonLTT(tpe) }) }\n        }\n        // NB: we're resolving LTTs anew for all type members here, instead of optimizing\n        // to resolve only for 'weak' members as in Scala 2.\n        log(\n          s\"\"\"Got refinement $refinement\n             |parent=$parent\n             |members=$members\n             |closestClass=$cls\n             |\"\"\".stripMargin\n        )\n        '{ Tag.refinedTag[T](${ cls }, List(${ parentLtt }), ${ termAndStrongTpesOnlyWeakStructLtt }, Map(${ Varargs(resolvedTypeMemberLtts) }: _*)) }\n\n      // error: the entire type is just a proper type parameter with no type arguments\n      // it cannot be resolved further\n      case x if ReflectionUtil.topLevelWeakType(owners, Set.empty, x) =>\n        val tStr = x.show\n        val implicitMessage = defaultImplicitError.replace(\"${T}\", tStr)\n        report.errorAndAbort(s\"\"\"$tStr is a type parameter without an implicit Tag!\n                                |  $implicitMessage\n                                |\"\"\".stripMargin)\n\n      case _ =>\n        report.errorAndAbort(s\"Unsupported type in TagMacro.summonCombinedTag: $typeReprDealiased\")\n    }\n  }\n\n  private def closestClassOfTypeRepr(typeRepr: TypeRepr): Expr[Class[?]] = {\n    Literal(ClassOfConstant(lubClassOf(typeRepr, intersectionUnionRefinementClassPartsOf(typeRepr)))).asExpr.asInstanceOf[Expr[Class[?]]]\n  }\n\n  private def lubClassOf(specificTpe: TypeRepr, tpes: List[TypeRepr]): TypeRepr = {\n    tpes.map(_.baseClasses) match {\n      case h :: t =>\n        val bases = h.to(mutable.LinkedHashSet)\n        t.foreach {\n          b =>\n            val bBases = b.to(mutable.HashSet)\n            bases.filterInPlace(bBases)\n        }\n        // rely on the fact that .baseClasses returns classes in order from most specific to least, therefore most specific class should be first.\n        val baseClass = bases.headOption.getOrElse(defn.AnyClass)\n        // try to recover type parameters of the specific type e.g. to support Arrays\n        // see https://github.com/zio/izumi-reflect/issues/474 & https://github.com/scala/scala3/issues/21916\n        specificTpe.baseType(baseClass)\n      // FIXME: below doesn't work, need to treat AnyVals specially\n//        bases.find(!_.typeRef.baseClasses.contains(defn.AnyValClass)).getOrElse(defn.AnyClass).typeRef\n      case Nil =>\n        defn.AnyClass.typeRef\n    }\n  }\n\n  private def summonTag[T <: AnyKind](typeRepr: TypeRepr)(using outerCombinedType: Type[T]): Expr[Tag[?]] = {\n    val tagTypeRepr = AppliedType(tagSymbolTypeRef, List(typeRepr))\n    Implicits.search(tagTypeRepr) match {\n      case s: ImplicitSearchSuccess =>\n        s.tree.asExpr.asInstanceOf[Expr[Tag[?]]]\n      case f: ImplicitSearchFailure =>\n        val aStr = typeRepr.show\n        val implicitMessage = defaultImplicitError.replace(\"${T}\", aStr)\n        val message = s\"\"\"Error when creating a combined tag for ${Type.show[T]}, when summoning Tag for part of that type $aStr:\n                         |  $implicitMessage\n                         |Structure of overall type was: `${TypeRepr.of[T]}`\n                         |Structure of part of the type was: `$typeRepr\n                         |Stack trace: ${locally {\n                          import java.io.{PrintWriter, StringWriter}\n                          val t = new Exception()\n                          val sw = new StringWriter()\n                          t.printStackTrace(new PrintWriter(sw))\n                          sw.toString\n                        }}\"\"\".stripMargin\n        report.errorAndAbort(message)\n    }\n  }\n\n  private inline val defaultImplicitError =\n    \"could not find implicit value for izumi.reflect.Tag[${T}]. Did you forget to put on a Tag, TagK or TagKK context bound on one of the parameters in ${T}? e.g. def x[T: Tag, F[_]: TagK] = ...\"\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/Tags.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\nimport izumi.reflect.dottyreflection.Inspect\nimport izumi.reflect.macrortti.{LTag, LightTypeTag, LightTypeTagRef}\n\nimport scala.annotation.implicitNotFound\n\ntrait AnyTag extends Serializable {\n  def tag: LightTypeTag\n\n  /**\n    * Closest class found for the type or for a LUB of all intersection\n    * members in case of an intersection type.\n    *\n    * A Scala type may not have an associated JVM class, as such\n    * this class may not be sufficient to create instances of `T`\n    *\n    * Only if `tag.hasPreciseClass` returns true\n    * it may be safe to reflect on `closestClass`\n    */\n  def closestClass: Class[_]\n\n  final def hasPreciseClass: Boolean = {\n    try tag.shortName == closestClass.getSimpleName\n    catch {\n      case i: InternalError if i.getMessage == \"Malformed class name\" => false\n    }\n  }\n\n  final def =:=(that: AnyTag): Boolean = {\n    tag =:= that.tag\n  }\n\n  final def <:<(that: AnyTag): Boolean = {\n    tag <:< that.tag\n  }\n\n  override final def equals(that: Any): Boolean = that match {\n    case that: AnyTag => this.tag == that.tag\n    case _ => false\n  }\n\n  override final def hashCode(): Int = tag.hashCode()\n\n  override def toString: String = s\"AnyTag[$tag]\"\n}\n\n/**\n  * Like [[scala.reflect.api.TypeTags.TypeTag]], but supports higher-kinded type tags via `TagK` type class.\n  *\n  * In context of DI this lets you define modules parameterized by higher-kinded type parameters.\n  * This is especially helpful for applying [[https://www.beyondthelines.net/programming/introduction-to-tagless-final/ `tagless final` style]]\n  *\n  * Example:\n  * {{{\n  * import distage.ModuleDef\n  *\n  * class MyModule[F[_]: Monad: TagK] extends ModuleDef {\n  *   make[MyService[F]]\n  *   make[F[Int]].named(\"lucky-number\").from(Monad[F].pure(7))\n  * }\n  * }}}\n  *\n  * Without a `TagK` constraint above, this example would fail with `no TypeTag available for MyService[F]` error\n  *\n  * Currently some limitations apply as to when a `Tag` will be correctly constructed:\n  *   * Type Parameters do not yet resolve in structural refinement methods, e.g. T in {{{ Tag[{ def x: T}] }}}\n  *     They do resolve in refinement type members however, e.g. {{{ Tag[ Any { type Out = T } ] }}}\n  *   * TagK* does not resolve for constructors with bounded parameters, e.g. S in {{{ class Abc[S <: String]; TagK[Abc] }}}\n  *     (You can still have a bound in partial application: e.g. {{{ class Abc[S <: String, A]; TagK[Abc[\"hi\", _]] }}}\n  *   * Further details at [[https://github.com/7mind/izumi/issues/374]]\n  *\n  * @see \"Lightweight Scala Reflection and why Dotty needs TypeTags reimplemented\" https://blog.7mind.io/lightweight-reflection.html\n  *\n  * @see [[izumi.reflect.macrortti.LTag]] - summoner for [[izumi.reflect.macrortti.LightTypeTag]] that does not resolve type parameters\n  * @see [[izumi.reflect.macrortti.LTag.Weak]] - summoner for [[izumi.reflect.macrortti.LightTypeTag]] that does not resolve type parameters and allows unresolved (\"weak\") type parameters to be part of a tag\n  */\n@implicitNotFound(\n  \"could not find implicit value for izumi.reflect.Tag[${T}]. Did you forget to put on a Tag, TagK or TagKK context bound on one of the parameters in ${T}? e.g. def x[T: Tag, F[_]: TagK] = ...\"\n)\ntrait Tag[T <: AnyKind] extends AnyTag {\n  def tag: LightTypeTag\n  def closestClass: Class[_]\n\n  override final def toString: String = s\"Tag[$tag]\"\n}\n\nobject Tag {\n\n  /**\n    * Use `Tag.auto.T[TYPE_PARAM]` syntax to summon a `Tag` for a type parameter of any kind:\n    *\n    * NOTE: On Scala 3+ it's the same as `Tag[T]`\n    */\n  object auto {\n    type T[X <: AnyKind] = Tag[X]\n  }\n\n  @inline def apply[T <: AnyKind: Tag]: Tag[T] = implicitly\n\n  def apply[T <: AnyKind](cls: Class[_], tag0: LightTypeTag): Tag[T] = {\n    new Tag[T] {\n      override val tag: LightTypeTag = tag0\n      override val closestClass: Class[_] = cls\n    }\n  }\n\n  /**\n    * Create a Tag of a type formed by applying the type in `tag` to `args`.\n    *\n    * Example:\n    * {{{\n    *   implicit def tagFromTagTAKA[T[_, _[_], _]: TagK3, K[_]: TagK, A0: Tag, A1: Tag]: Tag[T[A0, K, A1]] =\n    *     Tag.appliedTag(TagK3[T].tag, List(Tag[A0].tag, TagK[K].tag, Tag[A1].tag))\n    * }}}\n    */\n  def appliedTag[R <: AnyKind](tag: Tag[_], args: List[LightTypeTag]): Tag[R] = {\n    Tag(tag.closestClass, tag.tag.combine(args: _*))\n  }\n\n  def appliedTagNonPos[R <: AnyKind](tag: Tag[_], args: List[Option[LightTypeTag]]): Tag[R] = {\n    Tag(tag.closestClass, tag.tag.combineNonPos(args: _*))\n  }\n\n  def appliedTagNonPosAux[R <: AnyKind](cls: Class[_], ctor: LightTypeTag, args: List[Option[LightTypeTag]]): Tag[R] = {\n    Tag(cls, ctor.combineNonPos(args: _*))\n  }\n\n  def unionTag[R <: AnyKind](lubClass: Class[_], union: List[LightTypeTag]): Tag[R] = {\n    Tag(lubClass, LightTypeTag.unionType(union))\n  }\n\n  /**\n    * Create a Tag of a type formed from an `intersection` of types (A with B) with a structural refinement taken from `structType`\n    *\n    * `structType` is assumed to be contain the structural refinements of the entire type, e.g.\n    * {{{\n    *   Tag[A with B {def abc: Unit}] == refinedTag(classOf[Any], List(LTag[A].tag, LTag[B].tag), LTag.Weak[{ def abc: Unit }].tag, Map.empty)\n    * }}}\n    */\n  def refinedTag[R <: AnyKind](\n    lubClass: Class[_],\n    intersection: List[LightTypeTag],\n    structType: LightTypeTag,\n    additionalTypeMembers: Map[String, LightTypeTag]\n  ): Tag[R] = {\n    Tag(lubClass, LightTypeTag.refinedType(intersection, structType, additionalTypeMembers))\n  }\n\n  inline implicit final def tagFromTagMacro[T <: AnyKind]: Tag[T] = ${ TagMacro.createTagExpr[T] }\n}\n\n/**\n  * Internal unsafe API representing a poly-kinded, higher-kinded type tag.\n  *\n  * NOTE: On Scala 3+ it's the same as `Tag[T]`\n  */\ntype HKTag[T <: AnyKind] = Tag[T]\n\nobject HKTag {\n  def apply[T](cls: Class[_], lightTypeTag: LightTypeTag): Tag[T] = Tag(cls, lightTypeTag)\n\n  def appliedTag[R <: AnyKind](tag: Tag[_], args: List[LightTypeTag]): Tag[R] = Tag.appliedTag(tag, args)\n\n  def appliedTagNonPos[R <: AnyKind](tag: Tag[_], args: List[Option[LightTypeTag]]): Tag[R] = Tag.appliedTagNonPos(tag, args)\n\n  def appliedTagNonPosAux[R](cls: Class[_], ctor: LightTypeTag, args: List[Option[LightTypeTag]]): Tag[R] = Tag.appliedTagNonPosAux(cls, ctor, args)\n}\n\n/**\n  * `TagK` is like a [[scala.reflect.api.TypeTags.TypeTag]] but for higher-kinded types.\n  *\n  * NOTE: On Scala 3+ it's the same as `Tag[T]`\n  */\ntype TagK[K[_]] = Tag[K]\ntype TagKK[K[_, _]] = Tag[K]\ntype TagK3[K[_, _, _]] = Tag[K]\n\ntype TagT[K[_[_]]] = Tag[K]\ntype TagTK[K[_[_], _]] = Tag[K]\ntype TagTKK[K[_[_], _, _]] = Tag[K]\ntype TagTK3[K[_[_], _, _, _]] = Tag[K]\n\nobject TagK {\n  /**\n    * Construct a type tag for a higher-kinded type `K[_]`\n    *\n    * Example:\n    * {{{\n    *     TagK[Option]\n    * }}}\n    */\n  @inline def apply[K[_]: TagK]: TagK[K] = implicitly\n}\n\nobject TagKK {\n  @inline def apply[K[_, _]: TagKK]: TagKK[K] = implicitly\n}\n\nobject TagK3 {\n  @inline def apply[K[_, _, _]: TagK3]: TagK3[K] = implicitly\n}\n\nobject TagT {\n  @inline def apply[K[_[_]]: TagT]: TagT[K] = implicitly\n}\n\nobject TagTK {\n  @inline def apply[K[_[_], _]: TagTK]: TagTK[K] = implicitly\n}\n\nobject TagTKK {\n  @inline def apply[K[_[_], _, _]: TagTKK]: TagTKK[K] = implicitly\n}\n\nobject TagTK3 {\n  @inline def apply[K[_[_], _, _, _]: TagTK3]: TagTK3[K] = implicitly\n}\n\ntype TagK4[K[_, _, _, _]] = Tag[K]\ntype TagK5[K[_, _, _, _, _]] = Tag[K]\ntype TagK6[K[_, _, _, _, _, _]] = Tag[K]\ntype TagK7[K[_, _, _, _, _, _, _]] = Tag[K]\ntype TagK8[K[_, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK9[K[_, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK10[K[_, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK11[K[_, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK12[K[_, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK13[K[_, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK14[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK15[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK16[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK17[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK18[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK19[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK20[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK21[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\ntype TagK22[K[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]] = Tag[K]\n\n// Workaround needed specifically to support generic methods in factories, see `GenericAssistedFactory` and related tests\n//\n// We need to construct a SafeType signature for a generic method, but generic parameters have no type tags\n// So we resort to weak type parameters and pointer equality\ntrait WeakTag[T <: AnyKind] extends AnyTag {\n  def tag: LightTypeTag\n  def closestClass: Class[_]\n\n  override final def toString: String = s\"WeakTag[$tag]\"\n}\n\nobject WeakTag extends WeakTagInstances1 {\n  @inline def apply[T <: AnyKind: WeakTag]: WeakTag[T] = implicitly\n\n  def apply[T <: AnyKind](cls: Class[_], l: LightTypeTag): WeakTag[T] = {\n    new WeakTag[T] {\n      override val tag: LightTypeTag = l\n      override val closestClass: Class[_] = cls\n    }\n  }\n\n  implicit def weakTagFromTag[T <: AnyKind](implicit t: Tag[T]): WeakTag[T] = WeakTag(t.closestClass, t.tag)\n}\ntrait WeakTagInstances1 {\n  implicit final def weakTagFromWeakTypeTag[T <: AnyKind](implicit l: LTag.Weak[T]): WeakTag[T] = WeakTag(classOf[Any], l.tag)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/FullDbInspector.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport izumi.reflect.internal.fundamentals.collections.IzCollections.toRich\nimport izumi.reflect.macrortti.LightTypeTagRef\nimport izumi.reflect.macrortti.LightTypeTagRef.*\n\nimport scala.collection.immutable.Queue\nimport scala.collection.mutable\nimport scala.quoted.*\n\nobject FullDbInspector {\n  def make(q: Quotes): FullDbInspector { val qctx: q.type } = new FullDbInspector(0) {\n    override val qctx: q.type = q\n  }\n}\n\nabstract class FullDbInspector(protected val shift: Int) extends InspectorBase {\n  import qctx.reflect._\n\n  def buildFullDb(typeRepr: TypeRepr): Map[AbstractReference, Set[AbstractReference]] = {\n    new Run(Inspector.make(qctx), mutable.HashSet.empty, mutable.HashSet.empty)\n      .inspectTypeReprToFullBases(typeRepr, onlyIndirect = false)\n      .iterator\n      .filterNot {\n        case (t, parent) =>\n          parent == t\n      }\n      .toMultimap\n  }\n\n  class Run(\n    inspector: Inspector { val qctx: FullDbInspector.this.qctx.type },\n    basesTermination: mutable.HashSet[Symbol],\n    toLambdaTermination: mutable.HashSet[Symbol]\n  ) {\n    def inspectTypeReprToFullBases(tpe0: TypeRepr, onlyIndirect: Boolean): List[(AbstractReference, AbstractReference)] = {\n      val tpe = tpe0._dealiasSimplifiedFull\n      def selfRef(): AbstractReference = inspector.inspectTypeRepr(tpe)\n\n      tpe match {\n        case appliedType: AppliedType =>\n          extractBase(appliedType, selfRef(), onlyIndirect = onlyIndirect) ++ extractLambdaBase(appliedType, onlyIndirect = onlyIndirect)\n\n        case typeLambda: TypeLambda =>\n          val resultTypeParents = new Run(inspector.nextLam(typeLambda), basesTermination, toLambdaTermination).inspectTypeBoundsToFull(typeLambda.resType)\n\n          makeLambdaParents(selfRef(), resultTypeParents)\n\n        case a: AndType =>\n          inspectTypeReprToFullBases(a.left, onlyIndirect = false) ++ inspectTypeReprToFullBases(a.right, onlyIndirect = false)\n\n        case o: OrType =>\n          inspectTypeReprToFullBases(o.left, onlyIndirect = false) ++ inspectTypeReprToFullBases(o.right, onlyIndirect = false)\n\n        case typeRef: TypeRef =>\n          processSymbol(typeRef, selfRef(), onlyIndirect = onlyIndirect)\n\n        case _: ParamRef =>\n          // do not process type parameters for bases db\n          Nil\n\n        case termRef: TermRef =>\n          extractBase(termRef, selfRef(), onlyIndirect = onlyIndirect)\n\n        case b: TypeBounds =>\n          processTypeBounds(b)\n\n        case c: ConstantType =>\n          extractBase(c, selfRef(), onlyIndirect = onlyIndirect)\n\n        case t: ThisType =>\n          inspectTypeReprToFullBases(t.tref, onlyIndirect = onlyIndirect)\n\n        case r: Refinement =>\n          refinementInfoToParts(r.info).flatMap(inspectTypeBoundsToFull)\n            ++ inspectTypeReprToFullBases(r.parent, onlyIndirect = onlyIndirect)\n\n        case other =>\n          log(s\"FullDbInspector: UNSUPPORTED: $other\")\n          extractBase(other, selfRef(), onlyIndirect = onlyIndirect)\n      }\n    }\n\n    // Equivalent to Scala 2 LightTypeTagImpl.makeLambdaOnlyBases\n    private def extractLambdaBase(appliedType: AppliedType, onlyIndirect: Boolean): List[(AbstractReference, AbstractReference)] = {\n      if (onlyIndirect || toLambdaTermination.isTerminatingClsSym(appliedType)) {\n        Nil\n      } else {\n        appliedType._etaExpand match {\n          case None => Nil\n          case Some(typeLambda) =>\n            toLambdaTermination.addTerminatingClsSym(appliedType)\n\n            val resultTypeParents = new Run(inspector.nextLam(typeLambda), basesTermination, toLambdaTermination)\n              .inspectTypeBoundsToFull(typeLambda.resType)\n\n            makeLambdaParents(inspector.inspectTypeRepr(typeLambda), resultTypeParents)\n        }\n      }\n    }\n\n    private def makeLambdaParents(\n      selfRef: AbstractReference,\n      resultTypeParents: List[(AbstractReference, AbstractReference)]\n    ): List[(AbstractReference, AbstractReference)] = {\n      val selfL = selfRef.asInstanceOf[Lambda]\n\n      val out = resultTypeParents.flatMap {\n        case (child0, parent0) =>\n          val child = if (child0 == selfL.output) { // if child == typeLambda.resType, use typeLambda itself\n            selfL\n          } else {\n            child0\n          }\n\n          // For Scala 2: see LightTypeTagImpl.makeLambdaOnlyBases.makeLambdaParents\n          def maybeToLambda(parentOrChild: LightTypeTagRef): AbstractReference = parentOrChild match {\n            case l: Lambda =>\n              l\n            case applied: AppliedReference =>\n              val l = LightTypeTagRef.Lambda(selfL.input, applied)\n              if (l.someArgumentsReferenced) l else applied\n          }\n\n          val childMaybeAsLambda = maybeToLambda(child)\n          val parentMaybeAsLambda = maybeToLambda(parent0)\n\n          Seq(\n            (childMaybeAsLambda, parentMaybeAsLambda)\n            // you may debug by inserting some trash into the dbs:\n            //                NameReference(SymName.SymTypeName(s\"LEFT ${System.nanoTime()} before:$child after:$childMaybeAsLambda\")) ->\n            //                NameReference(SymName.SymTypeName(s\"RIGHT before:$parent0 after:$parentMaybeAsLambda\"))\n          )\n      }\n\n      out\n    }\n\n    private def processSymbol(r: TypeRef | ParamRef, selfRef: AbstractReference, onlyIndirect: Boolean): List[(AbstractReference, AbstractReference)] = {\n      r.typeSymbol match {\n        case s if s.isClassDef =>\n          extractBase(r, selfRef, onlyIndirect = onlyIndirect)\n\n        case s if s.isTypeDef =>\n//          println(r -> s -> r._underlying)\n          processTypeMemberWithTypeLambdaBounds(r, onlyIndirect = onlyIndirect)\n\n        case o =>\n          throw new RuntimeException(s\"Unknown tree: ${o.getClass} $o $r ${o.tree} (pretty: ${o.tree.show})\")\n      }\n    }\n\n    private def extractBase(tpe: TypeRepr, selfRef: AbstractReference, onlyIndirect: Boolean): List[(AbstractReference, AbstractReference)] = {\n      val argBasesRefs = tpe.typeArgs.flatMap {\n        case t if basesTermination.isTerminatingClsSym(t) => Nil\n        case t =>\n          inspectTypeBoundsToFull(t)\n      }\n\n      val baseTypes: List[TypeRepr] = tpe\n        .baseClasses\n        .map(tpe.baseType)\n        .filterNot(_ =:= tpe)\n\n      basesTermination.addTerminatingClsSym(tpe)\n\n      log(s\"For `${tpe.show}` (onlyIndirect=$onlyIndirect) found base types ${baseTypes.map(_.show)}\")\n\n      val recursiveParentRefs = baseTypes.flatMap {\n        case t if basesTermination.isTerminatingClsSym(t) => Nil\n        case t => inspectTypeReprToFullBases(t, onlyIndirect = true)\n      }\n\n      val directBaseRefs = if (onlyIndirect) {\n        Nil\n      } else {\n        baseTypes.map {\n          bt =>\n            val parentRef = inspector.inspectTypeRepr(bt)\n            (selfRef, parentRef)\n        }\n      }\n\n      val mainBasesRefs = recursiveParentRefs ::: directBaseRefs\n\n      argBasesRefs ::: mainBasesRefs\n    }\n\n    private def inspectTypeBoundsToFull(tpe: TypeRepr): List[(AbstractReference, AbstractReference)] = {\n      tpe._dealiasSimplifiedFull match {\n        case t: TypeBounds =>\n          processTypeBounds(t)\n        case t: TypeRepr =>\n          inspectTypeReprToFullBases(t, onlyIndirect = false)\n      }\n    }\n\n    private def processTypeBounds(tb: TypeBounds): List[(AbstractReference, AbstractReference)] = {\n      inspectTypeReprToFullBases(tb.hi, onlyIndirect = false) ++ inspectTypeReprToFullBases(tb.low, onlyIndirect = false)\n    }\n\n    private def processTypeMemberWithTypeLambdaBounds(t: TypeRef | ParamRef, onlyIndirect: Boolean): List[(AbstractReference, AbstractReference)] = {\n      t._underlying match {\n        // handle abstract higher-kinded type members specially,\n        // move their upper bound into inheritance db, because they\n        // will lose it after application. (Unlike proper type members)\n        case TypeBounds(_, tl0: TypeLambda) =>\n          val selfRef = inspector.inspectTypeRepr(t)\n          // include only upper bound: we discard the lower bound for abstract higher-kinded type members\n          val tl = tl0._dealiasSimplifiedFull\n          val hiTypeLambda = inspector.inspectTypeRepr(tl)\n\n          (selfRef, hiTypeLambda) :: replaceUpperBoundWithSelfInUpperBoundBases(selfRef, hiTypeLambda, tl, onlyIndirect = onlyIndirect)\n\n        case underlying @ TypeBounds(_, _) =>\n          val selfRef = inspector.inspectTypeRepr(t)\n          extractBase(underlying, selfRef, onlyIndirect = onlyIndirect)\n\n        // for opaque types\n        case underlying =>\n          inspectTypeReprToFullBases(underlying, onlyIndirect = onlyIndirect)\n      }\n    }\n\n    private def replaceUpperBoundWithSelfInUpperBoundBases(\n      selfRef: AbstractReference,\n      upperBound: AbstractReference,\n      upperBoundTpe: TypeRepr,\n      onlyIndirect: Boolean\n    ): List[(AbstractReference, AbstractReference)] = {\n      val basesOfUpperBound = inspectTypeReprToFullBases(upperBoundTpe, onlyIndirect = onlyIndirect)\n      basesOfUpperBound.map {\n        case (k, v) if k == upperBound =>\n          // bases of upper bound are also bases of the abstract type\n          selfRef -> v\n        case kv =>\n          kv\n      }\n    }\n\n    extension (set: mutable.HashSet[Symbol]) {\n\n      private def addTerminatingClsSym(typeRepr: TypeRepr): Unit = {\n        typeRepr.classSymbol match {\n          case Some(clsSym) => set.add(clsSym)\n          case _ =>\n        }\n      }\n\n      private def isTerminatingClsSym(t: TypeRepr): Boolean = {\n        t.classSymbol match {\n          case Some(clsSym) => set.contains(clsSym)\n          case None => false\n        }\n      }\n\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/InheritanceDbInspector.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport izumi.reflect.internal.fundamentals.collections.IzCollections.toRich\nimport izumi.reflect.macrortti.LightTypeTagRef\nimport izumi.reflect.macrortti.LightTypeTagRef.*\n\nimport scala.collection.immutable.Queue\nimport scala.collection.mutable\nimport scala.quoted.*\n\nobject InheritanceDbInspector {\n  def make(q: Quotes): InheritanceDbInspector { val qctx: q.type } = new InheritanceDbInspector(0) {\n    override val qctx: q.type = q\n  }\n}\n\nabstract class InheritanceDbInspector(protected val shift: Int) extends InspectorBase {\n  import qctx.reflect.*\n\n  def makeUnappliedInheritanceDb(typeRepr: TypeRepr): Map[NameReference, Set[NameReference]] = {\n    val tpe0 = typeRepr._dealiasSimplifiedFull\n\n    new Run(Inspector.make(qctx), mutable.HashSet.empty)\n      .makeUnappliedInheritanceDb(tpe0)\n  }\n\n  class Run(\n    inspector: Inspector { val qctx: InheritanceDbInspector.this.qctx.type },\n    termination: mutable.HashSet[Symbol]\n  ) {\n\n    def makeUnappliedInheritanceDb(tpe0: TypeRepr): Map[NameReference, Set[NameReference]] = {\n      inspectTypeReprToUnappliedBases(tpe0, onlyIndirect = false)\n        .iterator\n        .filterNot {\n          case (parent, t) =>\n            parent == t\n        }\n        .toMultimap\n    }\n\n    private def inspectTypeReprToUnappliedBases(tpe0: TypeRepr, onlyIndirect: Boolean): List[(NameReference, NameReference)] = {\n      val allReferenceComponents = allTypeReferences(tpe0, onlyIndirect)\n      allReferenceComponents.iterator.flatMap(inspectTypeReprToUnappliedIndirectBases).toList\n    }\n\n    private def inspectTypeReprToUnappliedIndirectBases(i: TypeRepr): List[(NameReference, NameReference)] = {\n      val tpe = i._dealiasSimplifiedFull._resultType\n      val tpeRef = inspector.makeNameReferenceFromType(tpe)\n\n      tpeBases(tpeRef, tpe, onlyIndirect = false)\n    }\n\n    private def allTypeReferences(tpe0: TypeRepr, onlyIndirect: Boolean): mutable.Set[TypeRepr] = {\n      extension (t: TypeRepr) {\n        inline def dealiasPrepare: TypeRepr = {\n          t._dealiasSimplifiedFull._resultType\n        }\n      }\n\n      val inh = mutable.LinkedHashSet.empty[TypeRepr]\n\n      val tpeDealiased = tpe0.dealiasPrepare\n\n      def goExtractComponents(tpeRaw0: TypeRepr): Unit = {\n        val tpeRes = tpeRaw0.dealiasPrepare\n        val intersectionUnionMembers = breakRefinement(tpeRes)\n\n        if (intersectionUnionMembers.sizeIs == 1) {\n          inh += intersectionUnionMembers.head\n        }\n\n        (\n          tpeRes.typeArgs.iterator ++\n          intersectionUnionMembers.iterator.flatMap(_.typeArgs) ++\n          intersectionUnionMembers\n        ).foreach(t => if (!inh.contains(t)) goExtractComponents(t))\n      }\n\n      goExtractComponents(tpe0)\n\n      inh.filterInPlace {\n        case _: ParamRef => false // do not process type parameters for inheritance db\n        case t if onlyIndirect => t != tpe0 && t != tpeDealiased && !isTerminatingClsSym(t)\n        case _ => true\n      }\n\n      inh\n    }\n\n    private def breakRefinement(tpe0: TypeRepr): collection.Set[TypeRepr] = {\n      val tpes = mutable.LinkedHashSet.empty[TypeRepr]\n\n      def go(t0: TypeRepr): Unit = t0._dealiasSimplifiedFull match {\n        case tpe: AndOrType =>\n          go(tpe.left)\n          go(tpe.right)\n        case r: Refinement =>\n          refinementInfoToParts(r.info).foreach(go)\n          go(r.parent)\n        case t =>\n          tpes += t\n      }\n\n      go(tpe0)\n      tpes\n    }\n\n    private def tpeBases(tpeRef: NameReference, typeRepr: TypeRepr, onlyIndirect: Boolean): List[(NameReference, NameReference)] = {\n      addTerminatingClsSym(typeRepr)\n\n      val typeReprBases = typeRepr\n        .baseClasses\n        .map(typeRepr.baseType)\n\n      val upperBoundBases = typeRepr match {\n        case t: TypeRef =>\n          t._underlying match {\n            // handle abstract higher-kinded type members specially,\n            // move their upper bound into inheritance db, because they\n            // will lose it after application. (Unlike proper type members)\n            case TypeBounds(_, tl: TypeLambda) =>\n              List(tl.resType._dealiasSimplifiedFull)\n            case _ =>\n              Nil\n          }\n        case _ =>\n          Nil\n      }\n\n      val allTypeReprBases = (upperBoundBases ::: typeReprBases)\n        .filterNot(_ =:= typeRepr)\n\n      val recursiveParentRefs = allTypeReprBases.flatMap {\n        case t if isTerminatingClsSym(t) => Nil\n        case t => inspectTypeReprToUnappliedBases(t, onlyIndirect = true)\n      }\n\n      val directBaseRefs = if (onlyIndirect) {\n        Nil\n      } else {\n        allTypeReprBases.filter(!_._takesTypeArgs).map(base => (tpeRef, inspector.makeNameReferenceFromType(base)))\n      }\n\n      recursiveParentRefs ::: directBaseRefs\n    }\n\n    private def addTerminatingClsSym(typeRepr: TypeRepr): Unit = {\n      typeRepr.classSymbol match {\n        case Some(clsSym) => termination.add(clsSym)\n        case _ =>\n      }\n    }\n\n    private def isTerminatingClsSym(t: TypeRepr): Boolean = {\n      t.classSymbol match {\n        case Some(clsSym) => termination.contains(clsSym)\n        case None => false\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/Inspect.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport izumi.reflect.macrortti.LightTypeTag\nimport izumi.reflect.macrortti.LightTypeTag.ParsedLightTypeTag.SubtypeDBs\nimport izumi.reflect.thirdparty.internal.boopickle.PickleImpl\n\nimport scala.quoted.{Expr, Quotes, Type}\n\nobject Inspect {\n  inline def inspect[T <: AnyKind]: LightTypeTag = ${ inspectAny[T] }\n\n  inline def inspectStrong[T <: AnyKind]: LightTypeTag = ${ inspectStrong[T] }\n\n  def inspectAny[T <: AnyKind: Type](using qctx: Quotes): Expr[LightTypeTag] = {\n    inspectTypeRepr(qctx.reflect.TypeRepr.of[T])\n  }\n\n  def inspectTypeRepr(using qctx: Quotes)(typeRepr: qctx.reflect.TypeRepr): Expr[LightTypeTag] = {\n    val ltt = {\n      val ref = TypeInspections(typeRepr)\n      val fullDb = TypeInspections.fullDb(typeRepr)\n      val nameDb = TypeInspections.unappliedDb(typeRepr)\n      LightTypeTag(ref, fullDb, nameDb)\n    }\n    makeParsedLightTypeTagImpl(ltt)\n  }\n\n  def inspectStrong[T <: AnyKind: Type](using qctx: Quotes): Expr[LightTypeTag] = {\n    import qctx.reflect.*\n    val tpe = TypeRepr.of[T]\n    val owners = ReflectionUtil.getClassDefOwners(Symbol.spliceOwner)\n    if (ReflectionUtil.allPartsStrong(0, owners, Set.empty, tpe)) {\n      inspectAny[T]\n    } else {\n      report.errorAndAbort(s\"Can't materialize LTag[$tpe]: found unresolved type parameters in $tpe\")\n    }\n  }\n\n  def makeParsedLightTypeTagImpl(ltt: LightTypeTag)(using qctx: Quotes): Expr[LightTypeTag] = {\n    val serialized = ltt.serialize()\n    val hashCodeRef = serialized.hash\n    val strRef = serialized.ref\n    val strDBs = serialized.databases\n\n    InspectorBase.ifDebug {\n      def string2hex(str: String): String = str.toList.map(_.toInt.toHexString).mkString\n\n      println(s\"${ltt.ref} => ${strRef.size} bytes, ${string2hex(strRef)}\")\n      println(s\"${SubtypeDBs.make(ltt.basesdb, ltt.idb)} => ${strDBs.size} bytes, ${string2hex(strDBs)}\")\n      println(strDBs)\n    }\n\n    '{ LightTypeTag.parse(${ Expr(hashCodeRef) }, ${ Expr(strRef) }, ${ Expr(strDBs) }, ${ Expr(LightTypeTag.currentBinaryFormatVersion) }) }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/Inspector.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport izumi.reflect.macrortti.{LightTypeTagInheritance, LightTypeTagRef}\nimport izumi.reflect.macrortti.LightTypeTagRef.*\nimport izumi.reflect.macrortti.LightTypeTagRef.SymName.SymTypeName\n\nimport scala.annotation.{tailrec, targetName}\nimport scala.collection.immutable.Queue\nimport scala.quoted.{Quotes, Type}\nimport scala.reflect.Selectable.reflectiveSelectable\n\nobject Inspector {\n  case class LamParam(name: String, index: Int, depth: Int, arity: Int)(val qctx: Quotes)(val tpe: qctx.reflect.TypeRepr) {\n    def asParam = SymName.LambdaParamName(index, depth, arity) // s\"$depth:$index/$arity\")\n    // this might be useful for debugging\n    // def asParam = LambdaParameter(s\"$depth:$index/$arity:$name\")\n\n    override def toString: String = s\"[($name: $tpe) = $asParam]\"\n  }\n  case class LamContext(params: List[LamParam])\n\n  def make(q: Quotes): Inspector { val qctx: q.type } = new Inspector(0, Queue.empty) {\n    override val qctx: q.type = q\n  }\n}\n\nabstract class Inspector(protected val shift: Int, val context: Queue[Inspector.LamContext]) extends InspectorBase {\n  import qctx.reflect._\n\n  def next(newContext: Option[Inspector.LamContext] = None): Inspector { val qctx: Inspector.this.qctx.type } =\n    new Inspector(shift + 1, newContext.fold(this.context)(this.context :+ _)) {\n      val qctx: Inspector.this.qctx.type = Inspector.this.qctx\n    }\n\n  def nextLam(lambda: TypeLambda): Inspector { val qctx: Inspector.this.qctx.type } = {\n    val params = lambda\n      .paramNames\n      .zipWithIndex\n      .map {\n        case (nme, idx) =>\n          Inspector.LamParam(nme, idx, context.size, lambda.paramNames.size)(qctx)(lambda.param(idx))\n      }\n      .toList\n    next(Some(Inspector.LamContext(params)))\n  }\n\n  def buildTypeRef(typeRepr: TypeRepr): AbstractReference = {\n    log(s\" -------- about to inspect ${typeRepr.show(using Printer.TypeReprStructure)} ($typeRepr) --------\")\n    val res = inspectTypeRepr(typeRepr)\n    log(s\" -------- done inspecting ${typeRepr.show(using Printer.TypeReprStructure)} ($typeRepr) --------\")\n    res\n  }\n\n  private[dottyreflection] def inspectTypeRepr(tpe0: TypeRepr, outerTypeRef: Option[TypeRef] = None): AbstractReference = {\n    val tpe = tpe0._dealiasSimplifiedFull\n\n    if (context.flatMap(_.params.map(_.tpe)).toSet.contains(tpe0)) {\n      assert(tpe == tpe0)\n      assert(tpe match {\n        case _: ParamRef =>\n          true\n        case _ =>\n          false\n      })\n    }\n\n//    log(s\"inspectTypeRepr tpe=$tpe outerTypeRef=$outerTypeRef\")\n\n    tpe match {\n      case a: AnnotatedType =>\n        inspectTypeRepr(a.underlying)\n\n      case appliedType: AppliedType =>\n        val tycon: TypeRepr = appliedType.tycon._dealiasSimplifiedFull\n        val args0: List[TypeRepr] = appliedType.args\n        args0 match {\n          case Nil =>\n            makeNameReferenceFromType(tycon)\n          case _ =>\n            val symbolVariances: List[Variance] = tycon.typeSymbol.declaredTypes.collect {\n              case s if s.isTypeParam => extractVariance(s)\n            }\n            val variances: List[Variance] = if (symbolVariances.sizeCompare(appliedType.args) < 0) {\n              tycon match {\n                case typeParamRef: ParamRef =>\n                  typeParamRef._underlying match {\n                    case TypeBounds(_, hi) =>\n                      hi._paramVariancesIfHKTypeLambda.fold(Nil)(_.map(extractVariance))\n                    case _ =>\n                      Nil\n                  }\n                case _ =>\n                  Nil\n              }\n            } else {\n              symbolVariances\n            }\n            val nameRef = makeNameReferenceFromType(tycon)\n            val args = args0\n              .iterator\n              .zipAll(variances, null.asInstanceOf[TypeRepr], Variance.Invariant)\n              .takeWhile(_._1 != null)\n              .map(next().inspectTypeParam(_, _)).toList\n            FullReference(symName = nameRef.symName, parameters = args, prefix = nameRef.prefix)\n        }\n\n      case l: TypeLambda =>\n        val inspector = nextLam(l)\n        val resType = inspector.inspectTypeRepr(l.resType)\n        val paramNames = inspector.context.last.params.map(_.asParam)\n        LightTypeTagRef.Lambda(paramNames, resType)\n\n      case t: ThisType =>\n        next().inspectTypeRepr(t.tref)\n\n      case a: AndType =>\n        val elements = flattenInspectAnd(a)\n        if (elements.sizeIs == 1) {\n          elements.head\n        } else {\n          IntersectionReference(elements)\n        }\n\n      case o: OrType =>\n        val elements = flattenInspectOr(o)\n        if (elements.sizeIs == 1) {\n          elements.head\n        } else {\n          UnionReference(elements)\n        }\n\n      case p: ParamRef =>\n        makeNameReferenceFromType(p)\n\n      case term: TermRef =>\n        makeNameReferenceFromType(term)\n\n      case r: TypeRef =>\n        next().inspectSymbol(r.typeSymbol, Some(r), Some(r))\n\n      case tb: TypeBounds =>\n        inspectBounds(outerTypeRef, tb)\n\n      case constant: ConstantType =>\n        makeNameReferenceFromType(constant)\n\n      case ref: Refinement =>\n        next().inspectRefinements(ref)\n\n      case lazyref if lazyref.getClass.getName.contains(\"LazyRef\") => // upstream bug seems like\n        log(s\"TYPEREPR UNSUPPORTED: LazyRef occured $lazyref\")\n        NameReference(SymName.SymTypeName(\"???\"))\n\n      case o =>\n        log(s\"TYPEREPR UNSUPPORTED: $o\")\n        throw new RuntimeException(s\"TYPEREPR, UNSUPPORTED: ${o.getClass} - $o\")\n\n    }\n  }\n\n  private def inspectRefinements(ref: Refinement): AbstractReference = {\n    val (refinements, nonRefinementParent) = flattenRefinements(ref)\n\n    val parentRef = next().inspectTypeRepr(nonRefinementParent)\n\n    val refinementDecls = refinements.map {\n      case (_, name, ByNameType(tpe)) => // def x(): Int\n        RefinementDecl.Signature(name, Nil, next().inspectTypeRepr(tpe).asInstanceOf[AppliedReference])\n\n      case (_, name, m0: MethodOrPoly) => // def x(i: Int): Int; def x[A](a: A): A\n        // FIXME as of version 2.3.0 RefinementDecl.Signature model is broken\n        //   it doesn't support either multiple parameter lists or type parameters\n        //   on methods, so this is a hacky to avoid fixing that for now.\n        def squashMethodIgnorePolyType(m: TypeRepr): (List[TypeRepr], TypeRepr) = {\n          m match {\n            case p: PolyType =>\n              squashMethodIgnorePolyType(p.resType)\n            case m: MethodType =>\n              val inputs = m.paramTypes\n              val (inputs2, res) = squashMethodIgnorePolyType(m.resType)\n              (inputs ++ inputs2, res)\n            case tpe =>\n              (Nil, tpe)\n          }\n        }\n        val (inputTpes, resType) = squashMethodIgnorePolyType(m0)\n        val inputRefs = inputTpes.map(next().inspectTypeRepr(_).asInstanceOf[AppliedReference])\n        val outputRef = next().inspectTypeRepr(resType).asInstanceOf[AppliedReference]\n        RefinementDecl.Signature(name, inputRefs, outputRef)\n\n      case (_, name, bounds: TypeBounds) => // type T = Int\n        val boundaries = next().inspectBoundsImpl(bounds)\n        val res = boundaries match {\n          case Boundaries.Defined(low, high) if high == low =>\n            // concrete type member: type T = Int (can't distinguish between equal-bounded type and alias inside refinements in dotty)\n            high\n          case definedBoundaries =>\n            // abstract type member: type T >: Int <: AnyVal\n            NameReference(SymName.SymTypeName(name), definedBoundaries, None)\n        }\n        RefinementDecl.TypeMember(name, res)\n\n      case (_, name, tpe) => // val t: Int\n        RefinementDecl.Signature(name, Nil, next().inspectTypeRepr(tpe).asInstanceOf[AppliedReference])\n    }\n\n    val ohOh = parentRef.asInstanceOf[AppliedReference]\n\n    LightTypeTagRef.Refinement(ohOh, refinementDecls.toSet)\n  }\n\n  private def inspectBounds(outerTypeRef: Option[TypeRef], tb: TypeBounds): AbstractReference = {\n    log(s\"inspectBounds: found TypeBounds $tb outer=$outerTypeRef\")\n    val boundaries = inspectBoundsImpl(tb)\n    if (outerTypeRef.isEmpty) {\n      // Boundaries in parameters always stand for wildcards even though Scala3 eliminates wildcards\n      WildcardReference(boundaries)\n    } else {\n      // Type projections like A#S2 don't get dealiased with .dealias for some reason, so we dereference them manually here\n      val outerTpe = outerTypeRef.get\n      boundaries match {\n        case Boundaries.Defined(bottom, top) if outerTpe.typeSymbol.isAliasType && top == bottom =>\n          // type projection, return underlying\n          top\n        case _ =>\n          // abstract type, return TpeName|LowerBound..UpperBound\n          // Boundaries which are not parameters are named types (e.g. type members) and are NOT wildcards\n          // if hi and low boundaries are defined <strike>and distinct</strike>, type is not reducible to one of them\n          val nameRef = makeNameReferenceFromType(outerTypeRef.get).copy(boundaries = boundaries)\n          invertTypeMemberWithTypeLambdaBounds(nameRef)\n      }\n    }\n  }\n\n  private def invertTypeMemberWithTypeLambdaBounds(abstractReference: AbstractReference): AbstractReference = abstractReference match {\n    case NameReference(symName, Boundaries.Defined(bottom @ _, LightTypeTagRef.Lambda(input, realTop @ _)), prefix) =>\n      // We throw away both upper and lower boundaries\n      // Upper boundaries we'll recover later in fulldb and inheritancedb\n      // But lower boundaries we don't recover\n      log(s\"invertTypeMemberWithTypeLambdaBounds: found symName=$symName, input=$input\")\n      LightTypeTagRef.Lambda(input, FullReference(symName, input.map(p => TypeParam(NameReference(p), Variance.Invariant)), prefix))\n    case other =>\n      other\n  }\n\n  private def inspectBoundsImpl(tb: TypeBounds): Boundaries = {\n    val hi = next().inspectTypeRepr(tb.hi)\n    val low = next().inspectTypeRepr(tb.low)\n    if (hi == LightTypeTagInheritance.tpeAny && low == LightTypeTagInheritance.tpeNothing) {\n      Boundaries.Empty\n    } else {\n      Boundaries.Defined(low, hi)\n    }\n  }\n\n  private[dottyreflection] def inspectSymbol(symbol: Symbol, outerTypeRef: Option[TypeRef], prefixSource: Option[NamedType]): AbstractReference = {\n    symbol match {\n      case s if s.isClassDef || s.isValDef || s.isBind =>\n        log(s\"inspectSymbol: Found Cls=${s.isClassDef} Val=${s.isValDef} Bind=${s.isBind} symbol $s\")\n        makeNameReferenceFromSymbol(symbol, prefixSource)\n\n      case s if s.isTypeDef =>\n        val rhs = outerTypeRef match {\n          case Some(r) if r.isOpaqueAlias => r._underlying\n          case _ => s.typeRef._underlying\n        }\n        log(s\"inspectSymbol: Found TypeDef symbol $s (rhs=$rhs)\")\n        next().inspectTypeRepr(rhs, outerTypeRef)\n\n      case s if s.isDefDef =>\n        // We don't support method types, but if we do in the future,\n        // Something like `s.typeRef.translucentSuperType match { case MethodType(_, params, resultType) => (params, resultType) }`\n        // should get the result type & params\n        log(s\"UNEXPECTED METHOD TYPE, METHOD TYPES UNSUPPORTED: $symbol / ${symbol.tree} / ${s.getClass}\")\n        throw new RuntimeException(s\"UNEXPECTED METHOD TYPE, METHOD TYPES UNSUPPORTED: $symbol / ${symbol.tree} / ${s.getClass}\")\n\n      case o => // Should not happen according to documentation of `.tree` method\n        // still no access to relevant types\n        log(s\"SYMBOL TREE, UNSUPPORTED: $symbol / $o / ${o.getClass}\")\n        throw new RuntimeException(s\"SYMBOL TREE, UNSUPPORTED: $symbol / $o / ${o.getClass}\")\n    }\n  }\n\n  private def inspectTypeParam(tpe: TypeRepr, variance: Variance): TypeParam = {\n    tpe match {\n      case t: TypeBounds => // wildcard\n        TypeParam(inspectBounds(outerTypeRef = None, tb = t), variance)\n      case t: TypeRepr =>\n        TypeParam(inspectTypeRepr(t), variance)\n    }\n  }\n\n  private def extractVariance(t: Symbol): Variance = {\n    extractVariance(t.flags)\n  }\n\n  @targetName(\"extractVarianceFlags\")\n  private def extractVariance(flags: Flags): Variance = {\n    if (flags.is(Flags.Covariant)) {\n      Variance.Covariant\n    } else if (flags.is(Flags.Contravariant)) {\n      Variance.Contravariant\n    } else {\n      Variance.Invariant\n    }\n  }\n\n  private def flattenInspectAnd(and: AndType): Set[AppliedReferenceExceptIntersection] = {\n    flattenAnd(and).toSet.map(inspectTypeRepr(_)).flatMap {\n      case i: IntersectionReference => i.refs\n      case other: AppliedReferenceExceptIntersection => Set(other)\n      case _: LightTypeTagRef.Lambda => Set.empty\n    }\n  }\n\n  private def flattenInspectOr(or: OrType): Set[AppliedReferenceExceptUnion] =\n    flattenOr(or).toSet.map(inspectTypeRepr(_)).flatMap {\n      case i: UnionReference => i.refs\n      case other: AppliedReferenceExceptUnion => Set(other)\n      case _: LightTypeTagRef.Lambda => Set.empty\n    }\n\n  private[dottyreflection] def makeNameReferenceFromType(t: TypeRepr): NameReference = {\n    t match {\n      case ref: TypeRef =>\n        log(s\"make name reference from type $ref termSymbol=${ref.termSymbol}\")\n        makeNameReferenceFromSymbol(ref.typeSymbol, Some(ref))\n      case term: TermRef =>\n        log(s\"make name reference from term $term\")\n        makeNameReferenceFromSymbol(term.termSymbol, Some(term))\n      case t: ParamRef =>\n        log(s\"make name reference from paramRef $t\")\n        val isInContext = context.flatMap(_.params.map(_.tpe)).contains(t)\n        if (isInContext) {\n          // assert(isInContext, s\"${context.flatMap(_.params.map(_.tpe)).map(t => t)} must contain $t\")\n\n          val candidates = context.reverse.flatMap(_.params).filter(_.tpe == t)\n          val contextParam = candidates.head\n\n          locally {\n            val paramName = t.binder.asInstanceOf[LambdaType].paramNames(t.paramNum).toString\n            assert(contextParam.name == paramName, s\"$contextParam should match $paramName\")\n          }\n\n          NameReference(contextParam.asParam, Boundaries.Empty, None)\n\n        } else {\n          val lt = t.binder.asInstanceOf[LambdaType]\n          NameReference(SymName.LambdaParamName(t.paramNum, -1, lt.paramNames.size), Boundaries.Empty, None)\n        }\n\n      case constant: ConstantType =>\n        log(s\"make name reference from ConstantType $constant\")\n        NameReference(SymName.SymLiteral(constant.constant.value), Boundaries.Empty, prefix = None)\n\n      case ref =>\n        log(s\"make name reference from what? $ref ${ref.getClass} ${ref.termSymbol}\")\n        makeNameReferenceFromSymbol(ref.typeSymbol, None)\n    }\n  }\n\n  @tailrec\n  private[dottyreflection] final def makeNameReferenceFromSymbol(symbol: Symbol, prefixSource1: Option[NamedType]): NameReference = {\n    def default: NameReference = {\n      val (symName, prefixSource2) = if (symbol.isTerm || symbol.isBind || symbol.isValDef) {\n        (SymName.SymTermName(symbol.fullName), symbol.termRef)\n      } else if (symbol.flags.is(Flags.Module)) { // Handle ModuleClasses (can creep in from ThisType)\n        (SymName.SymTermName(symbol.companionModule.fullName), symbol.companionModule.termRef)\n      } else {\n        (SymName.SymTypeName(symbol.fullName), symbol.termRef)\n      }\n      val prefix = getPrefixFromQualifier(prefixSource1.getOrElse(prefixSource2))\n      NameReference(symName, Boundaries.Empty, prefix)\n    }\n\n    if (symbol.isBind) { log(s\"inspectSymbol: Found Bind symbol $symbol\") }\n\n    if (symbol.isValDef) {\n      log(s\"inspectSymbol: Found ValDef symbol $symbol\")\n      symbol.typeRef._underlying match {\n        case constant: ConstantType => // constant type vals are aliases to constant types\n          makeNameReferenceFromType(constant)\n        case t: TermRef => // singleton type vals are aliases to their singleton\n          makeNameReferenceFromSymbol(t.termSymbol, Some(t))\n        case other =>\n          log(s\"inspectSymbol: found UNKNOWN symbol in ValDef $other\")\n          default\n      }\n    } else {\n      default\n    }\n  }\n\n  private def getPrefixFromQualifier(tpe: NamedType): Option[AppliedReference] = {\n    tpe.qualifier match {\n      // Support https://github.com/zio/izumi-reflect/issues/35\n      // consider class member's this-prefix to be the defining template, not the most specific prefix from where the call is happening\n      case _: ThisType | _: SuperType | _: RecursiveThis =>\n        val s = if (!tpe.termSymbol.isNoSymbol) {\n          tpe.termSymbol\n        } else {\n          tpe.typeSymbol\n        }\n\n        val maybeOwner = s.maybeOwner\n        if (!maybeOwner.exists || maybeOwner.isNoSymbol || maybeOwner.isPackageDef || maybeOwner.isDefDef || maybeOwner.isTypeDef || maybeOwner.isLocalDummy) {\n          None\n        } else {\n          inspectSymbol(maybeOwner, None, None) match {\n            case a: AppliedReference =>\n              log(s\"Constructed prefix=$a from owner=$maybeOwner\")\n              Some(a)\n            case _ =>\n              None\n          }\n        }\n\n      case prefix =>\n        val typeSymbol = prefix.typeSymbol\n        if (!typeSymbol.exists || typeSymbol.isNoSymbol || typeSymbol.isPackageDef || typeSymbol.isDefDef || typeSymbol.isTypeDef || typeSymbol.isLocalDummy) {\n          None\n        } else {\n          inspectTypeRepr(prefix) match {\n            case reference: AppliedReference =>\n              log(s\"Constructed prefix=$reference from prefix=$prefix\")\n              Some(reference)\n            case _ => None\n          }\n        }\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/InspectorBase.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport scala.quoted.Quotes\n\ntrait InspectorBase extends ReflectionUtil {\n\n  val qctx: Quotes\n  import qctx.reflect._\n\n  protected def shift: Int\n\n  // FIXME reimplement TrivialMacroLogger for Scala 3\n  inline def debug: debug = valueOf[debug]\n  final type debug = false\n\n  // println instead of report.info because report.info eats all the subsequent report.info's after first.\n  inline final protected def logStart(inline s: String): Unit = {\n    inline if (debug) println(\" \" * shift + currentPositionStr + s)\n  }\n\n  inline final protected def log(inline s: String): Unit = {\n    inline if (debug) println(\" \" * shift + currentPositionStr + \" -> \" + s)\n  }\n\n  inline final protected def logTpeAttrs[T](inline typeRepr: TypeRepr): Unit = {\n    inline if (debug) {\n      val tree = TypeTree.of(using typeRepr.asType)\n      val symbol = tree.symbol\n      System\n        .err.println(\n          currentPositionStr + \": \" +\n          s\"Attrs[${tree.show}]: type=${symbol.isType}, term=${symbol.isTerm}, packageDef=${symbol.isPackageDef}, classDef=${symbol.isClassDef}, typeDef=${symbol.isValDef}, defdef=${symbol.isDefDef}, bind=${symbol.isBind}, nosymbol=${symbol.isNoSymbol}\"\n        )\n    }\n  }\n\n  private def currentPositionStr: String = {\n    val pos = qctx.reflect.Position.ofMacroExpansion\n    s\"${pos.sourceFile.name}:${pos.endLine}\"\n  }\n\n}\n\nobject InspectorBase {\n\n  private[reflect] inline def ifDebug[A](inline f: => Unit): Unit = {\n    inline if (valueOf[InspectorBase#debug]) {\n      f\n    }\n  }\n\n  private[reflect] inline def log(inline shift: Int, s: String): Unit = {\n    inline if (valueOf[InspectorBase#debug]) println(\" \" * shift + \" -> \" + s)\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/ReflectionUtil.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport scala.annotation.{nowarn, tailrec, unused}\nimport scala.collection.immutable.Queue\nimport scala.quoted.Quotes\n\nprivate[dottyreflection] trait ReflectionUtil { this: InspectorBase =>\n\n  import qctx.reflect.*\n\n  private final lazy val ignoredInIntersections0: Set[TypeRepr] = {\n    Set(\n      defn.AnyClass.typeRef,\n      defn.MatchableClass.typeRef,\n      defn.AnyRefClass.typeRef,\n      defn.ObjectClass.typeRef\n    )\n  }\n  def ignoredInIntersections(repr: qctx.reflect.TypeRepr): Boolean = {\n    ignoredInIntersections0.exists(_ =:= repr)\n  }\n  def ignoredInUnions(repr: qctx.reflect.TypeRepr): Boolean = {\n    repr =:= defn.NothingClass.typeRef\n  }\n\n  protected final def flattenAnd(tpe: TypeRepr): List[TypeRepr] =\n    tpe.dealias match {\n      case AndType(lhs, rhs) => flattenAnd(lhs) ++ flattenAnd(rhs)\n      case _ => List(tpe)\n    }\n\n  protected final def flattenOr(tpe: TypeRepr): List[TypeRepr] =\n    tpe.dealias match {\n      case OrType(lhs, rhs) => flattenOr(lhs) ++ flattenOr(rhs)\n      case _ => List(tpe)\n    }\n\n  protected final def intersectionUnionRefinementClassPartsOf(tpe: TypeRepr): List[TypeRepr] = {\n    tpe.dealias match {\n      case AndType(lhs, rhs) =>\n        intersectionUnionRefinementClassPartsOf(lhs) ++ intersectionUnionRefinementClassPartsOf(rhs)\n      case OrType(lhs, rhs) =>\n        intersectionUnionRefinementClassPartsOf(lhs) ++ intersectionUnionRefinementClassPartsOf(rhs)\n      case refinement: Refinement =>\n        intersectionUnionRefinementClassPartsOf(refinement.parent)\n      case _ =>\n        List(tpe)\n    }\n  }\n\n  protected final def refinementInfoToParts(tpe0: TypeRepr): List[TypeRepr] = {\n    tpe0 match {\n      case ByNameType(tpe) =>\n        refinementInfoToParts(tpe)\n      case MethodType(_, args, res) =>\n        args.flatMap(refinementInfoToParts) ++ refinementInfoToParts(res)\n      case PolyType(_, tbounds, res) =>\n        // FIXME we need to do FullDbInspector.inspectTypeReprToFullBases.lambdify/LightTypeTagImpl.makeLambdaOnlyBases.makeLambdaParents\n        //   to wrap the unresolved type params in `res` into a lambda.\n        //   As is, if type parameters are used in `res`, we'll add lots of trash types into db\n        tbounds.flatMap { case TypeBounds(lo, hi) => List(lo, hi) } ++ refinementInfoToParts(res)\n      case tpe =>\n        List(tpe)\n    }\n  }\n\n  protected final def flattenRefinements(ref: Refinement): (Queue[(Symbol, String, TypeRepr)], TypeRepr) = {\n    val refinementDecl = (ref.typeSymbol, ref.name, ref.info)\n    ref.parent match {\n      case innerRefinement: Refinement =>\n        val (innerRefs, nonRefinementParent) = flattenRefinements(innerRefinement)\n        (innerRefs :+ refinementDecl, nonRefinementParent)\n      case nonRefinementParent =>\n        (Queue(refinementDecl), nonRefinementParent)\n    }\n  }\n\n  protected final def allPartsStrong(outerOwnerClassDefs: Set[Symbol], typeRepr: TypeRepr): Boolean = {\n    ReflectionUtil.allPartsStrong(using qctx)(shift, outerOwnerClassDefs, Set.empty, typeRepr)\n  }\n\n  protected final def getClassDefOwners(symbol: Symbol): Set[Symbol] = {\n    ReflectionUtil.getClassDefOwners(using qctx)(symbol)\n  }\n\n  import ReflectionUtil.reflectiveUncheckedNonOverloadedSelectable\n  import InternalContext.InternalContext\n\n  extension (symbol: Symbol) {\n    protected final def _info: TypeRepr = {\n      symbol.asInstanceOf[InternalSymbol].denot(qctx._ctx).info(qctx._ctx)\n    }\n  }\n\n  extension (typeRef: TypeRef | ParamRef) {\n    protected final def _underlying: TypeRepr = {\n      // This works as a substitution for `TypeRef#underlying` call,\n      // but I'm not sure if it's a reliable substitution.\n\n//      typeRef.typeSymbol.owner._typeRef.memberType(typeRef.typeSymbol)\n\n      // No, It's not a reliable substitution. When used on a TypeParamRef it returns Any instead of the underlying TypeBounds\n      // https://github.com/lampepfl/dotty/issues/15799\n\n//      val underlying = typeRef\n//        .getClass.getMethods.collect { case m if m.getName == \"underlying\" => m }.head.invoke(\n//          typeRef,\n//          qctx.getClass.getMethods.collect { case m if m.getName == \"ctx\" => m }.head.invoke(qctx)\n//        )\n//      underlying.asInstanceOf[TypeRepr]\n\n      typeRef.asInstanceOf[InternalTypeRefOrParamRef].underlying(qctx._ctx)\n    }\n  }\n\n  extension (appliedType: AppliedType) {\n    protected final def _etaExpand: Option[TypeLambda] = {\n      etaExpandImpl(appliedType.tycon._dealiasSimplifiedFull, tparams0 => tparams0.sizeCompare(appliedType.args) < 0)\n    }\n  }\n\n  @nowarn(\"msg=anonymous class definition will be duplicated\")\n  inline private final def etaExpandImpl(tycon: TypeRepr, inline checkIfPartialApplication: List[TypeRepr] => Boolean): Option[TypeLambda] = {\n    val tparams0: List[TypeRepr] = tycon.typeSymbol.declaredTypes.collect { case s if s.isTypeParam => s._info }\n    val tparams: List[TypeRepr] = if (checkIfPartialApplication(tparams0)) {\n      tycon match {\n        case typeParamRef: ParamRef =>\n          typeParamRef._underlying match {\n            case TypeBounds(_, hi: LambdaType) =>\n              hi.paramTypes\n            case _ =>\n              Nil\n          }\n        case _ =>\n          Nil\n      }\n    } else {\n      tparams0\n    }\n\n    if (tparams.nonEmpty) {\n      val indices = tparams.indices\n      Some(\n        TypeLambda(\n          paramNames = indices.iterator.map(_.toString).toList,\n          boundsFn = _ => tparams.map { case tb: TypeBounds => tb; case t => TypeBounds(t, t) },\n          bodyFn = tl => AppliedType(tycon, indices.iterator.map(tl.param(_)).toList)\n        )\n      )\n    } else None\n  }\n\n  extension (typeRepr: TypeRepr) {\n\n    protected final def _resultType: TypeRepr = {\n      typeRepr match {\n        case l: LambdaType => l.resType\n        case _ => typeRepr\n      }\n    }\n\n    protected final def _takesTypeArgs: Boolean = {\n      typeRepr match {\n        case _: LambdaType => true\n        case tref: TypeRef =>\n          val tsym = tref.typeSymbol\n          tsym.isType && tsym.declaredTypes.exists(_.isTypeParam)\n        case _ => false\n      }\n    }\n\n    protected final def _paramVariancesIfHKTypeLambda: Option[List[Flags]] = {\n      try {\n        val params = typeRepr.asInstanceOf[InternalHKTypeLambda].typeParams\n        val flags = params.map(_.paramVariance(qctx._ctx))\n        Some(flags)\n      } catch {\n        case _: NoSuchMethodException => None\n      }\n    }\n\n    protected final def _etaExpandTypeRef: TypeRepr = {\n      typeRepr match {\n        case tref: TypeRef =>\n          etaExpandImpl(tref, _ => false) match {\n            case Some(typeLambda) => typeLambda\n            case None => typeRepr\n          }\n        case _ => typeRepr\n      }\n    }\n\n    @tailrec\n    protected final def _dealiasSimplifiedFull: TypeRepr = {\n//      val res = typeRepr.dealias.simplified\n      // simplified does everything below functions do, with exception of `_removeTautologicalUnions` for some reason\n      // All of these would be more useful, if not for forced type simplification on implicit macro\n      // - https://github.com/lampepfl/dotty/issues/17544\n      val res = typeRepr.dealias._removeTautologicalIntersections._removeTautologicalUnions._simplifyMatchCase\n      if (res.asInstanceOf[AnyRef] eq typeRepr.asInstanceOf[AnyRef]) {\n        res\n      } else {\n        res._dealiasSimplifiedFull\n      }\n    }\n\n    // Calling .simplified will remove too many intersections - we only want to remove those with Any/AnyRef/Object/Matchable\n    @tailrec private def _removeTautologicalIntersections: TypeRepr = {\n      typeRepr match {\n        case AndType(a, b) =>\n          if (ignoredInIntersections(a)) {\n            b._removeTautologicalIntersections\n          } else if (ignoredInIntersections(b)) {\n            a._removeTautologicalIntersections\n          } else {\n            removeTautologicalIntersectionsNonTailRec(a, b)\n          }\n        case _ =>\n          typeRepr\n      }\n    }\n\n    private def removeTautologicalIntersectionsNonTailRec(a: TypeRepr, b: TypeRepr): TypeRepr = {\n      val a0 = a._removeTautologicalIntersections\n      val b0 = b._removeTautologicalIntersections\n      if ((a.asInstanceOf[AnyRef] ne a0.asInstanceOf[AnyRef]) || (b.asInstanceOf[AnyRef] ne b0.asInstanceOf[AnyRef])) {\n        AndType(a0, b0)\n      } else {\n        typeRepr\n      }\n    }\n\n    @tailrec private def _removeTautologicalUnions: TypeRepr = {\n      typeRepr match {\n        case OrType(a, b) =>\n          if (ignoredInUnions(a)) {\n            b._removeTautologicalUnions\n          } else if (ignoredInUnions(b)) {\n            a._removeTautologicalUnions\n          } else {\n            removeTautologicaUnionsNonTailRec(a, b)\n          }\n        case _ =>\n          typeRepr\n      }\n    }\n\n    private def removeTautologicaUnionsNonTailRec(a: TypeRepr, b: TypeRepr): TypeRepr = {\n      val superA = ignoredInIntersections(a)\n      val superB = ignoredInIntersections(b)\n      if (superA && superB) {\n        (if (a <:< b) b else a)._removeTautologicalUnions\n      } else if (superA) {\n        a\n      } else if (superB) {\n        b\n      } else {\n        val a0 = a._removeTautologicalUnions\n        val b0 = b._removeTautologicalUnions\n        if ((a.asInstanceOf[AnyRef] ne a0.asInstanceOf[AnyRef]) || (b.asInstanceOf[AnyRef] ne b0.asInstanceOf[AnyRef])) {\n          AndType(a0, b0)\n        } else {\n          typeRepr\n        }\n      }\n    }\n\n    inline private def _simplifyMatchCase: TypeRepr = {\n      typeRepr match {\n        case _: MatchCase | _: MatchType =>\n          // no other way to evaluate a match type other than calling simplified,\n          // even though that'll also cause a collapse of tautological intersections\n          // other than with Any/AnyRef/Object/Matchable\n          typeRepr.simplified\n        case _ =>\n          typeRepr\n      }\n    }\n\n  }\n\n  extension (qctx: Quotes) {\n    final def _ctx: InternalContext = qctx.asInstanceOf[{ def ctx: InternalContext }].ctx\n  }\n\n  type InternalTypeRefOrParamRef = {\n    def underlying(ctx: InternalContext): TypeRepr\n  }\n\n  type InternalHKTypeLambda = {\n    val typeParams: List[InternalLambdaParam]\n  }\n\n  type InternalLambdaParam = {\n    def paramVariance(ctx: InternalContext): Flags\n  }\n\n  type InternalSymbol = {\n    def denot(ctx: InternalContext): InternalDenot\n  }\n\n  type InternalDenot = {\n    def info(ctx: InternalContext): TypeRepr\n  }\n\n  object InternalContext {\n    opaque type InternalContext = Any\n  }\n\n}\n\nprivate[reflect] object ReflectionUtil {\n\n  private[reflect] inline implicit def reflectiveUncheckedNonOverloadedSelectable(x: Any): UncheckedNonOverloadedSelectable = new UncheckedNonOverloadedSelectable(x)\n\n  /**\n    * Returns true if the given type contains no type parameters\n    * (this means the type is not \"weak\" https://stackoverflow.com/questions/29435985/weaktypetag-v-typetag)\n    */\n  private[reflect] def allPartsStrong(\n    using qctx: Quotes\n  )(shift: Int,\n    outerOwnerClassDefs: Set[qctx.reflect.Symbol],\n    outerLambdas: Set[qctx.reflect.TypeRepr],\n    typeRepr: qctx.reflect.TypeRepr\n  ): Boolean = {\n    import qctx.reflect.*\n    typeRepr.dealias match {\n      case x if topLevelWeakType(outerOwnerClassDefs, outerLambdas, x) => false\n      case AppliedType(tpe, args) =>\n        allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, tpe) && args.forall(allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, _))\n      case AndType(lhs, rhs) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, lhs) && allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, rhs)\n      case OrType(lhs, rhs) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, lhs) && allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, rhs)\n      case TypeRef(tpe, _) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, tpe)\n      case TermRef(tpe, _) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, tpe)\n      case ThisType(tpe) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, tpe)\n      case NoPrefix() => true\n      case TypeBounds(lo, hi) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, lo) && allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, hi)\n      case lam @ TypeLambda(_, _, body) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas + lam, body)\n      case Refinement(parent, _, tpe) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, tpe) && allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, parent)\n      case ByNameType(tpe) => allPartsStrong(shift, outerOwnerClassDefs, outerLambdas, tpe)\n      case strange =>\n        InspectorBase.log(shift, s\"Got unknown type component when checking strength: $strange\")\n        true\n    }\n  }\n\n  private[reflect] def topLevelWeakType(\n    using qctx: Quotes\n  )(outerOwnerClassDefs: Set[qctx.reflect.Symbol],\n    outerLambdas: Set[qctx.reflect.TypeRepr],\n    typeRepr: qctx.reflect.TypeRepr\n  ): Boolean = {\n    import qctx.reflect.*\n    typeRepr match {\n      case x if x.typeSymbol.isTypeParam =>\n        x match {\n          case t: ParamRef if outerLambdas.contains(t.binder) => false\n          case _ => true\n        }\n      // we regard abstract types like T in trait X { type T; Tag[this.T] } - when we are _inside_ the definition template\n      // as 'type parameters' too. So that you could define `implicit def tagForT: Tag[this.T]` and the tag would be resolved\n      // to this implicit correctly, instead of generating a useless `X::this.type::T` tag.\n      // TODO: Due to https://github.com/lampepfl/dotty/issues/16107 not being fixed we have to make sure we're actually\n      //       inside the definition of the this-type prefix to count it as 'weak' - unlike Scala 2 we're not protected\n      //       from this-types leaking in and have to carry the owner chain here - until that issue is fixed.\n      case x @ TypeRef(ThisType(prefix), _) if x.typeSymbol.isAbstractType && !x.typeSymbol.isClassDef && outerOwnerClassDefs.contains(prefix.typeSymbol) =>\n        true\n      case _ => false\n    }\n  }\n\n  private[reflect] def getClassDefOwners(using qctx: Quotes)(symbol: qctx.reflect.Symbol): Set[qctx.reflect.Symbol] = {\n    Iterator\n      .iterate(symbol) {\n        s =>\n          val owner = s.owner\n          if (owner == null || owner.isNoSymbol || owner == qctx.reflect.defn.RootClass) {\n            null.asInstanceOf[qctx.reflect.Symbol]\n          } else {\n            owner\n          }\n      }\n      .takeWhile(_ ne null)\n      .filter(s => s.isClassDef && !s.isAbstractType)\n      .toSet\n  }\n\n  private[reflect] final class UncheckedNonOverloadedSelectable(private val selectable: Any) extends AnyVal with Selectable {\n\n    inline def selectDynamic(name: String): Any = {\n      applyDynamic(name)()\n    }\n\n    def applyDynamic(name: String, @unused paramTypes: Class[_]*)(args: Any*): Any = {\n      val cls = selectable.getClass\n      val method = {\n        if (args.isEmpty) {\n          cls.getMethod(name)\n        } else {\n          cls.getMethods.collectFirst { case m if m.getName == name => m } match {\n            case Some(m) => m\n            case None => throw new NoSuchMethodException(s\"No method named `$name` found in class `$cls`\")\n          }\n        }\n      }\n      method.invoke(selectable, args*)\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/dottyreflection/TypeInspections.scala",
    "content": "package izumi.reflect.dottyreflection\n\nimport izumi.reflect.macrortti.LightTypeTagRef.{AbstractReference, NameReference}\n\nimport scala.quoted.{Quotes, Type}\nimport scala.collection.immutable.Queue\n\nobject TypeInspections {\n  def apply(using qctx: Quotes)(typeRepr: qctx.reflect.TypeRepr): AbstractReference = {\n    Inspector.make(qctx).buildTypeRef(typeRepr)\n  }\n\n  def unappliedDb(using qctx: Quotes)(typeRepr: qctx.reflect.TypeRepr): Map[NameReference, Set[NameReference]] = {\n    InheritanceDbInspector.make(qctx).makeUnappliedInheritanceDb(typeRepr)\n  }\n\n  def fullDb(using qctx: Quotes)(typeRepr: qctx.reflect.TypeRepr): Map[AbstractReference, Set[AbstractReference]] = {\n    FullDbInspector.make(qctx).buildFullDb(typeRepr)\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/macrortti/LTag.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.macrortti\n\nfinal case class LTag[T <: AnyKind](tag: LightTypeTag)\n\n/**\n  * these are different summoners for light tags, it's fine for them to be the same structurally\n  */\nobject LTag {\n  def apply[T <: AnyKind: LTag]: LTag[T] = implicitly\n\n  inline implicit def materialize[T <: AnyKind]: LTag[T] = LTag(izumi.reflect.dottyreflection.Inspect.inspectStrong[T])\n\n  final case class Weak[T <: AnyKind](tag: LightTypeTag)\n  object Weak {\n    def apply[T <: AnyKind: LTag.Weak]: LTag.Weak[T] = implicitly\n\n    inline implicit def materialize[T <: AnyKind]: LTag.Weak[T] = LTag.Weak(izumi.reflect.dottyreflection.Inspect.inspect[T])\n  }\n\n  type StrongHK[T <: AnyKind] = LTag[T]\n  type WeakHK[T <: AnyKind] = LTag.Weak[T]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/main/scala-3/izumi/reflect/macrortti/package.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect\n\npackage object macrortti {\n  type LWeakTag[T <: AnyKind] = LTag.Weak[T]\n  object LWeakTag {\n    def apply[T: LWeakTag]: LWeakTag[T] = implicitly\n  }\n\n  type LTagK[K[_]] = LTag[K]\n  type LTagKK[K[_, _]] = LTag[K]\n  type LTagK3[K[_, _, _]] = LTag[K]\n\n  type LTagT[K[_[_]]] = LTag[K]\n  type LTagTK[K[_[_], _]] = LTag[K]\n  type LTagTKK[K[_[_], _, _]] = LTag[K]\n  type LTagTK3[K[_[_], _, _, _]] = LTag[K]\n\n  object LTagK {\n    /**\n      * Construct a type tag for a higher-kinded type `K[_]`\n      *\n      * Example:\n      * {{{\n      *     LTagK[Option]\n      * }}}\n      */\n    def apply[K[_]: LTagK]: LTagK[K] = implicitly\n  }\n\n  object LTagKK {\n    def apply[K[_, _]: LTagKK]: LTagKK[K] = implicitly\n  }\n\n  object LTagK3 {\n    def apply[K[_, _, _]: LTagK3]: LTagK3[K] = implicitly\n  }\n\n  object LTagT {\n    def apply[K[_[_]]: LTagT]: LTagT[K] = implicitly\n  }\n\n  object LTagTK {\n    def apply[K[_[_], _]: LTagTK]: LTagTK[K] = implicitly\n  }\n\n  object LTagTKK {\n    def apply[K[_[_], _, _]: LTagTKK]: LTagTKK[K] = implicitly\n  }\n\n  object LTagTK3 {\n    def apply[K[_[_], _, _, _]: LTagTK3]: LTagTK3[K] = implicitly\n  }\n\n//   simple materializers\n  inline def LTT[T]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_]`[T[_]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[+_]`[T[+_]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[A,B,_>:B<:A]`[A, B <: A, T[_ >: B <: A]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[A[_],_[_[x] <: A[x]]`[A[_], T[B[x] <: A[x]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[_]]`[T[_[_]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[+_]]`[T[_[+_]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[_[_]]]`[T[_[_[_]]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  // Note that this variation is not required on Scala 2.13.5, a mismatch between versions on variance handling currently\n  inline def `LTT[_[+_[_]]]`[T[_[+_[_]]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_,_]`[T[_, _]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[_,_]]`[T[_[_, _]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[+_,+_]]`[T[_[+_, +_]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[_,_],_,_]`[T[_[_, _], _, _]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[+_,+_],_,_]`[T[_[+_, +_], _, _]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[_],_[_]]`[T[_[_], _[_]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n  inline def `LTT[_[_[_],_[_]]]`[T[_[_[_], _[_]]]]: LightTypeTag = dottyreflection.Inspect.inspect[T]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/internal/fundamentals/collections/IzCollectionsTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.collections\n\nimport izumi.reflect.internal.fundamentals.collections.IzCollections._\nimport org.scalatest.wordspec.AnyWordSpec\n\nimport scala.collection.mutable\n\nclass IzCollectionsTest extends AnyWordSpec {\n  \"Collection utils\" should {\n    \"allow to convert mappings to multimaps\" in {\n      assert(List(\"a\" -> 1, \"a\" -> 2).toMultimap == Map(\"a\" -> Set(1, 2)))\n      assert(List(\"a\" -> 1, \"a\" -> 2).toMutableMultimap == mutable.Map(\"a\" -> mutable.Set(1, 2)))\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/internal/fundamentals/platform/IzStringTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.internal.fundamentals.platform\n\nimport izumi.reflect.internal.fundamentals.platform.strings.IzString._\nimport org.scalatest.wordspec.AnyWordSpec\n\nclass IzStringTest extends AnyWordSpec {\n\n  \"Extended string\" should {\n    \"support boolean parsing\" in {\n      assert(\"false\".asBoolean().contains(false))\n      assert(\"true\".asBoolean().contains(true))\n\n      assert(null.asInstanceOf[String].asBoolean().isEmpty)\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/CurrentDottySupportExtentTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti._\n\ntrait CurrentDottySupportExtentTest extends TagAssertions {\n\n  trait Y\n  trait Z extends Y\n  trait XS[+K]\n  trait X[+AAAAAAARG, -B0] extends XS[AAAAAAARG] {}\n\n  trait A\n  trait B extends A\n\n  trait Listoid[+K]\n\n  trait Traitoid\n  trait Invariantoid[V]\n  trait SubInvariantoid[V] extends Invariantoid[V] with Traitoid\n\n  \"super-basic test 1\" in { test() }\n\n  // FIXME workaround for 'Cyclic reference involving class Bar'\n  def test() = {\n    val intTag = LTT[Int]\n\n    class Foo[+F[_]]()\n    class Bar[+F[+_, -_]]() extends Foo[F[Int, *]]\n    class Baz() extends X[String, Z]\n\n    val bazTag = LTT[Baz]\n    val bazTag2 = LTT[Baz]\n\n    val barXTag = LTT[Bar[X]]\n\n    assertSame(bazTag, bazTag2)\n    assertDifferent(bazTag, barXTag)\n    assertChild(bazTag, bazTag2)\n    assertNotChild(bazTag, barXTag)\n\n    assertChild(LTT[B], LTT[A])\n\n    val listTag = `LTT[_]`[Listoid]\n    val listIntTag = LTT[Listoid[Int]]\n\n    // see https://github.com/7mind/izumi/pull/1528\n    assertSame(bazTag.combine(), bazTag2)\n\n    assertChild(listTag.combine(intTag), listIntTag)\n\n    val listTag0 = `LTT[_]`[List]\n    val listIntTag0 = LTT[List[Int]]\n\n    assertChild(listTag0.combine(intTag), listIntTag0)\n\n    val invTag0 = `LTT[_]`[SubInvariantoid]\n    val _ = LTT[Invariantoid[Int]]\n    val combined = invTag0.combine(intTag)\n    assertChild(combined, LTT[Traitoid])\n\n    val tupleTag0 = LTT[(Any, Any)]\n    val tupleTag1 = LTT[(Baz, Baz)]\n    val tupleTag2 = LTT[(AnyVal, AnyVal)]\n    val tupleTag3 = LTT[(Double, Double)]\n    assertChild(tupleTag1, tupleTag0)\n    assertChild(tupleTag3, tupleTag2)\n\n    assertChild(LTT[List[B]], LTT[Seq[A]])\n    assertChild(`LTT[_]`[List].combine(LTT[B]), `LTT[_]`[Seq].combine(LTT[A]))\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/InheritedModel.scala",
    "content": "package izumi.reflect.test\n\ntrait InheritedModel {\n\n  class Dep\n\n  trait BIOService[F[_, _]]\n  type BIOServiceL[F[+_, +_], E, A] = BIOService[λ[(X, Y) => F[A, E]]]\n\n  type F2To3[F[_, _], R, E, A] = F[E, A]\n\n  type EitherR[-_, +L, +R] = Either[L, R]\n  type EitherRSwap[-_, +L, +R] = Either[R, L]\n\n  trait BlockingIO3[F[_, _, _]]\n  type BlockingIO[F[_, _]] = BlockingIO3[λ[(R, E, A) => F[E, A]]]\n\n  type IntersectionBlockingIO[F[_, _], G[_, _]] = BlockingIO3[λ[(R, E, A) => F[E, A] with G[A, E]]]\n\n  type RepeatedBlockingIO[F[_, _]] = BlockingIO3[λ[(R, E, A) => F[A, A]]]\n  type RepeatedNonLambdaBlockingIO[F[_, _]] = BlockingIO3[λ[(R, E, A) => F[Int, Int]]]\n  type RepeatedSymbolNonLambdaBlockingIO[F[_, _]] = BlockingIO3[λ[(R, E, A) => F[Either[Int, Int], Either[Int, String]]]]\n\n  trait BlockingIO3T[F[_, _[_], _]]\n  type BlockingIOT[F[_[_], _]] = BlockingIO3T[({ type l[R, E[_], A] = F[E, A] })#l]\n\n  type LambdaParamCtorBlockingIOT[A] = BlockingIO3T[({ type l[R, F[_], X] = F[A] })#l]\n\n  type Swap[A, B] = Either[B, A]\n  type SwapF2[F[_, _], A, B] = F[B, A]\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/LTTRenderablesTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti._\n\nclass LTTRenderablesTest extends TagAssertions {\n\n  object X {\n    object Y {\n      class C\n    }\n  }\n\n  \"LTT renderables\" should {\n    \"render simple lambdas using placeholders when using scalaStyledRepr\" in {\n      val list = `LTT[_]`[List].scalaStyledRepr\n      val either = `LTT[_,_]`[Either].scalaStyledRepr\n      val either2 = `LTT[_]`[Either[Int, *]].scalaStyledRepr\n      val either3 = `LTT[_]`[Either[*, Int]].scalaStyledRepr\n      val optionT = `LTT[_]`[OptionT[List, *]].scalaStyledRepr\n\n      assert(list == \"scala.collection.immutable.List[+_]\")\n      assert(either == \"scala.util.Either[+_,+_]\")\n      assert(either2 == \"scala.util.Either[+scala.Int,+_]\")\n      assert(either3 == \"scala.util.Either[+_,+scala.Int]\")\n      assert(optionT == \"izumi.reflect.test.OptionT[scala.collection.immutable.List[+_],_]\")\n    }\n\n    \"render complex lambdas using long form when using scalaStyledRepr\" in {\n      type Const[+A, +B] = B\n      type SwapEither[+A, +B] = Either[B, A]\n      type SwapOptionT[A, B[_]] = OptionT[B, A]\n      type UseInner[A] = OptionT[Either[A, *], A]\n      type UseInner2[A, B] = OptionT[Either[A, *], B]\n      type Reuse[A] = Either[A, A]\n\n      val identity = `LTT[_]`[ID.Identity].scalaStyledRepr\n      val const = `LTT[_,_]`[Const].scalaStyledRepr\n      val swapEither = `LTT[_,_]`[SwapEither].scalaStyledRepr\n      val swapOptionT = `LTT[_]`[SwapOptionT[*, ID.Identity]].scalaStyledRepr\n      val useInner = `LTT[_]`[UseInner].scalaStyledRepr\n      val useInner2 = `LTT[_,_]`[UseInner2].scalaStyledRepr\n      val reuse = `LTT[_]`[Reuse].scalaStyledRepr\n\n      assert(identity == \"[A] ➾ A\")\n      assert(const == \"[A,B] ➾ B\")\n      assert(swapEither == \"[A,B] ➾ scala.util.Either[+B,+A]\")\n      val expectedDepth = if (IsScala3) 1 else 2\n      assert(swapOptionT == s\"izumi.reflect.test.OptionT[[A$expectedDepth] ➾ A$expectedDepth,_]\")\n      assert(useInner == s\"[A] ➾ izumi.reflect.test.OptionT[[A$expectedDepth] ➾ scala.util.Either[+A,+A$expectedDepth],A]\")\n      assert(useInner2 == s\"[A,B] ➾ izumi.reflect.test.OptionT[[A$expectedDepth] ➾ scala.util.Either[+A,+A$expectedDepth],B]\")\n      assert(reuse == \"[A] ➾ scala.util.Either[+A,+A]\")\n    }\n\n    \"types in nested objects should be rendered with dot separator\" in {\n      assert(LTT[X.Y.C].scalaStyledRepr == \"izumi.reflect.test.LTTRenderablesTest.X.Y.C\")\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/SharedLightTypeTagProgressionTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti._\n\n/**\n  * The tests here are *progression* tests, that means they test that something *doesn't work*\n  *\n  * If a test here starts to fail that's a GOOD thing - that means a new feature is now supported.\n  * When that happens you can remove the `broken` condition inversions and move the test to\n  * the non-progression test suite.\n  *\n  * All tests must have `broken` clauses wrapping the expected GOOD conditions if a feature\n  * were to work. If a test is missing `broken` clause, it's a probably not a progression test\n  * anymore and should be moved.\n  */\nabstract class SharedLightTypeTagProgressionTest extends TagAssertions with TagProgressions {\n\n  \"[progression] lightweight type tags (all versions)\" should {\n\n    import TestModel._\n\n    \"progression test: can't support subtyping of type prefixes\" in {\n      val a = new C {}\n\n      broken {\n        assertChild(LTT[a.A], LTT[C#A])\n      }\n      assertDifferent(LTT[a.A], LTT[C#A])\n      assertNotChild(LTT[C#A], LTT[a.A])\n    }\n\n    \"progression test: can't support subtyping of concrete type projections\" in {\n      trait A {\n        trait T\n      }\n      trait B extends A\n\n      val tagA = LTT[A#T]\n      val tagB = LTT[B#T]\n\n      assertSame(LTT[A#T], LTT[A#T])\n      assertDifferent(LTT[B#T], LTT[A#T])\n      broken {\n        assertChild(tagB, tagA)\n      }\n    }\n\n    \"progression test: bounds-based subtype checks for lambdas do not work properly (LambdaParameter must contain bounds and NameReferences shouldn't for this to work)\" in {\n      // I consider this stuff practically useless\n      type X[A >: H4 <: H2] = Set[A]\n      type X1[A >: H3 <: H3] = Set[A]\n      type X2[A >: H5 <: H5] = Set[A]\n\n//      def compare[a >: c <: b, b <: d, c <: d, d, A[x >: a <: b] <: B[x], B[_ >: c <: d], x >: a <: b](s: A[x], t: B[_ >: c <: d]) = null\n\n      broken {\n////      compare[H5, H5, H4, H2, X2, X, H5](null: Set[H5], null) // error\n////      (null: Set[H5]): Set[_ >: H4 <: H2] // error\n        assertNotChild(`LTT[A,B,_>:B<:A]`[H5, H5, X2], `LTT[A,B,_>:B<:A]`[H2, H4, X])\n      }\n\n//      compare[H3, H3, H4, H2, X1, X, H3](null: Set[H3], null)\n//      (null: Set[H3]): Set[_ >: H4 <: H2]\n      assertChild(`LTT[A,B,_>:B<:A]`[H3, H3, X1], `LTT[A,B,_>:B<:A]`[H2, H4, X])\n    }\n\n    \"progression test: indirect structural checks do not work\" in {\n      assertDifferent(LTT[{ type A }], LTT[Object])\n      broken {\n        assertChildStrict(LTT[C], LTT[{ type A }])\n      }\n    }\n\n    \"progression test: combined intersection lambda tags still contain some junk bases (coming from the unsound same-arity assumption in LightTypeTag#combine)\" in {\n      val tCtor = `LTT[_,_]`[T3]\n      val combined = tCtor.combine(LTT[Int], LTT[Boolean])\n      val debugCombined = combined.debug(\"combined\")\n\n      val alias = LTT[T3[Int, Boolean]]\n      val direct = LTT[W1 with W4[Boolean] with W5[Int]]\n\n      broken {\n        assert(!debugCombined.contains(\"W4[=scala.Int]\"))\n      }\n      broken {\n        assert(!debugCombined.contains(\"W3[=scala.Int]\"))\n      }\n\n      broken {\n        assertDebugSame(combined, alias)\n      }\n      broken {\n        assertDebugSame(combined, direct)\n      }\n    }\n\n    \"progression test: combined lambda tags still contain some junk bases (coming from the unsound same-arity assumption in LightTypeTag#combine)\" in {\n      val curriedApplied = `LTT[_,_]`[Right].combine(LTT[Throwable]).combine(LTT[Unit])\n      val debug1 = curriedApplied.debug()\n\n      assertSame(curriedApplied, LTT[Right[Throwable, Unit]])\n\n      assert(debug1.contains(\": scala.util.Right[+java.lang.Throwable,+scala.Unit]\"))\n      assert(debug1.contains(\"- scala.util.Right[+java.lang.Throwable,+scala.Unit]\"))\n      assert(debug1.contains(\"* scala.Product\"))\n      assert(debug1.contains(\"- λ %1 → scala.util.Right[+java.lang.Throwable,+1]\"))\n      assert(debug1.contains(\"- λ %0,%1 → scala.util.Right[+0,+1]\"))\n      broken {\n        assert(!debug1.contains(\"λ %1 → scala.util.Right[+scala.Unit,+1]\"))\n      }\n    }\n\n    \"progression test: Dotty fails to `support methods with type parameters in structural refinements`\" in {\n      trait X { def x[A](a: A): A }\n\n      assertNotChildStrict(LTT[X { def x[A](a: A): Boolean }], LTT[X { def x[A](a: A): Int }])\n      assertChildStrict(LTT[X { def x[A](a: A): Boolean }], LTT[X { def x[A](a: A): AnyVal }])\n      broken {\n        assertChildStrict(LTT[X { def x[A](a: A): Boolean }], LTT[X { def x[A](a: A): A }])\n      }\n    }\n\n    \"fails to treat tautological refinements as equal to the underlying type\" in {\n      trait X { def x[A](a: A): A }\n\n      broken {\n        assertSameStrict(LTT[X], LTT[X { def x[A](a: A): A }])\n        assertSameStrict(LTT[Object], LTT[Object { def equals(obj: Object): Boolean }])\n      }\n    }\n\n    \"fails to support methods with multiple parameter lists in refinements\" in {\n      brokenOnScala2 {\n        assertNotChildStrict(LTT[{ def x(i: Int)(b: Boolean): Int }], LTT[{ def x(b: Boolean): Int }])\n      }\n      brokenOnScala2 {\n        assertNotChildStrict(LTT[{ def x(i: Int)(b: Boolean): Int }], LTT[{ def x(i: Int): Int }])\n      }\n\n      brokenOnScala3 {\n        // no distinction between method with multiple param lists and one param list\n        assertNotChildStrict(LTT[{ def x(i: Int)(b: Boolean): Int }], LTT[{ def x(i: Int, b: Boolean): Int }])\n      }\n\n      assertChildStrict(LTT[{ def x(i: Int)(b: Boolean): Int }], LTT[{ def x(i: Int)(b: Boolean): Any }])\n      // This isn't quite true according to Scalac:\n      //   implicitly[({ def x(i: Int)(b: Boolean): Int }) <:< ({ def x(i: Int)(b: Nothing): Int })] // false\n      // But since the equivalent with values instead of methods is true, we regard this as true:\n      //   implicitly[({ def x(i: Int): Boolean => Int }) <:< ({ def x(i: Int): Nothing => Int })] // true\n      assertChildStrict(LTT[{ def x(i: Int)(b: Boolean): Int }], LTT[{ def x(i: Int)(b: Nothing): Int }])\n    }\n\n    \"progression test: fails to `Any/Object relation is consistent with Scala`\" in {\n      implicitly[Object <:< Any]\n      def isNoImplicit[A <: AnyRef](implicit ev: A = null): Boolean = ev eq null\n      assert(isNoImplicit[Any <:< Object])\n\n      assertChild(LTT[Object], LTT[Any])\n      broken {\n        assertNotChild(LTT[Any], LTT[Object])\n      }\n      assertDifferent(LTT[Any], LTT[Object])\n    }\n\n    \"progression test: can't distinguish between equal-bounded type and alias inside refinements on dotty\" in {\n      val t4 = LTT[{ type X >: Any <: Any }] // (java.lang.Object {type X = Any}), but should be (java.lang.Object {type X::<Any..Any>})\n      val t5 = LTT[{ type X = Any }]\n\n      brokenOnScala3 {\n        assertDifferent(t4, t5)\n      }\n    }\n\n    \"progression test: Null type is a subtype of Nothing, but shouldn't be\" in {\n      broken {\n        assertNotChild(LTT[Null], LTT[Nothing])\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/SharedLightTypeTagTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti.LightTypeTagRef.{AbstractReference, AppliedNamedReference, Boundaries, FullReference, NameReference, TypeParam, Variance}\nimport izumi.reflect.macrortti._\n\nimport scala.collection.immutable.ListSet\nimport scala.collection.{BitSet, immutable, mutable}\n\nabstract class SharedLightTypeTagTest extends TagAssertions {\n\n  import TestModel._\n\n  \"lightweight type tags (all versions)\" should {\n\n    \"support distinction between subtypes\" in {\n      val str = LTT[String]\n      val subStrA = LTT[SubStrA]\n      val subStrB = LTT[SubStrB]\n      val subStrC = LTT[SubStrC]\n      val subStrD = LTT[SubStrD]\n      val subSubStr = LTT[SubSubStr]\n\n      assertChildStrict(subStrA, str)\n      assertChildStrict(subSubStr, str)\n      assertChildStrict(subSubStr, subStrA)\n      assertNotChildStrict(subSubStr, subStrB)\n\n      assertSameStrict(subStrC, str)\n\n      assertNotChild(subStrA, subStrB)\n      assertSame(subStrA, subStrD)\n\n      // see https://github.com/7mind/izumi/pull/1528\n      assertSame(str.combine(), str)\n\n      val strInhBases = LightTypeTagUnpacker(str).inheritance(str.ref.asInstanceOf[NameReference])\n      val subStrAInhBases = LightTypeTagUnpacker(subStrA).inheritance(subStrA.ref.asInstanceOf[NameReference].copy(boundaries = Boundaries.Empty))\n      val subSubStrInhBases = LightTypeTagUnpacker(subSubStr).inheritance(subSubStr.ref.asInstanceOf[NameReference].copy(boundaries = Boundaries.Empty))\n\n      assert(subStrAInhBases == (strInhBases ++ Set(str.ref.asInstanceOf[NameReference])))\n      assert(subSubStrInhBases == (strInhBases ++ Set(str.ref.asInstanceOf[NameReference])))\n\n      val strFullBases = LightTypeTagUnpacker(str).bases(str.ref.asInstanceOf[NameReference])\n      val subStrAFullBases = LightTypeTagUnpacker(subStrA).bases(subStrA.ref.asInstanceOf[NameReference])\n      val subSubStrFullBases = LightTypeTagUnpacker(subSubStr).bases(subSubStr.ref.asInstanceOf[NameReference])\n\n      assert(LightTypeTagUnpacker(str).bases.keySet == Set(str.ref.asInstanceOf[AppliedNamedReference]))\n      assert(subStrA.repr == \"izumi.reflect.test.TestModel::SubStrA|<scala.Nothing..java.lang.String>\")\n      assert(subStrA.repr != \"izumi.reflect.test.TestModel$::SubStrA|<scala.Nothing..java.lang.String>\")\n\n      assert(subStrAFullBases == (strFullBases ++ Set(str.ref.asInstanceOf[AbstractReference])))\n      assert(subSubStrFullBases == (strFullBases ++ Set(str.ref.asInstanceOf[AbstractReference])))\n\n      val foo = LTT[SubStrA \\/ Int]\n      val bar = `LTT[_,_]`[\\/].combine(subStrA, LTT[Int])\n      assertSameStrict(foo, bar)\n    }\n\n    \"eradicate intersection tautologies with Any/Object\" in {\n      assertSameStrict(LTT[Any with Option[String]], LTT[Option[String]])\n      assertSameStrict(LTT[AnyRef with Option[String]], LTT[Option[String]])\n      assertSameStrict(LTT[Object with Option[String]], LTT[Option[String]])\n    }\n\n    \"do not eradicate intersections with Nothing\" in {\n      assertDifferent(LTT[Nothing with Option[String]], LTT[Option[String]])\n      assertSameStrict(LTT[Nothing with Option[String]], LTT[Option[String] with Nothing])\n    }\n\n    \"eradicate self-intersection (X with X)\" in {\n      assertSameStrict(`LTT`[String with String], `LTT`[String])\n    }\n\n    \"support subtype checks\" in {\n      assertChild(LTT[Int], LTT[AnyVal])\n      assertChild(LTT[Int], LTT[Int])\n      assertChild(LTT[List[Int]], LTT[List[Int]])\n      assertChild(LTT[List[I2]], LTT[List[I1]])\n      assertChild(LTT[Either[Nothing, Int]], LTT[Either[Throwable, Int]])\n\n      assertChild(LTT[F2[I2]], LTT[F1[I1]])\n      assertChild(LTT[FT2[IT2]], LTT[FT1[IT2]])\n\n      assertChild(LTT[FM2[I2]], LTT[FM1[I1, Unit]])\n\n      assertChild(LTT[Option[Nothing]], LTT[Option[Int]])\n\n      assertChild(`LTT[_[_],_[_]]`[P1].combine(`LTT[_]`[X1], `LTT[_]`[X2]), LTT[P0[X2, X1]])\n      assertNotChild(`LTT[_[_],_[_]]`[P1].combine(`LTT[_]`[X1], `LTT[_]`[X2]), LTT[P0[X1, X2]])\n\n      assertChild(`LTT[_[_]]`[XP1].combine(`LTT[_]`[X1]), LTT[P0[X2, X1]])\n      assertChild(`LTT[_[_]]`[XP1].combine(`LTT[_]`[X2]), LTT[P0[X2, X2]])\n      assertNotChild(`LTT[_[_]]`[XP1].combine(`LTT[_]`[X2]), LTT[P0[X2, X1]])\n      assertNotChild(`LTT[_[_]]`[XP1].combine(`LTT[_]`[X2]), LTT[P0[X1, X2]])\n    }\n\n    \"support unsound subtype checks\" in {\n      // UNSOUND-LAMBDA-COMPARISON\n      // it's hard to say how should we compare propers with lambdas...\n\n      // these two may be inverted by uncommenting corresponding lines in inheritance checks\n      assertNotChild(LTT[FM2[I2]], `LTT[_,_]`[FM1])\n      assertNotChild(LTT[List[Int]], `LTT[_]`[List])\n\n      // this one should be always false\n      assertNotChild(LTT[Set[Int]], `LTT[_]`[Set])\n    }\n\n    \"support swapped parents\" in {\n      trait KT1[+A1, +B1]\n      trait KT2[+A2, +B2] extends KT1[B2, A2]\n\n      assertChild(LTT[KT2[H1, I1]], LTT[KT1[I1, H1]])\n      assertNotChild(LTT[KT2[H1, I1]], LTT[KT1[H1, I1]])\n\n      assertChild(LTT[KT2[H2, I2]], LTT[KT1[I1, H1]])\n      assertNotChild(LTT[KT2[H2, I2]], LTT[KT1[H1, I1]])\n\n      trait KK1[+A, +B, +U]\n      trait KK2[+A, +B] extends KK1[B, A, Unit]\n\n      assertChild(LTT[KK2[Int, String]], LTT[KK1[String, Int, Unit]])\n\n      assertChild(LTT[KK2[H2, I2]], LTT[KK1[I1, H1, Unit]])\n      assertNotChild(LTT[KK2[H2, I2]], LTT[KK1[H1, I1, Unit]])\n\n      assertNotChild(`LTT[_]`[KK2[H2, *]], `LTT[_]`[KK1[H1, *, Unit]])\n\n      type KK1Unit[+A, +B] = KK1[A, B, Unit]\n      type SwappedKK2[+A, +B] = KK2[B, A]\n\n      // before, we had incorrect fullBases parent lambdaification on Scala 3:\n      // fullBases on Scala 3 has 1 type parameter before extractLambdaBase:\n      // - λ %0 → izumi.reflect.test.SharedLightTypeTagProgressionTest._$KK2[+izumi.reflect.test.TestModel::H2,+0] ->\n      //   * λ %0 → izumi.reflect.test.SharedLightTypeTagProgressionTest._$KK1[+0,+izumi.reflect.test.TestModel::H2,+scala.Unit]\n      // While should be 2 type parameters:\n      // - λ %0,%1 → izumi.reflect.test.SharedLightTypeTagProgressionTest.KK2[+0,+1] ->\n      //   * λ %0,%1 → izumi.reflect.test.SharedLightTypeTagProgressionTest.KK1[+1,+0,+scala.Unit]\n\n      // Or... maybe it's Scala 3 that's more correct. See SwappedKK2 parents on Scala 2:\n      // - λ %0,%1 → izumi.reflect.test.SharedLightTypeTagProgressionTest.KK2[+0,+1] ->\n      //   * λ %0,%1 → izumi.reflect.test.SharedLightTypeTagProgressionTest.KK1[+1,+0,+scala.Unit]\n      // VS SwappedKK2 parents on Scala 3, which is correct (it preserves the swappiness):\n      // - λ %0,%1 → izumi.reflect.test.SharedLightTypeTagProgressionTest._$KK2[+1,+0] ->\n      //   * λ %0,%1 → izumi.reflect.test.SharedLightTypeTagProgressionTest._$KK1[+0,+1,+scala.Unit]\n\n      // Ok... we just supported both forms in LightTypeTagInheritance in 3.0.4... somehow... ... ...\n\n      val tag = `LTT[_]`[KK2[H2, *]]\n      val tag1 = `LTT[_,_]`[SwappedKK2]\n\n//      withDebugOutput {\n      assertChild(tag, `LTT[_]`[KK1[*, H1, Unit]])\n      assertChild(tag1, `LTT[_,_]`[KK1Unit])\n      assertNotChild(tag1, `LTT[_,_]`[KK2])\n//      }\n    }\n\n    \"support subtyping of parents parameterized with type lambdas\" in {\n      assertChild(LTT[RoleChild[Either]], LTT[RoleParent[Either[Throwable, *]]])\n    }\n\n    \"support subtyping of parents parameterized with type lambdas in combined tags\" in {\n      val childBase = `LTT[_[_,_]]`[RoleChild]\n      val childArg = `LTT[_,_]`[Either]\n      val combinedTag = childBase.combine(childArg)\n\n      assertSame(combinedTag, LTT[RoleChild[Either]])\n    }\n\n    \"support subtyping of parents parameterized with type lambdas in combined tags with multiple parameters\" in {\n      val childBase = `LTT[_[+_,+_],_,_]`[RoleChild2]\n      val childArgs = Seq(`LTT[_,_]`[Either], LTT[Int], LTT[String])\n      val combinedTag = childBase.combine(childArgs: _*)\n      val expectedTag = LTT[RoleParent[Either[Throwable, *]]]\n      val noncombinedTag = LTT[RoleChild2[Either, Int, String]]\n\n      assertSame(combinedTag, noncombinedTag)\n      assertChild(noncombinedTag, expectedTag)\n    }\n\n    \"support PDTs\" in {\n      val a = new C {\n        override type A = Int\n      }\n      val a0 = new C {}\n      val a1: C = new C {\n        override type A = Int\n      }\n      val a2 = new C {\n        override type A = String\n      }\n\n      assertSame(LTT[a.A], LTT[Int])\n      assertDifferent(LTT[a0.A], LTT[Int])\n      assertDifferent(LTT[a1.A], LTT[Int])\n      assertDifferent(LTT[a1.A], LTT[a2.A])\n      assertChild(LTT[a1.A], LTT[a1.A])\n      assertSame(LTT[a2.A], LTT[String])\n    }\n\n    \"intersections are associative\" in {\n      type F1 = (W3[Int] with W1) with I1\n      type F2 = W3[Int] with (W1 with I1)\n\n      type T1[A] = (W3[A] with W1) with I1\n      type T2[A] = W3[A] with (W1 with I1)\n\n      assertSameStrict(LTT[F1], LTT[F2])\n      assertSameStrict(`LTT[_]`[T1], `LTT[_]`[T2])\n    }\n\n    \"runtime-combined intersections are associative\" in {\n      type F1 = W3[Int] with W1\n      type F11 = (W3[Int] with W1) with I1\n      type F12 = W3[Int] with (W1 with I1)\n\n      type T1[A] = W3[Int] with (W1 with A)\n      type T2[A] = (W3[Int] with W1) with A\n\n      assertIntersection(List(LTT[F1], LTT[I1]), LTT[F11])\n      assertIntersection(List(LTT[F1], LTT[I1]), LTT[F12])\n\n      assertCombine(`LTT[_]`[T1], LTT[I1], LTT[F11])\n      assertCombine(`LTT[_]`[T1], LTT[I1], LTT[F12])\n\n      assertCombine(`LTT[_]`[T2], LTT[I1], LTT[F11])\n      assertCombine(`LTT[_]`[T2], LTT[I1], LTT[F12])\n    }\n\n    \"support type alias and refinement subtype checks\" in {\n      val t1 = LTT[XS]\n      val t2 = LTT[WithX]\n      val t3 = LTT[{ type X >: Nothing <: Any }]\n      val t4 = LTT[{ type X >: Any <: Any }]\n      val t5 = LTT[{ type X = Any }]\n      val t6 = LTT[{ type X = Int }]\n      val t7 = LTT[{ type X <: AnyVal }]\n\n      assertChildStrict(t1, t2)\n      assertChildStrict(t1, t3)\n      assertNotChild(t3, t4)\n      assertChildStrict(t4, t3)\n      assertChildStrict(t5, t3)\n      assertSameStrict(t3, LTT[{ type X }])\n      assertNotChild(t3, t7)\n\n      assertNotChild(t3, t5)\n      assertNotChild(t2, t5)\n      assertNotChild(t3, t4)\n      assertNotChild(t2, t4)\n      assertNotChild(t1, t4)\n\n      assertChildStrict(t6, t3)\n      assertChildStrict(t6, t7)\n      assertNotChildStrict(t6, t4)\n      assertNotChildStrict(t6, t5)\n    }\n\n    \"support refinement higher-kinded subtype checks\" in {\n      val t1 = LTT[{ type F[A] = A }]\n      val t2 = LTT[{ type F[A] <: Any }]\n      val t3 = LTT[{ type F[A] <: AnyVal }]\n      val t4 = LTT[FXS]\n\n      assertChildStrict(t1, t2)\n      assertNotChildStrict(t1, t3)\n\n      assertChildStrict(t4, t1)\n      assertChildStrict(t4, t2)\n      assertNotChildStrict(t4, t3)\n    }\n\n    \"support literal types\" in {\n      assertSame(literalLtt(\"str2\"), literalLtt(\"str2\"))\n      assertDifferent(literalLtt(\"str1\"), literalLtt(\"str2\"))\n\n      assertChildStrict(literalLtt(\"str\"), LTT[String])\n      assertNotChild(literalLtt(\"str\"), LTT[Int])\n\n      val tag = literalLtt(\"str\")\n      assertRepr(tag, \"\\\"str\\\"\")\n    }\n\n    \"resolve comparisons of object and trait with the same name\" in {\n      assertNotChild(LTT[YieldOpCounts.type], LTT[RoleChild[Either]])\n      assertChild(LTT[YieldOpCounts.type], LTT[YieldOpCounts])\n      assertDifferent(LTT[YieldOpCounts.type], LTT[YieldOpCounts])\n      assertNotChild(LTT[YieldOpCounts], LTT[YieldOpCounts.type])\n    }\n\n    \"resolve prefixes of annotated types\" in {\n      assertSame(LTT[TPrefix.T @unchecked], LTT[TPrefix.T])\n    }\n\n    \"`withoutArgs` comparison works\" in {\n      assert(LTT[Set[Int]].ref.withoutArgs == LTT[Set[Any]].ref.withoutArgs)\n      assert(LTT[Either[Int, String]].ref.withoutArgs == LTT[Either[Boolean, List[Int]]].ref.withoutArgs)\n\n      assertSame(LTT[Set[Int]].withoutArgs, LTT[Set[Any]].withoutArgs)\n\n      assertChild(LTT[mutable.LinkedHashSet[Int]].withoutArgs, LTT[collection.Set[Any]].withoutArgs)\n      assertChild(LTT[ListSet[Int]].withoutArgs, LTT[collection.Set[Any]].withoutArgs)\n      assertChild(LTT[ListSet[Int]].withoutArgs, LTT[immutable.Set[Any]].withoutArgs)\n      assertChild(LTT[BitSet].withoutArgs, LTT[collection.Set[Any]].withoutArgs)\n    }\n\n    \"`typeArgs` works\" in {\n      assertSame(LTT[Set[Int]].typeArgs.head, LTT[collection.Set[Int]].typeArgs.head)\n      assertChild(LTT[Set[Int]].typeArgs.head, LTT[collection.Set[AnyVal]].typeArgs.head)\n\n      assert(`LTT[_,_]`[Either].typeArgs.isEmpty)\n      assert(`LTT[_]`[Either[String, *]].typeArgs == List(LTT[String]))\n\n      val tag = `LTT[_[_]]`[({ type l[F[_]] = T0[List, F] })#l]\n      val tagApplied = tag.combine(`LTT[_]`[Option])\n      assertSame(tagApplied, LTT[T0[List, Option]])\n      assert(tag.typeArgs == List(`LTT[_]`[List]))\n      assert(tagApplied.typeArgs == List(`LTT[_]`[List], `LTT[_]`[Option]))\n    }\n\n    \"support subtyping of a simple combined type\" in {\n      val ctor = `LTT[_[_]]`[ApplePaymentProvider]\n      val arg = `LTT[_]`[Id]\n      val combined = ctor.combine(arg)\n      assertChild(combined, LTT[H1])\n    }\n\n    \"issue #762: properly strip away annotated types / empty refinements / type aliases\" in {\n      val predefString = LTT[String]\n      val javaLangString = LTT[java.lang.String]\n      val weirdPredefString = LTT[(scala.Predef.String {}) @IdAnnotation(\"abc\")]\n\n      assertSame(predefString, javaLangString)\n      assertSame(predefString, weirdPredefString)\n      assertSame(javaLangString, weirdPredefString)\n\n      assertDebugSame(predefString, javaLangString)\n      assertDebugSame(predefString, weirdPredefString)\n      assertDebugSame(javaLangString, weirdPredefString)\n\n      val javaLangOpt = LTT[Option[java.lang.String]]\n      val predefOpt = LTT[Option[scala.Predef.String]]\n      val weirdPredefOpt = LTT[Option[(scala.Predef.String {}) @IdAnnotation(\"x\")]]\n\n      assertDebugSame(javaLangOpt, predefOpt)\n      assertDebugSame(javaLangOpt, weirdPredefOpt)\n    }\n\n    \"calculate identical hashCode in parsed and constructed instances\" in {\n      val tag1 = LTT[String]\n      val tag2 = tag1.withoutArgs\n      assertSameRef(tag1, tag2)\n      assertSame(tag1, tag2)\n      assert(tag1.hashCode() == tag2.hashCode())\n      assert(tag1.hashCode() != 0)\n      assert(tag1.ref.hashCode() != 0)\n    }\n\n    \"support non-positional typetag combination\" in {\n      assertCombineNonPos(`LTT[_,_]`[Either], Seq(None, Some(LTT[Unit])), `LTT[_]`[Either[*, Unit]])\n    }\n\n    \"support additional mixin traits after first trait with a HKT parameter\" in {\n      assertChild(LTT[J[Option]], LTT[J1[Option]])\n      assertChild(LTT[J[Option]], LTT[J3])\n      assertChild(LTT[J[Option]], LTT[J2])\n      assertChild(LTT[J[Option]], LTT[J1[Option] with J2])\n      assertChild(LTT[J[Option]], LTT[J2 with J3])\n      assertChild(LTT[J[Option]], LTT[J1[Option] with J2 with J3])\n    }\n\n    \"support LTagK* family summoners\" in {\n      val tag = LTagK[List].tag\n      val tag1 = LTagKK[Either].tag\n      assertSame(tag, `LTT[_]`[List])\n      assertSame(tag1, `LTT[_,_]`[Either])\n    }\n\n    \"support higher-kinded intersection type equality\" in {\n      type T1[A] = W3[A] with W1\n      type T2[A] = W4[A] with W2\n\n      assertSame(`LTT[_]`[T1], `LTT[_]`[T1])\n      assertDifferent(`LTT[_]`[T1], `LTT[_]`[T2])\n    }\n\n    \"support contravariance\" in {\n      assertChildStrict(LTT[Any => Int], LTT[Int => Int])\n    }\n\n    \"support typetag combination\" in {\n      assertCombine(`LTT[_[_]]`[T1], `LTT[_]`[Id], LTT[T1[Id]])\n      assertCombine(`LTT[_[_]]`[T1], `LTT[_]`[FP], LTT[T1[FP]])\n      assertCombine(`LTT[_[_]]`[T1], `LTT[_]`[FI], LTT[T1[FI]])\n\n      assertCombine(`LTT[_[_]]`[T1], `LTT[_]`[List], LTT[T1[List]])\n      assertCombine(`LTT[_]`[List], LTT[Int], LTT[List[Int]])\n      assertCombine(`LTT[_,_]`[Either], LTT[Unit], `LTT[_]`[Either[Unit, *]])\n\n      assertCombine(`LTT[_[_[_],_[_]]]`[T2], `LTT[_[_],_[_]]`[T0], LTT[T2[T0]])\n\n      type ComplexRef[T] = W1 with T { def a(p: T): T; type M = T }\n      assertCombine(`LTT[_]`[ComplexRef], LTT[Int], LTT[W1 with Int { def a(p: Int): Int; type M = Int }])\n\n      assertCombine(`LTT[_[_]]`[({ type l[K[_]] = T0[Id, K] })#l], `LTT[_]`[FP], LTT[T0[Id, FP]])\n    }\n\n    \"tautological intersections with Any/Object are discarded from internal structure\" in {\n      assertSameStrict(LTT[(Object {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]], LTT[Option[String]])\n      assertSameStrict(LTT[(Any {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]], LTT[Option[String]])\n      assertSameStrict(LTT[(AnyRef {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]], LTT[Option[String]])\n\n      assertDebugSame(LTT[(Object {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]], LTT[Option[String]])\n      assertDebugSame(LTT[(Any {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]], LTT[Option[String]])\n      assertDebugSame(LTT[(AnyRef {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]], LTT[Option[String]])\n    }\n\n    \"wildcards are supported\" in {\n      assertDifferent(LTT[Set[_]], LTT[Set[Any]])\n      assertChild(LTT[Set[Int]], LTT[Set[_]])\n      assertNotChild(LTT[Set[_]], LTT[Set[Int]])\n      assertChild(LTT[Set[Any]], LTT[Set[_]])\n      assertNotChild(LTT[Set[_]], LTT[Set[Any]])\n\n      assertDifferent(LTT[List[_]], LTT[List[Any]])\n      assertChild(LTT[List[Int]], LTT[List[_]])\n      assertNotChild(LTT[List[_]], LTT[List[Int]])\n      assertChild(LTT[List[Any]], LTT[List[_]])\n      assertChild(LTT[List[_]], LTT[List[Any]])\n\n      assertDifferent(LTT[Int => Int], LTT[_ => Int])\n      assertChild(LTT[Int => Int], LTT[_ => Int])\n      assertChild(LTT[_ => Int], LTT[Int => Int]) // incorrect but whatever\n    }\n\n    \"wildcards with bounds are supported\" in {\n      assertDifferent(LTT[Option[W1]], LTT[Option[_ <: W1]])\n      assertDifferent(LTT[Option[H2]], LTT[Option[_ >: H4 <: H2]])\n      assertDifferent(LTT[Option[Any]], LTT[Option[_ >: H4]])\n    }\n\n    \"generate tags for wildcards with type boundaries\" in {\n      assertDifferent(LTT[Option[W1]], LTT[Option[_ <: W1]])\n      assertChild(LTT[Option[W1]], LTT[Option[_ <: W1]])\n      assertChild(LTT[Option[W2]], LTT[Option[_ <: W1]])\n      assertNotChild(LTT[Option[W2]], LTT[Option[_ <: I1]])\n\n      assertChild(LTT[Option[_ <: W2]], LTT[Option[W1]])\n      assertChild(LTT[Option[_ <: W2]], LTT[Option[W2]])\n      assertNotChild(LTT[Option[_ <: I1]], LTT[Option[W2]])\n\n      assertChild(LTT[Option[H3]], LTT[Option[_ >: H4 <: H2]])\n      assertNotChild(LTT[Option[H1]], LTT[Option[_ >: H4 <: H2]])\n\n      assertTypeError(\"val o: Option[H3] = None: Option[_ >: H4 <: H2]\")\n      assertNotChild(LTT[Option[_ >: H4 <: H2]], LTT[Option[H3]])\n      assertNotChild(LTT[Option[_ >: H4]], LTT[Option[H3]])\n      assertNotChild(LTT[Option[_ <: H2]], LTT[Option[H3]])\n\n      locally { val o: Option[H1] = None: Option[_ <: H2] }\n      assertTypeError(\"val o: Option[H1] = None: Option[_ >: H4]\")\n      assertChild(LTT[Option[_ <: H2]], LTT[Option[H1]])\n      assertNotChild(LTT[Option[_ >: H4]], LTT[Option[H1]])\n      assertChild(LTT[Option[_ >: H4 <: H2]], LTT[Option[H1]])\n\n      if (!IsScala3) {\n        assertCompiles(\"val opt: Option[_ >: H4 <: H2] = None: Option[H5]\")\n      } else {\n        assertCompiles(\"val opt: Option[_ >: H4 <: H2] = (None: Option[H5]): Option[H4]\")\n      }\n      assertChild(LTT[Option[H4]], LTT[Option[_ >: H4 <: H2]])\n      assertChild(LTT[Option[H2]], LTT[Option[_ >: H4 <: H2]])\n      // this is counterintuitive but that's how Scala works, it ignores lower boundary in contravariant position\n      assertChild(LTT[Option[H5]], LTT[Option[_ >: H4 <: H2]])\n    }\n\n    \"https://github.com/zio/izumi-reflect/issues/315 regression test 2.1.0-M1: IntegrationCheck[F] should not be related to IntegrationCheck[Identity]\" in {\n      assertNotChildStrict(LTT[IntegrationCheck[Option]], LTT[IntegrationCheck[Id]])\n    }\n\n    \"normalize stable PDTs (https://github.com/zio/zio/issues/3390)\" in {\n      val t1 = LTT[PDTNormA.Service]\n      val t2 = LTT[PDTNormB.Service]\n      assertSameStrict(t2, t1)\n      assertDebugSame(t2, t1)\n\n      val PDTAlias1 = PDTNormB\n      val PDTAlias2 = PDTAlias1\n      val PDTAlias3 = PDTAlias2\n      val PDTAlias4 = PDTAlias3\n      val PDTAlias5 = PDTAlias4\n      val t3 = LTT[PDTAlias5.Service]\n      assertSameStrict(t3, t1)\n      assertDebugSame(t3, t1)\n      object xa {\n        val PDTAlias6 = PDTAlias5\n      }\n\n      val t4 = LTT[PDTNormA.type]\n      val t5 = LTT[PDTAlias5.type]\n      val t6 = LTT[xa.PDTAlias6.type]\n\n      assertSameStrict(t5, t4)\n      assertDebugSame(t5, t4)\n      assertSameStrict(t6, t4)\n      assertDebugSame(t6, t4)\n\n      val literal = \"x\"\n      val aliasLiteral: literal.type = literal\n      val t7 = LTag[literal.type].tag\n      val t8 = LTag[aliasLiteral.type].tag\n\n      assertSameStrict(t7, t8)\n      assertDebugSame(t7, t8)\n    }\n\n    \"distinguish nested path dependent types (https://github.com/zio/izumi-reflect/issues/363)\" in {\n      trait Base {\n        object Nested {\n          trait Member\n        }\n      }\n      object A extends Base\n      object B extends Base\n\n      assertDifferent(LTT[A.Nested.Member], LTT[B.Nested.Member])\n    }\n\n    // Workaround for https://github.com/scala/scala3/issues/23279\n    def dealiasTestWrapper(): Unit = {\n      object lifecycle {\n        object Lifecycle {\n          trait FromZIO\n        }\n      }\n      object defn {\n        val Lifecycle: lifecycle.Lifecycle.type = lifecycle.Lifecycle\n      }\n      val xa: defn.Lifecycle.type = defn.Lifecycle\n\n      assertSameStrict(LTT[xa.FromZIO], LTT[lifecycle.Lifecycle.FromZIO])\n    }\n    \"dealias nested singletons, regression test for singleton dealias regression introduced in 3.0.0 (https://github.com/zio/izumi-reflect/pull/504)\" in {\n      dealiasTestWrapper()\n    }\n\n    \"dealias deeply singleton val aliases\" in {\n      trait diffBase {\n        object Nested {\n          trait Member\n        }\n      }\n      object diffA extends diffBase\n      object diffB {\n        val Nested: diffA.Nested.type = diffA.Nested\n      }\n      object diffNB {\n        val Nested: diffB.Nested.type = diffB.Nested\n      }\n\n      assertSameStrict(LTT[diffNB.Nested.Member], LTT[diffA.Nested.Member])\n    }\n\n    \"properly dealias and assign prefixes to existential types and wildcards\" in {\n      val withNothing = LTT[TestModel.With[Nothing]]\n      val with_ = LTT[TestModel.With[_]]\n      assert(withNothing.debug().contains(\": izumi.reflect.test.TestModel::With[=scala.Nothing]\"))\n      assert(withNothing.debug().contains(\"- izumi.reflect.test.TestModel::With[=scala.Nothing]\"))\n      assert(with_.debug().contains(\": izumi.reflect.test.TestModel::With[=?]\"))\n      assert(with_.debug().contains(\"- izumi.reflect.test.TestModel::With[=?]\"))\n\n      val list1 = LTT[List[_]]\n      val list2 = LTT[List[_]]\n      assertChild(LTT[List[Int]], list2)\n      assertChild(LTT[scala.collection.immutable.List[Int]], list1)\n      assertChild(list1, list2)\n      assertChild(list2, list1)\n      assertDebugSame(list1, list2)\n    }\n\n    \"no redundant $ in object names\" in {\n      val ltt = LTT[TestModel.BasicCases.BasicCase2.TestImpl0Good]\n      assert(!ltt.debug().contains(\"BasicCase2$\"))\n      assert(!ltt.debug().contains(\"BasicCases$\"))\n      assert(!ltt.repr.contains(\"BasicCase2$\"))\n      assert(!ltt.repr.contains(\"BasicCases$\"))\n      assert(!ltt.toString.contains(\"BasicCase2$\"))\n      assert(!ltt.toString.contains(\"BasicCases$\"))\n      assert(ltt.longNameWithPrefix == \"izumi.reflect.test.TestModel.BasicCases.BasicCase2.TestImpl0Good\")\n    }\n\n    \"support basic None.type subtype check\" in {\n      assertChild(LTT[None.type], LTT[Option[Int]])\n    }\n\n    \"supports complex type lambdas\" in {\n      assertSame(`LTT[_,_]`[NestedTL[Const, *, *]], `LTT[_,_]`[λ[(A, B) => FM2[(B, A)]]])\n      assertSame(\n        `LTT[_[_]]`[({ type l[F[_]] = NestedTL2[W1, W2, F] })#l],\n        `LTT[_[_]]`[({ type l[G[_]] = FM2[G[S[W2, W1]]] })#l]\n      )\n      assertChild(`LTT[_,_]`[NestedTL[Const, *, *]], `LTT[_,_]`[λ[(A, B) => FM2[(B, A)]]])\n    }\n\n    \"applied tags should not contain junk bases\" in {\n      val debug0 = LTT[List[Any]].debug()\n//      val debug0 = PlatformSpecific.fromRuntime[List[Any]].debug()\n\n      assert(!debug0.contains(\"scala.List\"))\n      assert(!debug0.contains(\"package::List\"))\n      assert(!debug0.contains(\"<refinement>\"))\n      assert(!debug0.contains(\"<none>\"))\n      assert(debug0.contains(\"- scala.collection.immutable.List[+scala.Any]\"))\n      assert(debug0.contains(\"- λ %0 → scala.collection.immutable.List[+0]\"))\n\n      //      val debug1 = LTT[List[_]].debug()\n      val debug1 = PlatformSpecific.fromRuntime[List[_]].debug()\n\n      assert(!debug1.contains(\"scala.List\"))\n      assert(!debug1.contains(\"package::List\"))\n      assert(!debug1.contains(\"<refinement>\"))\n      assert(!debug1.contains(\"<none>\"))\n      assert(debug1.contains(\"- scala.collection.immutable.List[+?]\"))\n      assert(debug1.contains(\"- λ %0 → scala.collection.immutable.List[+0]\"))\n\n      val debug2 = LTT[Either[RoleChild[IO], Product]].debug()\n//      val debug2 = PlatformSpecific.fromRuntime[Either[RoleChild[IO], Product]].debug()\n\n      assert(!debug2.contains(\"package::Either\"))\n      assert(!debug2.contains(\"<refinement>\"))\n      assert(!debug2.contains(\"<none>\"))\n      assert(!debug2.contains(\"TestModel.E\"))\n      assert(!debug2.contains(\"TestModel.A\"))\n      assert(debug2.contains(\"- λ %0 → izumi.reflect.test.TestModel::RoleChild[=0]\"))\n      assert(debug2.contains(\"* λ %0 → izumi.reflect.test.TestModel::RoleParent[=λ %1:0 → 0[=java.lang.Throwable,=1:0]]\"))\n    }\n\n    \"intersection lambda tags should not contain junk bases\" in {\n      val tCtor = `LTT[_,_]`[T3]\n      //      val tCtor = PlatformSpecific.fromRuntime(scala.reflect.runtime.universe.typeOf[T3[Any, Any]].typeConstructor)\n      val debugCtor = tCtor.debug(\"ctor\")\n\n      val combined = tCtor.combine(LTT[Int], LTT[Boolean])\n      val debugCombined = combined.debug(\"combined\")\n\n      val alias = LTT[T3[Int, Boolean]]\n      val direct = LTT[W1 with W4[Boolean] with W5[Int]]\n\n      assert(!debugCtor.contains(\"<refinement>\"))\n      assert(!debugCtor.contains(\"<none>\"))\n      assert(!debugCtor.contains(\"- T\"))\n      assert(!debugCtor.contains(\"W4[=B]\"))\n      assert(!debugCtor.contains(\"W3[=B]\"))\n      assert(!debugCtor.contains(\"W5[=A]\"))\n\n      assert(!direct.debug().contains(\"W4[=Int]\"))\n      assert(!direct.debug().contains(\"W4[=scala.Int]\"))\n\n      assert(!debugCombined.contains(\"<refinement>\"))\n      assert(!debugCombined.contains(\"<none>\"))\n      assert(!debugCombined.contains(\"- T\"))\n      assert(!debugCombined.contains(\"W4[=B]\"))\n      assert(!debugCombined.contains(\"W3[=B]\"))\n      assert(!debugCombined.contains(\"W5[=A]\"))\n      assert(debugCombined.contains(\"W5[=scala.Int]\"))\n\n      assertDebugSame(alias, direct)\n    }\n\n    \"lambda tags should not contain junk bases\" in {\n      val debug1 = `LTT[_,_]`[Right].debug()\n\n      assert(!debug1.contains(\"package::Either\"))\n      assert(!debug1.contains(\"scala.package.A\"))\n      assert(!debug1.contains(\"scala.package.B\"))\n      assert(debug1.contains(\"- λ %0,%1 → scala.util.Right[+0,+1]\"))\n      assert(debug1.contains(\"* scala.Product\"))\n\n      val debug2 = `LTT[_,_]`[Right].combine(LTT[Int], LTT[Int]).debug()\n\n      assert(!debug2.contains(\"package::Either\"))\n      assert(!debug2.contains(\"scala.package.A\"))\n      assert(!debug2.contains(\"scala.package.B\"))\n      assert(debug2.contains(\"- λ %0,%1 → scala.util.Right[+0,+1]\"))\n      assert(debug2.contains(\"* scala.Product\"))\n\n      val debug3 = LTT[RoleParent[Right[Throwable, *]]].debug()\n//      val debug3 = PlatformSpecific.fromRuntime[RoleParent[Right[Throwable, *]]].debug()\n\n      assert(!debug3.contains(\"package::Right\"))\n      assert(!debug3.contains(\"<refinement>\"))\n      assert(!debug3.contains(\"<none>\"))\n      assert(!debug3.contains(\"TestModel.E\"))\n      assert(!debug3.contains(\"TestModel.A\"))\n      assert(!debug3.contains(\"+scala.Nothing\"))\n//        assert(debug3.contains(\"- λ %0 → scala.util.Right[+java.lang.Throwable,+0]\"))\n      if (IsScala3) {\n        assert(debug3.contains(\"- λ %1:0,%1:1 → scala.util.Right[+1:0,+1:1]\"))\n      } else {\n        assert(debug3.contains(\"- λ %0,%1 → scala.util.Right[+0,+1]\"))\n      }\n      assert(debug3.contains(\"* scala.Product\"))\n\n      val debug4 = `LTT[_]`[Right[Throwable, *]].debug()\n//      val debug4 = PlatformSpecific\n//        .fromRuntime(\n//          scala.reflect.runtime.universe.typeOf[{ type l[a] = Right[Throwable, a] }].member(scala.reflect.runtime.universe.TypeName(\"l\")).typeSignature\n//        ).debug()\n\n      assert(!debug4.contains(\"package::Right\"))\n      assert(!debug4.contains(\"<refinement>\"))\n      assert(!debug4.contains(\"<none>\"))\n      assert(!debug4.contains(\"TestModel.E\"))\n      assert(!debug4.contains(\"TestModel.A\"))\n      assert(!debug4.contains(\"+scala.Nothing\"))\n//        assert(debug4.contains(\"- λ %0 → scala.util.Right[+java.lang.Throwable,+0]\"))\n      if (IsScala3) {\n        assert(debug4.contains(\"- λ %1:0,%1:1 → scala.util.Right[+1:0,+1:1]\"))\n      } else {\n        assert(debug4.contains(\"- λ %0,%1 → scala.util.Right[+0,+1]\"))\n      }\n      assert(debug4.contains(\"* scala.Product\"))\n\n      val oneArgApplied = `LTT[_,_]`[Right].combine(LTT[Throwable]).combine(LTT[Unit])\n      val debug5 = oneArgApplied.debug()\n\n      assert(!debug5.contains(\"package::Right\"))\n      assert(!debug5.contains(\"<refinement>\"))\n      assert(!debug5.contains(\"<none>\"))\n      assert(!debug5.contains(\"scala.package.A\"))\n      assert(!debug5.contains(\"scala.package.B\"))\n      assert(!debug5.contains(\"+scala.Nothing\"))\n      assert(debug5.contains(\"* scala.Product\"))\n      assert(debug5.contains(\"- λ %1 → scala.util.Right[+java.lang.Throwable,+1]\"))\n      assert(debug5.contains(\"- λ %0,%1 → scala.util.Right[+0,+1]\"))\n    }\n\n    \"No degenerate lambdas (regression test https://github.com/zio/izumi-reflect/issues/345)\" in {\n      val fullDb = LTT[List[Int]].basesdb\n\n      fullDb.foreach {\n        case (_, parents) =>\n          parents.foreach {\n            case LightTypeTagRef.Lambda(List(name), FullReference(_, params, _)) =>\n              assert(params.exists {\n                case TypeParam(NameReference(ref, _, _), _) =>\n                  name == ref\n                case _ => false\n              })\n            case _ =>\n          }\n      }\n    }\n\n    \"check subtyping when higher-kinds are involved on Scala 3\" in {\n      assertChild(LTT[FT2[IT2]], LTT[FT1[IT1]])\n      assertChild(`LTT[_[+_[_]]]`[FT2].combine(`LTT[_[+_]]`[IT2]), LTT[FT1[IT1]])\n      assertDifferent(`LTT[_[+_[_]]]`[FT2].combine(`LTT[_[+_]]`[IT2]), LTT[FT1[IT1]])\n      assertChild(`LTT[_[+_[_]]]`[FT2].combine(`LTT[_[+_]]`[IT1]), LTT[FT1[IT1]])\n      assertDifferent(`LTT[_[+_[_]]]`[FT2].combine(`LTT[_[+_]]`[IT1]), LTT[FT1[IT1]])\n      assertChild(`LTT[_[+_[_]]]`[FT1].combine(`LTT[_[+_]]`[IT2]), LTT[FT1[IT1]])\n      assertDifferent(`LTT[_[+_[_]]]`[FT1].combine(`LTT[_[+_]]`[IT2]), LTT[FT1[IT1]])\n      assertSame(`LTT[_[+_[_]]]`[FT1].combine(`LTT[_[+_]]`[IT1]), LTT[FT1[IT1]])\n    }\n\n    \"support higher-kinded intersection type subtyping\" in {\n      type F1 = W3[Int] with W1\n      type F2 = W4[Int] with W2\n\n      type T1[A] = W3[A] with W1\n      type T2[A] = W4[A] with W2\n\n      val f1 = LTT[F1]\n      val f2 = LTT[F2]\n\n      assertChild(f1, LTT[W3[Int]])\n      assertChild(f1, LTT[W1])\n      assertChild(f2, f1)\n\n      val t1 = `LTT[_]`[T1]\n      val t2 = `LTT[_]`[T2]\n      val w3 = `LTT[_]`[W3]\n      val w4 = `LTT[_]`[W4]\n\n      assertChild(t1, w3)\n      assertChild(t1, LTT[W1])\n      assertChild(w4, w3)\n      assertChild(t2, t1)\n    }\n\n    \"support higher-kinded intersection type combination\" in {\n      val tCtor = `LTT[_,_]`[T3]\n\n      val combined = tCtor.combine(LTT[Int], LTT[Boolean])\n      val alias = LTT[T3[Int, Boolean]]\n      val direct = LTT[W1 with W4[Boolean] with W5[Int]]\n\n      assertChild(alias, direct)\n      assertChild(combined, alias)\n      assertChild(combined, direct)\n\n      assertSame(alias, direct)\n      assertSame(alias, combined)\n\n      assertDifferent(combined, LTT[Either[Int, Boolean]])\n      assertDifferent(combined, LTT[T3[Boolean, Int]])\n\n      assertNotChild(combined, LTT[Either[Int, Boolean]])\n      assertNotChild(combined, LTT[T3[Boolean, Int]])\n\n      assertChild(combined, LTT[W5[Int]])\n      assertChild(combined, LTT[W4[Boolean]])\n//      withDebugOutput {\n      assertChild(combined, LTT[W3[Boolean]])\n//      }\n      assertChild(combined, LTT[W1])\n      assertChild(combined, LTT[W2])\n      assertChild(combined, LTT[W1 with W3[Boolean]])\n\n      assertNotChild(combined, LTT[W4[Int]])\n      assertNotChild(combined, LTT[W3[Int]])\n      assertNotChild(combined, LTT[W5[Boolean]])\n      assertNotChild(combined, LTT[W1 with W5[Boolean]])\n    }\n\n    \"support structural & refinement type subtype checks\" in {\n      type C1 = C\n      assertSameStrict(LTT[{ def a: Int }], LTT[{ val a: Int }])\n      assertSameStrict(LTT[C { def a: Int }], LTT[C1 { def a: Int }])\n\n      assertChildStrict(LTT[C { def a: Int }], LTT[C])\n      assertChildStrict(LTT[C { type A = Int }], LTT[C])\n      assertChildStrict(LTT[C { type A <: Int }], LTT[C])\n\n      assertChildStrict(LTT[C { def a: Int; def b: Int }], LTT[C { def a: Int }])\n\n      assertChildStrict(LTT[C { def a: Int }], LTT[{ def a: Int }])\n    }\n\n    \"support structural & refinement type equality\" in {\n      assertDifferent(LTT[W4[str.type] with ({ type T = str.type with Int })], LTT[W4[str.type] with ({ type T = str.type with Long })])\n\n      type C1 = C\n      assertSame(LTT[{ def a: Int }], LTT[{ def a: Int }])\n      assertSame(LTT[C { def a: Int }], LTT[C1 { def a: Int }])\n\n      assertDifferent(LTT[C { def a: Int }], LTT[{ def a: Int }])\n      assertDifferent(LTT[C { def a: Int }], LTT[C])\n\n      assertDifferent(LTT[C { def a: Int }], LTT[C { def a: Int; def b: Int }])\n\n      val a1 = new C {\n        override type A = Int\n      }\n      object Z {\n        type X = { type A = Int }\n      }\n      val _ = (a1, Z)\n\n      assertSame(LTT[a1.A], LTT[Z.X#A])\n    }\n\n    \"strong summons test\" in {\n      assertTypeError(\"def x1[T] = LTag[Array[Int] { type X = T }]\")\n\n      assertTypeError(\"def x1[T] = LTag[Array[T]]\")\n      assertTypeError(\"def x1[T <: { type Array }] = LTag[T#Array]\")\n      assertTypeError(\"def x1[T] = LTag[Array[Int] with List[T]]\")\n      assertTypeError(\"def x1[F[_]] = LTag[F[Int]]\")\n\n      assertCompiles(\"def x1 = { object x { type T }; def x1 = LTag[Array[x.T]]; () }\")\n      assertCompiles(\"def x1 = { object x { type T }; LTag[Array[Int] { type X = x.T }]; () }\")\n      assertCompiles(\"def x1 = { object x { type T }; LTag[Array[Int] with List[x.T]]; () }\")\n      assertCompiles(\"def x1 = { object x { type F[_] }; LTag[x.F[Int]]; () }\")\n      assertCompiles(\"def x1 = { object x { type F[_[_]]; type Id[A] = A }; LTag[x.F[x.Id]]; () }\")\n    }\n\n    \"distinguishes between val and type structural refinements\" in {\n      val t1 = LTT[{ type T = Either[Int, String] }]\n      val t2 = LTT[{ val T: Either[Int, String] }]\n      assertNotChildStrict(t1, t2)\n    }\n\n    \"does not contain intersections in plain structural refinements\" in {\n      val t1 = LTT[Any { type T = Int }]\n      val t2 = LTT[{ def x: Int }]\n      assert(!t1.debug().contains(\"&\"))\n      assert(!t2.debug().contains(\"&\"))\n    }\n\n    \"support equal-bounded types as paradoxical (before 2.3.0 and since 2.3.6 NOT equal to their underlying)\" in {\n      object x {\n        type X >: String <: String\n      }\n      val tag = LTT[String]\n      val tag1 = LTT[x.X]\n\n      // equal bounds create a paradox where s <:< t && t <:< s but not s == t, because refs are not the same.\n      // but this is also technically true in Scala. equal bounded abstract types are not identical - have their own\n      // implicit scope, etc. And because in practical usage it's useful to permit these abstract types we're fine with\n      // representing them despite them breaking our model.\n      assertChild(tag, tag1)\n      assertChild(tag1, tag)\n      assertDifferent(tag1, tag) // paradox and bad, but also an inevitable result of using \"optimistic equality\" with binary strings\n    }\n\n    \"support structural subtype checks\" in {\n      assertNotChildStrict(LTT[{ type T = List[Int] }], LTT[{ type T[A] = List[A] }])\n      assertChildStrict(LTT[{ type T = List[Int] }], LTT[{ type T <: List[Any] }])\n      assertChildStrict(LTT[{ type T = Int }], LTT[{ type T <: AnyVal }])\n      assertChildStrict(LTT[{ type T = Int }], LTT[{ type T <: Any }])\n      assertChildStrict(LTT[{ type T = String }], LTT[{ type T <: CharSequence }])\n      assertChildStrict(LTT[{ def T: Int }], LTT[{ def T: AnyVal }])\n      assertChildStrict(LTT[{ type T = Int }], LTT[{ type T <: AnyVal }])\n\n      assertNotChild(LTT[{ type T = Int }], LTT[{ type T <: CharSequence }])\n      assertNotChildStrict(LTT[{ def T: Int }], LTT[{ type T }])\n    }\n\n    \"what about non-empty refinements with intersections\" in {\n      val ltt = LTT[Int with Object with Option[String] { def a: Boolean }]\n      val debug = ltt.debug()\n      assert(!debug.contains(\"<refinement>\"))\n      assert(!debug.contains(\"<none>\"))\n      assert(!debug.contains(\"* String\"))\n      assert(debug.contains(\"- java.lang.String\"))\n    }\n\n    \"support contravariance in refinement method comparisons\" in {\n      val t1 = LTT[{ def compare(a: AnyVal): Int }]\n      val t2 = LTT[{ def compare(b: Int): Int }]\n      assertChildStrict(t1, t2)\n    }\n\n    \"support human-readable representation\" in {\n      type TX[B] = Int { def a(k: String): Int; val b: String; type M1 = W1; type M2 <: W2; type M3[A] = Either[B, A] }\n      val txTag = `LTT[_]`[TX]\n      assert(\n        (txTag.toString // Scala 2\n          == \"λ %0 → (Int {def a(String): Int, def b(): String, type M1 = TestModel::W1, type M2 = M2|<Nothing..TestModel::W2>, type M3 = λ %2:0 → Either[+0,+2:0]})\")\n          || (txTag.toString // Dotty\n            == \"λ %0 → (Int {def a(String): Int, def b(): String, type M1 = TestModel::W1, type M2 = M2|<Nothing..TestModel::W2>, type M3 = λ %1:0 → Either[+0,+1:0]})\")\n      )\n      val txCombinedTag = `LTT[_]`[TX].combine(LTT[Unit])\n      assert(\n        (txCombinedTag.toString // Scala 2\n          == \"(Int {def a(String): Int, def b(): String, type M1 = TestModel::W1, type M2 = M2|<Nothing..TestModel::W2>, type M3 = λ %2:0 → Either[+Unit,+2:0]})\")\n          || (txCombinedTag.toString // Dotty\n            == \"(Int {def a(String): Int, def b(): String, type M1 = TestModel::W1, type M2 = M2|<Nothing..TestModel::W2>, type M3 = λ %1:0 → Either[+Unit,+1:0]})\")\n      )\n      val txUnitTag = LTT[TX[Unit]]\n      assert(\n        (txUnitTag.toString\n          == \"(Int {def a(String): Int, def b(): String, type M1 = TestModel::W1, type M2 = M2|<Nothing..TestModel::W2>, type M3 = λ %1:0 → Either[+Unit,+1:0]})\")\n          || (txUnitTag.toString\n            == \"(Int {def a(String): Int, def b(): String, type M1 = TestModel::W1, type M2 = M2|<Nothing..TestModel::W2>, type M3 = λ %0 → Either[+Unit,+0]})\")\n      )\n      assertRepr(LTT[I1 with (I1 with (I1 with W1))], \"{TestModel::I1 & TestModel::W1}\")\n      assertRepr(`LTT[_]`[R1], \"λ %0 → TestModel::R1[=0]\")\n      assertRepr(`LTT[_]`[Nothing], \"Nothing\")\n      assertRepr(LTT[Int], \"Int\")\n      assertRepr(LTT[List[Int]], \"List[+Int]\")\n      assertRepr(LTT[Id[Int]], \"Int\")\n      assertRepr(LTT[FP[Int]], \"List[+Int]\")\n      assertRepr(`LTT[_]`[L], \"λ %0 → List[+0]\")\n      assertRepr(`LTT[_]`[Either[Unit, *]], \"λ %0 → Either[+Unit,+0]\")\n      assertRepr(`LTT[_]`[S[Unit, *]], \"λ %0 → Either[+0,+Unit]\")\n    }\n\n    \"covariance of a concrete inheritor to a parent with a higher-kinded type parameter\" in {\n      trait Container[T] {\n        def tt(): T\n      }\n      final case class AContainer[T](t: T) extends Container[T] {\n        override def tt(): T = t\n      }\n\n      trait Service[+O[x] <: Container[x]] {\n        def giveHello: String\n      }\n      final case class MyConcreteService() extends Service[AContainer] {\n        def giveHello = \"Concrete hello!\"\n      }\n\n      assertChild(`LTT[_]`[AContainer], `LTT[_]`[Container])\n\n      assertChild(LTT[AContainer[Int]], LTT[Container[Int]])\n      assertChild(LTT[AContainer[Int]], LTT[Container[_]])\n      assertNotChild(LTT[AContainer[Int]], LTT[Container[Any]])\n\n      val concrete = LTT[MyConcreteService]\n      val parent = LTT[Service[Container]]\n      val appliedParent = `LTT[A[_],_[_[x] <: A[x]]`[Container, Service].combine(`LTT[_]`[Container])\n\n      assertChild(concrete, appliedParent)\n\n      implicitly[MyConcreteService <:< Service[Container]] // true\n\n      withSanityChecks {\n        assertChild(concrete, parent)\n      }\n    }\n\n    \"covariance of a concrete inheritor to a parent with a complex-shaped higher-kinded type parameter\" in {\n      trait Container[T] {\n        def tt(): T\n      }\n      final case class AContainer[T, Y](t: T) extends Container[T] {\n        override def tt(): T = t\n      }\n\n      trait Service[+O[x] <: Container[x]] {\n        def giveHello: String\n      }\n      final case class MyConcreteService() extends Service[AContainer[*, Int]] {\n        def giveHello = \"Concrete hello!\"\n      }\n\n      assertChild(`LTT[_]`[AContainer[*, Unit]], `LTT[_]`[Container])\n\n      assertChild(LTT[AContainer[Int, Unit]], LTT[Container[Int]])\n      assertChild(LTT[AContainer[Int, Unit]], LTT[Container[_]])\n      assertNotChild(LTT[AContainer[Int, Unit]], LTT[Container[Any]])\n\n      val concrete = LTT[MyConcreteService]\n      val parent = LTT[Service[Container]]\n      val appliedParent = `LTT[A[_],_[_[x] <: A[x]]`[Container, Service].combine(`LTT[_]`[Container])\n\n      assertChild(concrete, appliedParent)\n\n      implicitly[MyConcreteService <:< Service[Container]] // true\n\n      withSanityChecks {\n        assertChild(concrete, parent)\n      }\n    }\n\n    \"covariance of a concrete inheritor to a parent with a swap type lambda\" in {\n      trait Container[T, Y]\n      final case class AContainer[T, Y]() extends Container[Y, T]\n      type SwappedAContainer[T, Y] = AContainer[Y, T]\n\n      trait Service[+O[x, y] <: Container[x, y]] {\n        def giveHello: String\n      }\n      final case class MyConcreteService() extends Service[SwappedAContainer] {\n        def giveHello = \"Concrete hello!\"\n      }\n\n      assertChild(`LTT[_]`[AContainer[Int, *]], `LTT[_]`[Container[*, Int]])\n\n      assertChild(LTT[AContainer[Int, Unit]], LTT[Container[Unit, Int]])\n      assertChild(LTT[AContainer[Int, Unit]], LTT[Container[_, _]])\n      assertNotChild(LTT[AContainer[Int, Unit]], LTT[Container[Any, Any]])\n\n      val concrete = LTT[MyConcreteService]\n      val parent = LTT[Service[Container]]\n\n      implicitly[MyConcreteService <:< Service[Container]] // true\n\n      withSanityChecks {\n        assertChild(concrete, parent)\n      }\n    }\n\n    \"covariance of a concrete inheritor to a parent with a proper type parameter\" in {\n      trait Container {\n        def tt(): Any\n      }\n      final case class AContainer(t: Any) extends Container {\n        override def tt(): Any = t\n      }\n\n      trait Service[+O] {\n        def giveHello: String\n      }\n      final case class MyConcreteService() extends Service[AContainer] {\n        def giveHello = \"Concrete hello!\"\n      }\n      assertChild(LTT[AContainer], LTT[Container])\n\n      val concrete = LTT[MyConcreteService]\n      val parent = LTT[Service[Container]]\n\n      implicitly[MyConcreteService <:< Service[Container]] // true\n\n      assertChild(concrete, parent)\n    }\n\n    \"covariance of a parameterized inheritor to a parent with an indirect proper type parameter\" in {\n      trait Container {\n        def tt(): Any\n      }\n      final case class AContainer(t: Any) extends Container {\n        override def tt(): Any = t\n      }\n\n      trait Service[I, +O] {\n        def giveHello: String\n      }\n      final case class MyParameterizedService[T]() extends Service[T, AContainer] {\n        def giveHello = \"Concrete hello!\"\n      }\n      assertChild(LTT[AContainer], LTT[Container])\n\n      val concrete = LTT[MyParameterizedService[Int]]\n      val parent = LTT[Service[Int, Container]]\n\n      implicitly[MyParameterizedService[Int] <:< Service[Int, Container]] // true\n\n      assertChild(concrete, parent)\n    }\n\n    \"covariance of a parameterized inheritor to a parent with an indirect parameterized type parameter\" in {\n      trait Container[+T] {\n        def tt(): T\n      }\n      final case class AContainer[+T](t: T) extends Container[T] {\n        override def tt(): T = t\n      }\n\n      trait Service[I, +O] {\n        def giveHello: String\n      }\n      final case class MyParameterizedService[T]() extends Service[T, AContainer[Int]] {\n        def giveHello = \"Concrete hello!\"\n      }\n      assertChild(LTT[AContainer[Int]], LTT[Container[AnyVal]])\n\n      val concrete = LTT[MyParameterizedService[Int]]\n      val parent = LTT[Service[Int, Container[AnyVal]]]\n\n      implicitly[MyParameterizedService[Int] <:< Service[Int, Container[AnyVal]]] // true\n\n      assertChild(concrete, parent)\n    }\n\n    \"covariance of a parameterized inheritor to a parent with an indirect parameterized type parameter with different arity\" in {\n      trait Container[I, +T] {\n        def tt(): T\n      }\n      final case class AContainer[+T](t: T) extends Container[Int, T] {\n        override def tt(): T = t\n      }\n\n      trait Service[I, +O] {\n        def giveHello: String\n      }\n      final case class MyParameterizedService[T]() extends Service[T, AContainer[Int]] {\n        def giveHello = \"Concrete hello!\"\n      }\n      assertChild(LTT[AContainer[Int]], LTT[Container[Int, AnyVal]])\n\n      val concrete = LTT[MyParameterizedService[Int]]\n      val parent = LTT[Service[Int, Container[Int, AnyVal]]]\n\n      implicitly[MyParameterizedService[Int] <:< Service[Int, Container[Int, AnyVal]]] // true\n\n      assertChild(concrete, parent)\n    }\n\n    \"covariance of a self-parameterized inheritor to a parent with an indirect parameterized type parameter with different arity\" in {\n      trait Container[I, +T] {\n        def tt(): T\n      }\n      final case class AContainer[+T](t: T) extends Container[Int, T] {\n        override def tt(): T = t\n      }\n\n      trait Service[+I, +O] {\n        def giveHello: String\n      }\n      final case class MyParameterizedService[T]() extends Service[AContainer[T], AContainer[AContainer[T]]] {\n        def giveHello = \"Concrete hello!\"\n      }\n      val tag = LTT[AContainer[AContainer[Int]]]\n      val parent0 = LTT[Container[Int, Container[Int, AnyVal]]]\n\n      implicitly[AContainer[AContainer[Int]] <:< Container[Int, Container[Int, AnyVal]]]\n\n      assertChild(tag, parent0)\n\n      val concrete = LTT[MyParameterizedService[Int]]\n      val parent = LTT[Service[Container[Int, AnyVal], Container[Int, Any]]]\n\n      implicitly[MyParameterizedService[Int] <:< Service[Container[Int, AnyVal], Container[Int, Any]]] // true\n\n      assertChild(concrete, parent)\n    }\n\n    \"regression test for https://github.com/zio/izumi-reflect/issues/511\" in {\n      class Foo5[-A, B, -C, +DXX, +E]\n      class Foo10[F[_], +G[_], -H[-_, +_], I, +J[+_, +_], B, -A, -C, +E, +DXX] extends Foo5[A, B, C, DXX, E]\n\n      val tag1 = LTT[Foo5[Int, String, Double, Float, Long]]\n\n      assert(tag1.ref.isInstanceOf[FullReference])\n      assert(\n        tag1.ref.asInstanceOf[FullReference].parameters.map(_.variance)\n          == List(Variance.Contravariant, Variance.Invariant, Variance.Contravariant, Variance.Covariant, Variance.Covariant)\n      )\n\n      val tag2 = LTT[Foo10[Option, List, Function1, Boolean, Either, Int, String, Double, Float, Long]]\n\n      assert(tag2.ref.isInstanceOf[FullReference])\n      assert(\n        tag2.ref.asInstanceOf[FullReference].parameters.map(_.variance)\n          == List(\n            Variance.Invariant,\n            Variance.Covariant,\n            Variance.Contravariant,\n            Variance.Invariant,\n            Variance.Covariant,\n            Variance.Invariant,\n            Variance.Contravariant,\n            Variance.Contravariant,\n            Variance.Covariant,\n            Variance.Covariant\n          )\n      )\n    }\n\n    \"null type is supported\" in {\n      assertChildStrict(LTT[Null], LTT[I1])\n      assertChild(LTT[Nothing], LTT[Null])\n    }\n\n    \"fulldb should contain inheritance db of direct type argument\" in {\n      class Box[+T]\n\n      val lt = LTT[Box[Int]]\n      val fulldb = LightTypeTagUnpacker(lt).bases\n      assert(fulldb(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]) == Set(LTT[AnyVal].ref))\n    }\n\n    \"unapplied inheritance db should contain inheritance db of direct type argument\" in {\n      class Box[+T]\n\n      val lt = LTT[Box[Int]]\n      val inh = LightTypeTagUnpacker(lt).inheritance\n      assert(inh(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]) == Set(LTT[AnyVal].ref))\n    }\n\n    \"both dbs should contain db of direct self-nested type argument\" in {\n      class Box[+T]\n\n      val lt = LTT[Box[Box[Int]]]\n      val fulldb = LightTypeTagUnpacker(lt).bases\n      val inh = LightTypeTagUnpacker(lt).inheritance\n\n      assert(fulldb(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]) == Set(LTT[AnyVal].ref))\n      assert(inh(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]) == Set(LTT[AnyVal].ref))\n    }\n\n    \"fulldb should contain inheritance db of inherited type argument\" in {\n      class Box[+T]\n      class IndirectBox extends Box[Int]\n\n      val lt = LTT[IndirectBox]\n      val fulldb = LightTypeTagUnpacker(lt).bases\n      assert(fulldb.contains(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]))\n      assert(fulldb(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]) == Set(LTT[AnyVal].ref))\n    }\n\n    \"unapplied inheritance db should contain inheritance db of inherited type argument\" in {\n      class Box[+T]\n      class IndirectBox extends Box[Int]\n\n      val lt = LTT[IndirectBox]\n      val inh = LightTypeTagUnpacker(lt).inheritance\n\n      assert(inh.contains(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]))\n      assert(inh(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]) == Set(LTT[AnyVal].ref))\n    }\n\n    // Inheritance DB of parent itself is almost certainly not necessary for comparisons\n    // - if compared to a tag of parent type, that tag will already have a db for parent type.\n    \"both dbs should NOT contain inheritance db of direct parent type\" in {\n      case class CaseClass()\n\n      val lt = LTT[CaseClass]\n      val fulldb = LightTypeTagUnpacker(lt).bases\n      val inh = LightTypeTagUnpacker(lt).inheritance\n      val ltProduct = LTT[Product]\n      assert(!fulldb.contains(ltProduct.ref.asInstanceOf[LightTypeTagRef.NameReference]))\n      assert(!inh.contains(ltProduct.ref.asInstanceOf[LightTypeTagRef.NameReference]))\n    }\n\n    \"HKT List dbs should not contain superfluous base types\" in {\n      val lt = `LTT[_]`[List]\n      val fulldb = LightTypeTagUnpacker(lt).bases\n      val inh = LightTypeTagUnpacker(lt).inheritance\n\n      if (Scala2MinorVersion.scala2MinorVersion == 11 || Scala2MinorVersion.scala2MinorVersion == 12) {\n        assert(fulldb.keys.size == 4) // ParSeq + Seq\n        assert(inh.keys.size == 4)\n      } else {\n        assert(fulldb.keys.size == 2)\n        assert(inh.keys.size == 2)\n\n        assert(fulldb.keySet.contains(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]))\n        assert(inh.keySet.contains(LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]))\n\n        assert((fulldb.keySet - LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]).map(_.repr) == Set(\"λ %0 → scala.collection.immutable.List[+0]\"))\n        assert((inh.keySet - LTT[Int].ref.asInstanceOf[LightTypeTagRef.NameReference]).map(_.repr) == Set(\"scala.collection.immutable.List\"))\n      }\n    }\n\n    \"subtype check succeeds when child type has absorbed a covariant type parameter of the supertype\" in {\n      assertChild(LTT[Set[Int]], LTT[Iterable[AnyVal]])\n\n      val tagF3 = LTT[F3]\n      val tagF2 = LTT[F2[Int]]\n      assertChildStrict(tagF3, tagF2)\n      assertChildStrict(tagF3, LTT[F2[Any]])\n      assertChildStrict(tagF3, LTT[F2[AnyVal]])\n    }\n\n    \"regression test 3.0.4: subtype check succeeds versus a parent parameterized with Identity type lambda\" in {\n      val child = LTT[TargetRole]\n      val parent = LTT[AbstractRole[Id]]\n\n      assertChildStrict(child, parent)\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/SharedTagProgressionTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti._\nimport izumi.reflect.test.TestModel._\nimport izumi.reflect._\nimport izumi.reflect.test.PlatformSpecific.fromRuntime\nimport org.scalatest.exceptions.TestFailedException\nimport org.scalatest.wordspec.AnyWordSpec\n\nimport scala.util.Try\n\n/**\n  * The tests here are *progression* tests, that means they test that something *doesn't work*\n  *\n  * If a test here starts to fail that's a GOOD thing - that means a new feature is now supported.\n  * When that happens you can remove the `broken` condition inversions and move the test to\n  * the non-progression test suite.\n  *\n  * All tests must have `broken` clauses wrapping the expected GOOD conditions if a feature\n  * were to work. If a test is missing `broken` clause, it's a probably not a progression test\n  * anymore and should be moved.\n  */\nabstract class SharedTagProgressionTest extends AnyWordSpec with TagAssertions with TagProgressions with InheritedModel {\n\n  \"[progression] Tag (all versions)\" should {\n\n    \"progression test: can't substitute type parameters inside defs/vals in structural types\" in {\n      def t1[T: Tag]: Tag[{ def x: T }] = Tag[{ def x: T }]\n      def t2[T: Tag]: Tag[{ val x: T }] = Tag[{ val x: T }]\n\n      broken {\n        assertSameStrict(t1[Int].tag, Tag[{ def x: Int }].tag)\n      }\n      broken {\n        assertSameStrict(t2[Int].tag, Tag[{ val x: Int }].tag)\n      }\n    }\n\n    \"progression test: cannot resolve a higher-kinded type in a higher-kinded tag in a named deeply-nested type lambda on Scala 2\" in {\n      val t = Try(intercept[TestFailedException] {\n        assertCompiles(\n          \"\"\"\n    def mk[F[+_, +_]: TagKK] = TagKK[({ type l[A, B] = BIOServiceL[F, A, B] })#l]\n    val tag = mk[Either]\n\n    assert(tag.tag == LTagKK[({ type l[E, A] = BIOService[ ({ type l[X, Y] = Either[A, E] })#l ] })#l].tag)\n    \"\"\"\n        )\n      })\n      brokenOnScala2 {\n        assert(t.isFailure)\n      }\n    }\n\n    \"progression test: cannot resolve a higher-kinded type in a higher-kinded tag in an anonymous deeply-nested type lambda\" in {\n      val t = intercept[TestFailedException] {\n        assertCompiles(\n          \"\"\"\n      def mk[F[+_, +_]: TagKK] = TagKK[ ({ type l[E, A] = BIOService[ ({ type l[X, Y] = F[A, E] })#l ] })#l ]\n      val tag = mk[Either]\n\n      assert(tag.tag == LTagKK[ ({ type l[E, A] = BIOService[ ({ type l[X, Y] = Either[A, E] })#l ] })#l ].tag)\n      \"\"\"\n        )\n      }\n      assert(\n        t.getMessage.contains(\"could not find implicit value\") ||\n        t.getMessage.contains(\"diverging implicit\") || /*2.11*/\n        t.getMessage.contains(\"no implicit argument of type\") || /*Dotty*/\n        t.getMessage.contains(\"Cannot find implicit Tag\") /*Dotty 3.1.3+*/\n      )\n    }\n\n    \"progression test: projections into singletons are not handled properly (on Scala 2)\" in {\n      trait A {\n        class X\n\n        final val singleton1 = \"bar\"\n        type S1 = singleton1.type\n\n        val singleton2 = \"bar\"\n        type S2 = singleton2.type\n\n//        val s1a = Tag[S1] // class type required but String(\"bar\") found error on 2.11\n        val s1a = LTT[S1]\n        val s1a1 = Tag[singleton1.type].tag\n\n//        val s2a = Tag[S2]\n        val s2a = LTT[S2]\n        val s2a1 = Tag[singleton2.type].tag\n      }\n\n      trait B extends A {\n        val xb = Tag[X].tag\n\n//        val s1b = Tag[S1].tag\n        val s1b = LTT[S1]\n        val s1b1 = Tag[singleton1.type].tag\n\n        val s2b = LTT[S2]\n        val s2b1 = Tag[singleton2.type].tag\n      }\n\n      object B extends B\n\n      // Scala 2.12 doesn't handle literal types here\n      if (LTT[B.singleton1.type] != LTT[String] && !IsScala3) {\n        assertDifferent(Tag[A#S1].tag, LTT[String])\n      }\n      assertSame(Tag[A#S1].tag, B.s1a)\n      assertSame(Tag[A#S1].tag, B.s1a1)\n      assertSame(Tag[A#S1].tag, B.s1b)\n      assertSame(Tag[A#S1].tag, B.s1b1)\n\n      // progression: this still fails; see https://github.com/zio/izumi-reflect/issues/192\n      //  projection into singleton generates a form `_1.singleton2.type forSome { val _1: A }` which is not handled on Scala 2\n      brokenOnScala2 {\n        assertSame(Tag[A#S2].tag, B.s2a)\n      }\n      brokenOnScala2 {\n        assertSame(Tag[A#S2].tag, B.s2b)\n      }\n      brokenOnScala2 {\n        assertSame(Tag[A#S2].tag, B.s2a1)\n      }\n      brokenOnScala2 {\n        assertSame(Tag[A#S2].tag, B.s2b1)\n      }\n    }\n\n    \"Progression test: Scala 2 partially fails to Handle Tags outside of a predefined set when using TagX alias (Tag.auto.T works directly)\" in {\n      type TagX[F[_, _, _[_[_], _], _[_], _]] = Tag.auto.T[F]\n      brokenOnScala2 {\n        assertCompiles(\n          \"\"\"\n          def testTagX[F[_, _, _[_[_], _], _[_], _]: TagX, A: Tag, B: Tag, C[_[_], _]: TagTK, D[_]: TagK, E: Tag]: Tag[F[A, B, C, D, E]] = Tag[F[A, B, C, D, E]]\n             \"\"\"\n        )\n      }\n\n      def testTagXDirect[F[_, _, _[_[_], _], _[_], _]: Tag.auto.T, A: Tag, B: Tag, C[_[_], _]: TagTK, D[_]: TagK, E: Tag]: Tag[F[A, B, C, D, E]] = Tag[F[A, B, C, D, E]]\n      val value = testTagXDirect[TXU, Int, String, OptionT, List, Boolean]\n      assert(value.tag == fromRuntime[TXU[Int, String, OptionT, List, Boolean]])\n    }\n\n    \"progression test: fails to combine higher-kinded intersection types without losing ignored type arguments\" in {\n      def mk[F[+_, +_]: TagKK, G[+_, +_]: TagKK] = Tag[IntersectionBlockingIO[F, G]]\n      val tag = mk[Either, IO]\n      val tagMono = Tag[IntersectionBlockingIO[Either, IO]]\n\n      broken {\n        assertSameStrict(tag.tag, tagMono.tag)\n      }\n    }\n\n    \"progression test: Dotty fails to regression test: resolve correct closestClass for Scala vararg AnyVal (https://github.com/zio/izumi-reflect/issues/224)\" in {\n      val tag = Tag[VarArgsAnyVal]\n      brokenOnScala3 {\n        assert(tag.closestClass == classOf[scala.Seq[Any]])\n      }\n    }\n\n    \"progression test: fails to preserve lower bound when combining higher-kinded type members\" in {\n      def combine1[X[_[_], _]: TagTK, F[_]: TagK, A: Tag]: Tag[X[F, A]] = Tag[X[F, A]]\n      def combine2[F[_]: TagK, A: Tag]: Tag[F[A]] = Tag[F[A]]\n\n      val t1 = TagTK[HigherKindedTypeMember.T]\n      val t2 = TagK[HigherKindedTypeMember.T[IO[Throwable, *], *]]\n\n      val tres1 = combine1[HigherKindedTypeMember.T, IO[Throwable, *], Int](t1, implicitly, implicitly)\n      val tres2 = combine2[HigherKindedTypeMember.T[IO[Throwable, *], *], Int](t2, implicitly)\n\n      broken {\n        assertChildStrict(Tag[Unit].tag, tres1.tag)\n        assertChildStrict(Tag[Unit].tag, tres2.tag)\n      }\n    }\n\n    // Can't fix this atm because simplification happens even without .simplified call because of https://github.com/lampepfl/dotty/issues/17544\n    // The other way to fix this is to call `LightTypeTag.removeIntersectionTautologies` for every `Tag.refinedTag` -\n    // but this would make such tags expensive to construct because the complexity is quadratic, with two <:< calls\n    // per iteration.\n    \"progression test: fails on Scala 3 don't lose tautological intersection components other than Any/AnyRef\" in {\n      def tag1[T: Tag]: Tag[T with Trait1] = Tag[T with Trait1]\n      def tag4[T: Tag]: Tag[T with Trait4] = Tag[T with Trait4]\n\n      val t1 = tag1[Trait3[Dep]].tag\n      val t2 = tag4[Trait3[Dep]].tag\n\n      val t10 = Tag[Trait3[Dep] with Trait1].tag\n      val t20 = Tag[Trait3[Dep] with Trait4].tag\n\n      brokenOnScala3 {\n        assertSameStrict(t1, t10)\n        assertDebugSame(t1, t10)\n      }\n\n      assertSameStrict(t2, t20)\n      assertDebugSame(t2, t20)\n    }\n\n    // We don't really want to fix it, because removing tautologies is quadratic, with two subtyping comparisions per step!\n    // Would make construction really expensive, all for an extremely rare corner case\n    \"progression test: intersection tautologies are not removed automatically when constructing combined intersection type\" in {\n      def tag1[T: Tag]: Tag[T with Trait1] = Tag[T with Trait1]\n\n      val t1 = tag1[Trait3[Dep]].tag\n\n      val t10 = t1.removeIntersectionTautologies\n\n      broken {\n        assertSameStrict(t1, t10)\n        assertDebugSame(t1, t10)\n      }\n    }\n\n    \"progression test: null is treated like Nothing, not like a separate type\" in {\n      assert(LTT[Null] <:< LTT[Int])\n      assert(LTT[Null] <:< LTT[Nothing])\n    }\n\n    \"progression test: parameter resolution breaks inside covariant wildcard type bounds on Scala 2.13\" in {\n      def xcov[T[_]: TagK, U: Tag]: Tag[List[_ <: T[U]]] = Tag[List[_ <: T[U]]]\n\n      brokenOnScala2MinorVersion(13) {\n        assertRepr(xcov[List, Long].tag, \"List[+?: <Nothing..List[+Long]>]\")\n        assertSameStrict(xcov[List, Long].tag, Tag[List[_ <: List[Long]]].tag)\n      }\n    }\n\n    \"progression test: combine intersection path-dependent intersection types with inner tags doesn't work on Scala 2\" in {\n      trait PDT {\n        type T\n        implicit def tag: Tag[T]\n\n        def badCombine(that: PDT): Tag[T with that.T] = {\n          Tag[T with that.T]\n        }\n      }\n\n      brokenOnScala2 {\n        assertCompiles(\n          \"\"\"\n          trait PDT0 {\n            type T\n            implicit def tag: Tag[T]\n\n            def goodCombine(that: PDT): Tag[this.T with that.T] = {\n              import that.tag\n              Tag[this.T with that.T]\n            }\n          }\"\"\"\n        )\n      }\n\n      def PDT[U: Tag]: PDT = new PDT { type T = U; override val tag: Tag[U] = Tag[U] }\n\n      val badCombine = PDT[Int].badCombine(PDT[Unit])\n      brokenOnScala2 {\n        assertSameStrict(badCombine.tag, Tag[Int with Unit].tag)\n      }\n    }\n\n    \"progression test: `combine inside type lambdas where the type constructor of the type lambda result is a type lambda type parameter` doesn't work\" in {\n      val res = Try(assertCompiles(\"\"\"\n      def mk[T: Tag] = Tag[LambdaParamCtorBlockingIOT[T]]\n      val tag = mk[Int]\n      val tagMono = Tag[LambdaParamCtorBlockingIOT[Int]]\n\n      assertSameStrict(tag.tag, tagMono.tag)\n      \"\"\"))\n      broken {\n        assert(res.isSuccess)\n      }\n      broken {\n        assert(\n          !(res.failed.get.getMessage.contains(\"Error when creating a combined tag\")\n            || res.failed.get.getMessage.contains(\"could not find implicit value for izumi.reflect.Tag\"))\n        )\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/SharedTagTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti.LightTypeTag.ParsedLightTypeTag230Plus\nimport izumi.reflect.macrortti._\nimport izumi.reflect.test.ID._\nimport izumi.reflect.test.TestModel._\nimport izumi.reflect.thirdparty.internal.boopickle.PickleImpl\nimport izumi.reflect._\nimport izumi.reflect.test.DiscoveryModel.{DiscoverableService, DiscoverableServiceImpl, DiscoveryNodeProvider, GetDiscoveryNode, NodeIdImpl}\nimport izumi.reflect.test.TestModel.x.SrcContextProcessor\nimport org.scalatest.Assertions\nimport org.scalatest.exceptions.TestFailedException\nimport org.scalatest.wordspec.AnyWordSpec\n\nimport scala.annotation.StaticAnnotation\nimport scala.collection.immutable.Set\nimport scala.collection.mutable\nimport scala.util.Try\n\nobject ID {\n  type id[A] = A\n  type Identity[+A] = A\n}\n\ntrait Clock\nobject ClockLive extends Clock\n\ntrait ZY extends Assertions {\n  type T\n  type U = T\n  type V = List[T]\n  type A = List[Option[Int]]\n  type O <: List[T]\n  val x: String = \"5\"\n  object y\n  trait Y\n\n  val tagT = intercept[TestFailedException](assertCompiles(\"izumi.reflect.Tag[T]\"))\n  val tagU = intercept[TestFailedException](assertCompiles(\"izumi.reflect.Tag[U]\"))\n  val tagV = intercept[TestFailedException](assertCompiles(\"izumi.reflect.Tag[V]\"))\n  val tagA = Try(assertCompiles(\"izumi.reflect.Tag[A]\"))\n}\n\ntrait XY[Y] {\n  type Z = id[Y]\n\n  implicit def tagZ: Tag[Z]\n}\n\ncase class OptionT[F[_], A](value: F[Option[A]])\n\nfinal case class testTag[T: Tag]() {\n  type X[A] = Either[Int, A]\n  type Y = T\n  val res = Tag[X[Y {}]]\n}\n\nfinal case class testTag2[T: Tag]() {\n  type X = List[T]\n  val res = Tag[X]\n}\n\ntrait TXU[A, B, C[_[_], _], D[_], E]\n\nabstract class SharedTagTest extends AnyWordSpec with XY[String] with TagAssertions with InheritedModel {\n\n  type Abstract\n  type Id[A] = A\n  type Id1[F[_], A] = F[A]\n\n  import izumi.reflect.test.PlatformSpecific.fromRuntime\n\n  final val str = \"str\"\n\n  final class With[T] extends StaticAnnotation\n\n  case class ZOBA[A, B, C](value: Either[B, C])\n\n  trait Test[A, dafg, adfg, LS, L[_], SD, GG[B] <: L[B], ZZZ[_, _], S, SDD, TG]\n  trait T1[A, B, C, D, E, F[_]]\n  trait YX[V] extends XY[V]\n\n  trait DockerContainer[T]\n  trait ContainerDef {\n    type T\n\n    def make(implicit t: Tag[T]) = {\n      val _ = t\n      Tag[DockerContainer[T]]\n    }\n  }\n\n  \"Tag (all versions)\" should {\n\n    \"Work for any concrete type\" in {\n      assert(Tag[Int].tag == fromRuntime[Int])\n      assert(Tag[Set[String]].tag == fromRuntime[Set[String]])\n      assert(Tag[Map[Boolean, Double]].tag == fromRuntime[Map[Boolean, Double]])\n      assert(Tag[_ => Unit].tag == fromRuntime[_ => Unit])\n      assert(Tag[Unit => _].tag == fromRuntime[Unit => _])\n      assert(Tag[_ => _].tag == fromRuntime[_ => _])\n\n      assert(Tag[Any].tag == fromRuntime[Any])\n      assert(Tag[Nothing].tag == fromRuntime[Nothing])\n      assert(Tag[Any => Nothing].tag == fromRuntime[Any => Nothing])\n      assert(Tag[Nothing => Any].tag == fromRuntime[Nothing => Any])\n\n      assert(Tag[With[Any]].tag == fromRuntime[With[Any]])\n      assert(Tag[With[Nothing]].tag == fromRuntime[With[Nothing]])\n      assert(Tag[With[_]].tag == fromRuntime[With[_]])\n\n      assert(Tag[Int with String].tag == fromRuntime[Int with String])\n\n      assert(Tag[str.type].tag == fromRuntime[str.type])\n\n      assert(Tag[this.Z].tag == fromRuntime[this.Z])\n      assert(Tag[TagTest#Z].tag == fromRuntime[TagTest#Z])\n    }\n\n    \"Support identity lambda type equality\" in {\n      val idTpeLTT = TagK[Identity].tag\n      val idLambdaLTT = TagK[λ[A => A]].tag\n      assert(idTpeLTT == idLambdaLTT)\n    }\n\n    \"regression test for https://github.com/zio/izumi-reflect/issues/98\" in {\n      object SomeService {\n        trait Service[T]\n\n        final case class Foo()\n\n        val tag1: Tag[Service[Foo]] = Tag[Service[Foo]]\n      }\n\n      object IzumiReflectTagEqualRegression {\n        import SomeService._\n\n        def test(): Unit = {\n          val tag1: Tag[Service[Foo]] = SomeService.tag1\n          val tag2: Tag[Service[Foo]] = Tag[Service[Foo]]\n\n          val rtTag1 = PickleImpl.serializeIntoString(tag1.tag.ref, LightTypeTag.lttRefSerializer)\n          val rtTag2 = PickleImpl.serializeIntoString(tag2.tag.ref, LightTypeTag.lttRefSerializer)\n\n          assert(tag1.tag.ref == tag2.tag.ref)\n\n          assert(rtTag1 == tag1.tag.asInstanceOf[ParsedLightTypeTag230Plus].refString)\n          assert(rtTag2 == tag2.tag.asInstanceOf[ParsedLightTypeTag230Plus].refString)\n\n          assert(rtTag1 == rtTag2)\n\n          assert(tag1.tag == tag2.tag)\n          ()\n        }\n      }\n\n      IzumiReflectTagEqualRegression.test()\n    }\n\n    \"Work for any abstract type with available Tag when obscured by empty refinement\" in {\n      def testTag[T: Tag] = Tag[T {}]\n\n      assert(testTag[String].tag == fromRuntime[String])\n    }\n\n    \"handle function local type aliases\" in {\n\n      def testTag[T: Tag] = {\n        type X[A] = Either[Int, A]\n\n        Tag[X[T {}]]\n      }\n\n      assert(testTag[String].tag == fromRuntime[Either[Int, String]])\n\n      def testTag2[T: Tag] = {\n        type X = List[T]\n\n        Tag[X]\n      }\n\n      assert(testTag2[String].tag == fromRuntime[List[String]])\n\n      def testTag3[F[_]: TagK] = {\n        type X = OptionT[F, Int]\n\n        Tag[X]\n      }\n\n      assert(testTag3[List].tag == fromRuntime[OptionT[List, Int]])\n    }\n\n    \"Can dealias transparent type members with class type parameters inside them when a tag is summoned _inside_ the class, because LightTypeTags are not affected by https://github.com/scala/bug/issues/11139\" in {\n      assert(testTag[String]().res.tag == fromRuntime[Either[Int, String]])\n      assert(testTag2[String]().res.tag == fromRuntime[List[String]])\n      assert(testTag3[List]().res == fromRuntime[OptionT[List, Int]])\n    }\n\n    \"Tag.auto.T kind inference macro works for known cases\" in {\n      def x[T[_]: Tag.auto.T]: TagK[T] = implicitly[Tag.auto.T[T]]\n\n      def x2[T[_, _]: Tag.auto.T]: TagKK[T] = implicitly[Tag.auto.T[T]]\n\n      def x3[T[_, _, _[_[_], _], _[_], _]](implicit x: Tag.auto.T[T]): Tag.auto.T[T] = x\n\n      val b1 = x[Option].tag =:= TagK[Option].tag\n      val b2 = x2[Either].tag =:= TagKK[Either].tag\n      val b3 = implicitly[Tag.auto.T[OptionT]].tag =:= TagTK[OptionT].tag\n      val b4 = x3[TXU].tag.withoutArgs =:= LTag[TXU[Nothing, Nothing, Nothing, Nothing, Nothing]].tag.withoutArgs\n\n      assert(b1)\n      assert(b2)\n      assert(b3)\n      assert(b4)\n    }\n\n    \"support HKTag for unapplied type lambdas with type bounds\" in {\n      trait X\n      trait XAble[A <: X]\n      class Y extends X\n\n      def getTag[F[A <: X]: Tag.auto.T] = {\n        val _ = implicitly[Tag.auto.T[F]]\n        Tag[F[Y]]\n      }\n\n      val tag = getTag[XAble]\n      assert(tag.tag == Tag[XAble[Y]].tag)\n    }\n\n    \"support Tag.auto.T for higher-kinded type lambdas with interdependent inner and outer type bounds\" in {\n      class Dep0\n      trait Trait30[T <: Dep0]\n      trait TraitK30[T[x <: Dep0] <: Trait30[x]]\n\n      def t[K[F[x <: Dep0] <: Trait30[x]]: Tag.auto.T, T[x <: Dep0] <: Trait30[x]: Tag.auto.T] = Tag[K[T]]\n\n      assert(t[TraitK30, Trait30].tag == Tag[TraitK30[Trait30]].tag)\n    }\n\n    \"Shouldn't work for any abstract type without available TypeTag or Tag or TagK\" in {\n      assertTypeError(\"\"\"\n      def testTag[T] = Tag[T]\n      def testTagK[F[_], T] = Tag[F[T]]\n         \"\"\")\n    }\n\n    \"handle Id type lambda\" in {\n      assert(TagK[Id].tag == TagK[Id].tag)\n      assert(TagK[Id].tag != TagTK[Id1].tag)\n    }\n\n    \"handle Id1 type lambda\" in {\n      assert(TagTK[Id1].tag == TagTK[Id1].tag)\n      assert(TagTK[Id1].tag != TagK[Id].tag)\n    }\n\n    \"handle singleton types\" in {\n      assertChild(Tag[ClockLive.type].tag, Tag[Clock].tag)\n    }\n\n    \"handle nested intersection aliases\" in {\n      type Inner = Int with String\n      type Outer = Boolean with Inner\n      assertChild(Tag[Outer].tag, Tag[Boolean with Int with String].tag)\n      assertChild(Tag[Boolean with Int with String].tag, Tag[Outer].tag)\n      assertSame(Tag[Outer].tag, Tag[Boolean with Int with String].tag)\n\n      assertNotChild(Tag[Outer].tag, Tag[Boolean with Int with String with Unit].tag)\n      assertNotChild(Tag[Boolean with Int with String].tag, Tag[Outer with Unit].tag)\n\n      assertChild(Tag[Boolean with Int with String].tag, Tag[CharSequence].tag)\n      assertChild(Tag[Outer].tag, Tag[CharSequence].tag)\n\n      // there should be no refinements or intersections in bases\n      assert(!Tag[Outer].tag.debug().contains(\"<refinement>\"))\n      assert(!Tag[Outer].tag.debug().contains(\"<none>\"))\n      assert(!Tag[Outer].tag.debug().contains(\"- {\"))\n    }\n\n    \"handle nested refined intersection aliases\" in {\n      type Inner = ((Int with (String {})) {}) @IdAnnotation(\"y\")\n      type Outer = Boolean with (((Inner {}) @IdAnnotation(\"x\")) {})\n      assertChild(Tag[Outer].tag, Tag[Boolean with Int with String].tag)\n      assertChild(Tag[Boolean with Int with String].tag, Tag[Outer].tag)\n      assertSame(Tag[Outer].tag, Tag[Boolean with Int with String].tag)\n\n      assertNotChild(Tag[Outer].tag, Tag[Boolean with Int with String with Unit].tag)\n      assertNotChild(Tag[Boolean with Int with String].tag, Tag[Outer with Unit].tag)\n\n      assertChild(Tag[Outer].tag, Tag[CharSequence].tag)\n\n      // there should be no refinements or intersections in bases\n      assert(!Tag[Outer].tag.debug().contains(\"<refinement>\"))\n      assert(!Tag[Outer].tag.debug().contains(\"<none>\"))\n      assert(!Tag[Outer].tag.debug().contains(\"- {\"))\n    }\n\n    \"simple combined Tag\" in {\n      def get[F[_]: TagK] = Tag[ApplePaymentProvider[F]]\n      val tag = get[Identity]\n\n      val left = tag.tag\n      val right = Tag[H1].tag\n\n      assertChild(left, right)\n    }\n\n    \"consider class member's this-prefix to be the defining template, not the most specific prefix from where the call is happening (deliberate omission of this for better ergonomics in cakes)\" in {\n      trait A {\n        class X\n\n        final val singleton1 = \"bar\"\n        type S1 = singleton1.type\n\n        val singleton2 = \"bar\"\n        type S2 = singleton2.type\n\n        val xa = Tag[X].tag\n\n//        val s1a = Tag[S1] // class type required but String(\"bar\") found error on 2.11\n        val s1a = LTT[S1]\n        val s1a1 = Tag[singleton1.type].tag\n\n//        val s2a = Tag[S2]\n        val s2a = LTT[S2]\n        val s2a1 = Tag[singleton2.type].tag\n      }\n\n      trait B extends A {\n        val xb = Tag[X].tag\n\n//        val s1b = Tag[S1].tag\n        val s1b = LTT[S1]\n        val s1b1 = Tag[singleton1.type].tag\n\n        val s2b = LTT[S2]\n        val s2b1 = Tag[singleton2.type].tag\n      }\n\n      object B extends B\n\n      assertSameStrict(B.xa, B.xb)\n      assertSameStrict(B.s1a, B.s1b)\n      assertSameStrict(B.s1a1, B.s1b1)\n      assertSameStrict(B.s2a, B.s2b)\n      assertSameStrict(B.s2a1, B.s2b1)\n\n      assertSameStrict(Tag[A#X].tag, B.xa)\n\n      assertSameStrict(B.s1b, B.s1a)\n      assertSameStrict(B.s1a, B.s1a1)\n      assertSameStrict(B.s1b, B.s1b1)\n    }\n\n    \"Does NOT synthesize Tags for abstract types, but recursively summons Tag[this.Abstract]\" in {\n      // no tag synthesized, there's no Tag[Abstract] unless defined\n      assertDoesNotCompile(\"Tag[Abstract]\")\n      locally {\n        implicit val implicitTag: Tag[Abstract] = Tag[Abstract](Tag[Int].closestClass, Tag[Int].tag)\n        val tag = Tag[Option[Abstract]]\n        assertSameStrict(tag.tag.typeArgs.head, implicitTag.tag)\n        assertSameStrict(tag.tag, TagK[Option].tag.combine(implicitTag.tag))\n      }\n    }\n\n    \"DOES synthesize Tags for abstract types (object X; X.T), does not summon Tag[X.T]\" in {\n      val realTag = Tag[Option[SomeObject.Abstract]]\n      locally {\n        implicit val implicitTag: Tag[SomeObject.Abstract] = Tag[SomeObject.Abstract](Tag[Int].closestClass, Tag[Int].tag)\n        val tag = Tag[Option[SomeObject.Abstract]]\n        assertDifferent(tag.tag.typeArgs.head, implicitTag.tag)\n        assertDifferent(tag.tag, TagK[Option].tag.combine(implicitTag.tag))\n        assertSameStrict(realTag.tag, tag.tag)\n      }\n    }\n\n    \"DOES synthesize Tags for abstract types (trait X; X#T), does not summon Tag[X#T]\" in {\n      val realTag = Tag[Option[SomeTrait#Abstract]]\n      locally {\n        implicit val implicitTag: Tag[SomeTrait#Abstract] = Tag[SomeTrait#Abstract](Tag[Int].closestClass, Tag[Int].tag)\n        val tag = Tag[Option[SomeTrait#Abstract]]\n        assertDifferent(tag.tag.typeArgs.head, implicitTag.tag)\n        assertDifferent(tag.tag, TagK[Option].tag.combine(implicitTag.tag))\n        assertSameStrict(realTag.tag, tag.tag)\n      }\n    }\n\n    \"DOES synthesize Tags for abstract types (val x; x.T), does not summon Tag[x.T]\" in {\n      val x = new SomeTrait {}\n      val realTag = Tag[Option[x.Abstract]]\n      locally {\n        implicit val implicitTag: Tag[x.Abstract] = Tag[x.Abstract](Tag[Int].closestClass, Tag[Int].tag)\n        val tag = Tag[Option[x.Abstract]]\n        assertDifferent(tag.tag.typeArgs.head, implicitTag.tag)\n        assertDifferent(tag.tag, TagK[Option].tag.combine(implicitTag.tag))\n        assertSameStrict(realTag.tag, tag.tag)\n      }\n    }\n\n    \"Work for an abstract type with available TagK when obscured by empty refinement\" in {\n      def testTagK[F[_]: TagK, T: Tag] = Tag[F[T {}] {}]\n\n      assert(testTagK[Set, Int].tag == fromRuntime[Set[Int]])\n    }\n\n    \"Work for an abstract type with available TagK when TagK is requested through an explicit implicit\" in {\n      def testTagK[F[_], T: Tag](implicit ev: Tag.auto.T[F]) = {\n        val _ = ev\n        Tag[F[T {}] {}]\n      }\n\n      assert(testTagK[Set, Int].tag == fromRuntime[Set[Int]])\n    }\n\n    \"Work for an abstract type with available TagKK\" in {\n      def t1[F[_, _]: TagKK, T: Tag, G: Tag] = Tag[F[T, G]]\n\n      assert(t1[ZOBA[Int, *, *], Int, String].tag == fromRuntime[ZOBA[Int, Int, String]])\n    }\n\n    \"Work for any configuration of parameters\" in {\n      def t1[A: Tag, B: Tag, C: Tag, D: Tag, E: Tag, F[_]: TagK]: Tag[T1[A, B, C, D, E, F]] = Tag[T1[A, B, C, D, E, F]]\n\n      type ZOB[A, B, C] = Either[B, C]\n\n      assert(\n        t1[Int, Boolean, ZOB[Unit, Int, Int], TagK[Option], Nothing, ZOB[Unit, Int, *]].tag\n          == fromRuntime[T1[Int, Boolean, Either[Int, Int], TagK[Option], Nothing, Either[Int, *]]]\n      )\n\n      def t2[A: Tag, dafg: Tag, adfg: Tag, LS: Tag, L[_]: TagK, SD: Tag, GG[A] <: L[A]: TagK, ZZZ[_, _]: TagKK, S: Tag, SDD: Tag, TG: Tag]\n        : Tag[Test[A, dafg, adfg, LS, L, SD, GG, ZZZ, S, SDD, TG]] =\n        Tag[Test[A, dafg, adfg, LS, L, SD, GG, ZZZ, S, SDD, TG]]\n\n      assert(\n        t2[\n          SharedTagTest.this.Z,\n          SharedTagTest.this.Z,\n          T1[\n            ZOB[String, Int, Byte],\n            String,\n            String,\n            String,\n            String,\n            List\n          ],\n          SharedTagTest.this.Z,\n          XY,\n          SharedTagTest.this.Z,\n          YX,\n          Either,\n          SharedTagTest.this.Z,\n          SharedTagTest.this.Z,\n          SharedTagTest.this.Z\n        ].tag\n          == fromRuntime[Test[String, String, T1[Either[Int, Byte], String, String, String, String, List], String, XY, String, YX, Either, String, String, String]]\n      )\n    }\n\n    \"handle Swap type lambda\" in {\n      def t1[F[_, _]: TagKK, A: Tag, B: Tag] = Tag[F[A, B]]\n\n      assert(t1[Swap, Int, String].tag == fromRuntime[Either[String, Int]])\n    }\n\n    \"Assemble from higher than TagKK tags\" in {\n      def tag[T[_[_], _]: TagTK, F[_]: TagK, A: Tag] = Tag[T[F, A]]\n\n      assert(tag[OptionT, Option, Int].tag == fromRuntime[OptionT[Option, Int]])\n    }\n\n    \"regression test: https://github.com/zio/izumi-reflect/issues/293 assemble tag for Builder[B, Collection[B]]\" in {\n      def tag[B: Tag](implicit tag: Tag[java.util.Collection[B]]) = Tag[mutable.Builder[B, java.util.Collection[B]]]\n\n      assertSameStrict(tag[Int].tag, Tag[mutable.Builder[Int, java.util.Collection[Int]]].tag)\n    }\n\n    \"combine intersection types\" in {\n      def t1[A: Tag] = Tag[String with A]\n      def t2[A: Tag, B: Tag] = Tag[A with B]\n\n      assertSameStrict(t1[Int].tag, Tag[Int with String].tag)\n      assertSameStrict(t2[Int, String].tag, Tag[String with Int].tag)\n      assertSameStrict(t1[String].tag, Tag[String].tag)\n      assertSameStrict(t2[String, String].tag, Tag[String].tag)\n    }\n\n    \"summon HKT Tag for a Java type\" in {\n      assertCompiles(\"TagK[java.util.Collection]\")\n    }\n\n    \"regression test: https://github.com/zio/izumi-reflect/issues/76 derive tag for a parametric trait inside object\" in {\n      assertSameStrict(X76.x.tag, Tag[X76.T[Int]].tag)\n    }\n\n    \"this.type tags should be generated, but are identical with their class / object tag\" in {\n      val classTag = Tag[ThisPrefixTest.ThisPrefix].tag\n      val objectTag = Tag[ThisPrefixTest.ThisPrefix.type].tag\n      val classThisTag = new ThisPrefixTest.ThisPrefix().tag\n      val objectThisTag = ThisPrefixTest.ThisPrefix.tag\n\n      assertDebugSame(classThisTag, classTag)\n      assertDebugSame(objectThisTag, objectTag)\n\n      assertNotChildStrict(classTag, objectTag)\n      assertNotChildStrict(classTag, objectThisTag)\n      assertNotChildStrict(classThisTag, objectTag)\n      assertNotChildStrict(classThisTag, objectThisTag)\n    }\n\n    \"this.type should have correct prefix\" in {\n      val classTag = Tag[ThisPrefixTest.ThisPrefix].tag\n      val objectTag = Tag[ThisPrefixTest.ThisPrefix.type].tag\n      val classThisTag = new ThisPrefixTest.ThisPrefix().tag\n      val objectThisTag = ThisPrefixTest.ThisPrefix.tag\n\n      assert(classTag.ref.getPrefix.isDefined)\n      assert(objectTag.ref.getPrefix.isDefined)\n      assert(classThisTag.ref.getPrefix.isDefined)\n      assert(objectThisTag.ref.getPrefix.isDefined)\n\n      assert(classTag.ref.getPrefix == objectTag.ref.getPrefix)\n      assert(classTag.ref.getPrefix == classThisTag.ref.getPrefix)\n      assert(classTag.ref.getPrefix == objectThisTag.ref.getPrefix)\n    }\n\n    \"regression test: https://github.com/zio/izumi-reflect/issues/83, convert trifunctor tag to bifunctor tag\" in {\n      import TestModel._\n      def direct[F[+_, +_]: TagKK] = Tag[BIO2[F]]\n      def indirectFrom3[F[-_, +_, +_]: TagK3] = direct[F[Any, +*, +*]]\n      assertSame(direct[ZIO[Any, +*, +*]].tag, indirectFrom3[ZIO].tag)\n    }\n\n    \"resolve TagK from TagKK\" in {\n      def getTag[F[+_, +_]: TagKK] = TagK[F[Throwable, *]]\n      val tagEitherThrowable = getTag[Either].tag\n      val tag = TagK[Either[Throwable, *]].tag\n\n      assertSameStrict(tagEitherThrowable, tag)\n      assertChildStrict(tagEitherThrowable, TagK[Either[Any, *]].tag)\n      assertChildStrict(TagK[Either[Nothing, *]].tag, tagEitherThrowable)\n    }\n\n    \"can materialize TagK for type lambdas that close on a generic parameter with available Tag\" in {\n      def partialEitherTagK[A: Tag] = TagK[Either[A, *]]\n\n      val tag = partialEitherTagK[Int].tag\n      val expectedTag = TagK[Either[Int, *]].tag\n\n      assert(tag =:= expectedTag)\n    }\n\n    \"can materialize TagK for type lambdas that close on a generic parameter with available Tag when the constructor is a type parameter\" in {\n      def partialFTagK[F[_, _]: TagKK, A: Tag] = TagK[F[A, *]]\n\n      val tag = partialFTagK[Either, Int].tag\n      val expectedTag = TagK[Either[Int, *]].tag\n\n      assert(tag =:= expectedTag)\n    }\n\n    \"type parameter covariance works after combine\" in {\n      def getTag[F[+_, +_]: TagKK] = TagK[F[Throwable, *]]\n      val tagEitherThrowable = getTag[Either].tag\n      val tagEitherSerializable = TagK[Either[java.io.Serializable, *]]\n      assert(tagEitherThrowable <:< tagEitherSerializable.tag)\n    }\n\n    \"combine Const Lambda to TagK\" in {\n      def get[F[_, _]: TagKK] = TagK[F[Int, *]]\n      val tag = get[Const]\n\n      assert(tag.tag =:= TagK[Const[Int, *]].tag)\n      assert(tag.tag <:< TagK[Const[AnyVal, *]].tag)\n      assert(tag.tag.hashCode() == TagK[Const[Int, *]].tag.hashCode())\n    }\n\n    \"combined TagK 3 & 2 parameter coherence\" in {\n      def get[F[+_, +_]: TagKK] = TagK[F[Throwable, *]]\n      val tag = get[IO]\n\n      assert(tag.tag =:= TagK[IO[Throwable, *]].tag)\n      assert(tag.tag <:< TagK[IO[Throwable, *]].tag)\n      assert(tag.tag <:< TagK[IO[Any, *]].tag)\n    }\n\n    \"resolve TagKK from an odd higher-kinded Tag with swapped & ignored parameters\" in {\n      def getTag[F[-_, +_, +_]: TagK3] = TagKK[F[*, *, Throwable]]\n      val tagEitherSwap = getTag[EitherRSwap].tag\n      val tagEitherThrowable = getTag[EitherR].tag\n\n      val expectedTagSwap = TagKK[EitherRSwap[*, *, Throwable]].tag\n      val expectedTagEitherThrowable = TagKK[EitherR[*, *, Throwable]].tag\n\n      assert(!(tagEitherSwap =:= expectedTagEitherThrowable))\n      assert(tagEitherSwap =:= expectedTagSwap)\n      assert(tagEitherThrowable =:= expectedTagEitherThrowable)\n      assert(tagEitherSwap <:< expectedTagSwap)\n      assert(tagEitherSwap <:< TagKK[EitherRSwap[*, *, Any]].tag)\n      assert(TagKK[EitherRSwap[*, *, Nothing]].tag <:< tagEitherSwap)\n    }\n\n    \"can resolve Tags of TagK's themselves correctly\" in {\n      trait X[A, B, C]\n\n      def tagk[F[_]: TagK]: Tag[TagK[F]] = Tag[TagK[F]]\n      def tagkk[F[_, _]: TagKK]: Tag[TagKK[F]] = Tag[TagKK[F]]\n      def tagk3[F[_, _, _]: TagK3]: Tag[TagK3[F]] = Tag[TagK3[F]]\n      def tagtk[F[_[_], _]: TagTK]: Tag[TagTK[F]] = Tag[TagTK[F]]\n\n      assertChild(tagk[List].tag, Tag[TagK[List]].tag)\n      assertSame(tagkk[Either].tag, Tag[TagKK[Either]].tag)\n      assertSame(tagk3[X].tag, Tag[TagK3[X]].tag)\n      assertSame(tagtk[OptionT].tag, Tag[TagTK[OptionT]].tag)\n    }\n\n    \"regression test: ignore function-local anonymous classes (https://github.com/zio/zio/issues/4285)\" in {\n      class ZIO[-R, +E, +A](val a: Any) {\n        def map[B](f: A => B): ZIO[R, E, B] = new ZIO(f)\n        def toLayer[A1 >: A: Tag]: ZLayer[R, E, Has[A1]] = new ZLayer(Tag[Has[A1]])\n      }\n      class ZLayer[-R, +E, +A](val t: Tag[_ <: A])\n      final class Has[X]\n\n      type UIO[T] = ZIO[Any, Nothing, T]\n      def f[T]: UIO[T] = new ZIO(1)\n      trait S[T] {\n        val param: T\n      }\n\n      def reproduce[T: Tag]: ZLayer[Any, Nothing, Has[S[T]]] = {\n        f[T]\n          .map(\n            p =>\n              new S[T] {\n                override val param: T = p\n              }\n          ).toLayer\n      }\n\n      assert(reproduce[Unit].t.tag == Tag[Has[S[Unit]]].tag)\n    }\n\n    \"equal path-dependent tags for singleton types are expected to be equal\" in {\n      // see https://github.com/zio/izumi-reflect/issues/192\n      object Foo {\n        val bar = \"bar\"\n        object Bar\n\n        val t1 = Tag[bar.type]\n        val t2 = Tag[Foo.bar.type]\n        val t3 = Tag[Foo.this.bar.type]\n\n        val T1 = Tag[Bar.type]\n        val T2 = Tag[Foo.Bar.type]\n        val T3 = Tag[Foo.this.Bar.type]\n      }\n\n      import Foo._\n      assert(t1.tag =:= t3.tag)\n      assert(t2.tag =:= t3.tag)\n\n      assert(T1.tag =:= T3.tag)\n      assert(T2.tag =:= T3.tag)\n    }\n\n    \"return expected class tag\" in {\n      assert(Tag[List[_] with Set[_]].closestClass eq classOf[scala.collection.immutable.Iterable[_]])\n      assert(!Tag[List[_] with Set[_]].hasPreciseClass)\n\n      assert(Tag[AnyVal].closestClass eq classOf[AnyVal])\n      assert(!Tag[AnyVal].hasPreciseClass)\n\n      assert(Tag[String].closestClass ne classOf[AnyVal])\n      assert(!Tag[String with Int].hasPreciseClass)\n      assert(Tag[String with Int].closestClass eq classOf[Any])\n\n      assert(Tag[List[Int]].hasPreciseClass)\n      assert(Tag[List[Int]].closestClass eq classOf[List[_]])\n\n      assert(Tag[H1].hasPreciseClass)\n      assert(Tag[H1].closestClass eq classOf[H1])\n\n      assert(!Tag[ZY#T].hasPreciseClass)\n      assert(Tag[ZY#T].closestClass eq classOf[Any])\n\n      assert(Tag[ZY#Y].hasPreciseClass)\n      assert(Tag[ZY#Y].closestClass eq classOf[ZY#Y])\n\n      assert(!Tag[ZY#O].hasPreciseClass)\n      assert(Tag[ZY#O].closestClass eq classOf[List[ZY#T]])\n\n      assert(Tag[Array[Byte]].closestClass eq classOf[Array[Byte]])\n      assert(Tag[Array[Int]].closestClass eq classOf[Array[Int]])\n      assert(Tag[Array[AnyRef]].closestClass eq classOf[Array[AnyRef]])\n      assert(Tag[Array[Boolean]].closestClass eq classOf[Array[Boolean]])\n      assert(Tag[Array[Char]].closestClass eq classOf[Array[Char]])\n      assert(Tag[Array[String]].closestClass eq classOf[Array[String]])\n      assert(Tag[Array[List[Any]]].closestClass eq classOf[Array[List[Any]]])\n\n      object test1 {\n        sealed trait TX0\n        class TX1 extends TX0\n        class TX2 extends TX0\n        class TX3 extends TX0\n\n        type OX[T] = TX1 with TX2 with T\n      }\n\n      assert(!Tag[test1.OX[ZY#Y]].hasPreciseClass)\n      assert(!Tag[test1.OX[test1.TX3]].hasPreciseClass)\n      assert(!Tag[test1.OX[test1.TX0]].hasPreciseClass)\n      assert(Tag[test1.OX[ZY#Y]].closestClass eq classOf[Any])\n      assert(Tag[test1.OX[test1.TX3]].closestClass eq classOf[test1.TX0])\n      assert(Tag[test1.OX[test1.TX0]].closestClass eq classOf[test1.TX0])\n\n      object test2 {\n        type ArrayT <: Array[Byte]\n      }\n      assert(!Tag[test2.ArrayT].hasPreciseClass)\n      assert(Tag[test2.ArrayT].closestClass eq classOf[Array[Byte]])\n    }\n\n    \"Work with term type prefixes\" in {\n      val zy = new ZY {}\n      val zx = new ZY {}\n\n      assertSameStrict(Tag[zy.T].tag, LTT[zy.T])\n      assertNotChildStrict(Tag[zy.T].tag, LTT[zx.T])\n      assertSameStrict(Tag[zy.x.type].tag, LTT[zy.x.type])\n      assertChild(Tag[zy.x.type].tag, LTT[String])\n      assertChild(Tag[zy.x.type].tag, LTT[java.io.Serializable])\n      assertNotChildStrict(Tag[zy.x.type].tag, LTT[zx.x.type])\n      assertSameStrict(Tag[zy.y.type].tag, LTT[zy.y.type])\n      assertChild(Tag[zy.y.type].tag, LTT[java.lang.Object])\n      assertNotChildStrict(Tag[zy.y.type].tag, LTT[zx.y.type])\n      assertNotChildStrict(Tag[zy.y.type].tag, LTT[zx.x.type])\n    }\n\n    \"correctly resolve abstract types inside traits when summoned inside trait\" in {\n      val a = new ContainerDef {}\n      val b = new ContainerDef {}\n\n      assert(a.make.tag == Tag[DockerContainer[a.T]].tag)\n      assertDifferent(a.make.tag, Tag[DockerContainer[b.T]].tag)\n      assertSameStrict(Tag[DockerContainer[a.T]].tag, Tag[DockerContainer[a.T]].tag)\n      assertDifferent(Tag[DockerContainer[a.T]].tag, Tag[DockerContainer[b.T]].tag)\n\n      val zy = new ZY {}\n      assert(zy.tagT.getMessage contains \"could not find implicit value\")\n      assert(zy.tagU.getMessage contains \"could not find implicit value\")\n      assert(zy.tagV.getMessage contains \"could not find implicit value\")\n      assert(zy.tagA.isSuccess)\n    }\n\n    \"combine higher-kinded type lambdas without losing ignored type arguments\" in {\n      val tag = `LTT[_[+_,+_]]`[({ type l[F[+_, +_]] = BlockingIO3[λ[(`-R`, `+E`, `+A`) => F[E, A]]] })#l]\n      val res = tag.combine(`LTT[_,_]`[IO])\n      val tagMono = LTT[BlockingIO[IO]]\n      assertSameStrict(res, tagMono)\n    }\n\n    \"resolve a higher-kinded type inside a named type lambda with ignored type arguments\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[BlockingIO3[F2To3[F, *, *, *]]]\n      val tag = mk[IO]\n      val tagMono = Tag[BlockingIO[IO]]\n      assertSameStrict(tag.tag, tagMono.tag)\n    }\n\n    \"resolve TagKK from an odd higher-kinded Tag with swapped & ignored parameters (low-level)\" in {\n      type Lt[F[_, _, _], _1, _2, _3] = F[_2, _3, _1]\n\n      val ctorTag: LightTypeTag = implicitly[Tag.auto.T[Lt]].tag\n      val eitherRSwapTag = LTagK3[EitherRSwap].tag\n      val throwableTag = LTag[Throwable].tag\n\n      val combinedTag = HKTag\n        .appliedTagNonPosAux(\n          classOf[Any],\n          ctor = ctorTag,\n          args = List(\n            Some(eitherRSwapTag),\n            Some(throwableTag),\n            None,\n            None\n          )\n        ).tag\n      val expectedTag = TagKK[Lt[EitherRSwap, Throwable, *, *]].tag\n      assertSameStrict(combinedTag, expectedTag)\n    }\n\n    \"correctly resolve a higher-kinded nested type inside a named swap type lambda\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[BIOService[SwapF2[F, *, *]]]\n\n      val tag = mk[Either]\n\n      assertSameStrict(tag.tag, Tag[BIOService[SwapF2[Either, *, *]]].tag)\n      assertSameStrict(tag.tag, Tag[BIOService[Swap]].tag)\n      assertSameStrict(tag.tag, Tag[BIOService[λ[(E, A) => Either[A, E]]]].tag)\n    }\n\n    \"support subtyping of parents parameterized with type lambdas in combined tags\" in {\n      val childBase = `LTT[_[_,_]]`[RoleChild]\n      val childArg = `LTT[_,_]`[Either]\n      val combinedTag = childBase.combine(childArg)\n      val parentTag = LTT[RoleParent[Either[Throwable, *]]]\n      val childTag = LTT[RoleChild[Either]]\n\n      assertChild(combinedTag, childTag)\n      assertSame(combinedTag, childTag)\n\n      assertChild(combinedTag, parentTag)\n      assertNotChild(parentTag, combinedTag)\n    }\n\n    \"support subtyping of parents parameterized with type lambdas in combined tags with multiple parameters\" in {\n      val childBase = `LTT[_[+_,+_],_,_]`[RoleChild2]\n      val childArgs = Seq(`LTT[_,_]`[Either], LTT[Int], LTT[String])\n      val combinedTag = childBase.combine(childArgs: _*)\n      val expectedTag = LTT[RoleParent[Either[Throwable, *]]]\n      val noncombinedTag = LTT[RoleChild2[Either, Int, String]]\n\n      assertSame(combinedTag, noncombinedTag)\n      assertChild(noncombinedTag, expectedTag)\n      assertChild(combinedTag, expectedTag)\n    }\n\n    \"combine inside type lambdas with repeated usages of a type lambda type parameter\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[RepeatedBlockingIO[F]]\n\n      val tag = mk[IO]\n      val tagMono = Tag[RepeatedBlockingIO[IO]]\n\n      assertSameStrict(tag.tag, tagMono.tag)\n    }\n\n    \"combine inside type lambdas with repeated usages of an outer type\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[RepeatedNonLambdaBlockingIO[F]]\n\n      val tag = mk[IO]\n      val tagMono = Tag[RepeatedNonLambdaBlockingIO[IO]]\n\n      assertSameStrict(tag.tag, tagMono.tag)\n    }\n\n    \"combine inside type lambdas with repeated usages of an outer distinct type with the same type symbol\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[RepeatedSymbolNonLambdaBlockingIO[F]]\n\n      val tag = mk[IO]\n      val tagMono = Tag[RepeatedSymbolNonLambdaBlockingIO[IO]]\n\n      assertSameStrict(tag.tag, tagMono.tag)\n    }\n\n    \"regression test: https://github.com/zio/izumi-reflect/issues/82, convert trifunctor hkt to bifunctor when combining tags\" in {\n      def tag[F[-_, +_, +_]: TagK3] = Tag[BIO2[F[Any, +*, +*]]]\n\n      assertSameStrict(tag[ZIO].tag, Tag[BIO2[IO]].tag)\n    }\n\n    \"combine higher-kinded types without losing ignored type arguments\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[BlockingIO[F]]\n\n      val tag = mk[IO]\n      val tagMono = Tag[BlockingIO[IO]]\n\n      assertSameStrict(tag.tag, tagMono.tag)\n    }\n\n    \"resolve a higher-kinded type inside an anonymous type lambda with ignored & higher-kinded type arguments\" in {\n      def mk[F[_[_], _]: TagTK] = Tag[BlockingIO3T[({ type l[R, E[_], A] = F[E, A] })#l]]\n\n      val tag = mk[OptionT]\n\n      assertSameStrict(tag.tag, Tag[BlockingIOT[OptionT]].tag)\n    }\n\n    \"correctly resolve a higher-kinded nested type inside an anonymous swap type lambda\" in {\n      def mk[F[+_, +_]: TagKK] = Tag[BIOService[λ[(E, A) => F[A, E]]]]\n\n      val tag = mk[Either]\n\n      assertSameStrict(tag.tag, Tag[BIOService[SwapF2[Either, *, *]]].tag)\n      assertSameStrict(tag.tag, Tag[BIOService[Swap]].tag)\n      assertSameStrict(tag.tag, Tag[BIOService[λ[(E, A) => Either[A, E]]]].tag)\n    }\n\n    \"handles abstract types instead of parameters\" in {\n      trait T1 {\n        type F[F0[_], A0] = OptionT[F0, A0]\n        type C[_, _]\n        type G[_]\n        type A\n        type B\n\n        def x: Tag[F[G, Either[A, B]]]\n      }\n\n      val t1: T1 {\n        type G[T] = List[T]\n        type C[A0, B0] = Either[A0, B0]\n        type A = Int\n        type B = Byte\n      } = new T1 {\n        type G[T] = List[T]\n        type C[A0, B0] = Either[A0, B0]\n        type A = Int\n        type B = Byte\n\n        // Inconsistent handling of type aliases by scalac...\n        // No TagK for G, but if G is inside an object or enclosing class\n        // then there is a TagK\n        val g: TagK[G] = TagK[List]\n\n        final val x: Tag[F[G, Either[A, B]]] = {\n          implicit val g0: TagK[G] = g\n          val _ = g0\n          Tag[F[G, C[A, B]]]\n        }\n      }\n\n      assertSameStrict(t1.x.tag, fromRuntime[OptionT[List, Either[Int, Byte]]])\n    }\n\n    \"Generates lambda parents for lambda bases\" in {\n      val childBase = `LTT[_[_,_]]`[RoleChild]\n\n      val fullDb = childBase.basesdb\n      fullDb.foreach {\n        case (_, parents) =>\n          parents.foreach {\n            p =>\n              if (p.toString.contains(\"RoleParent\")) {\n                assert(p.isInstanceOf[LightTypeTagRef.Lambda])\n                assert(p.asInstanceOf[LightTypeTagRef.Lambda].input.size == 1)\n              }\n          }\n      }\n    }\n\n    \"subtyping for Invariant Java HKT\" in {\n      val collection = TagK[java.util.Collection]\n      val javaIterable = TagK[java.lang.Iterable]\n      assertChildStrict(collection.tag, javaIterable.tag)\n    }\n\n    \"subtyping for Invariant Scala HKT\" in {\n      val mutableSet = TagK[scala.collection.mutable.Set]\n      val collectionSet = TagK[scala.collection.Set]\n      assertChildStrict(mutableSet.tag, collectionSet.tag)\n    }\n\n    \"Work for structural concrete types\" in {\n      assertSameStrict(Tag[{ def a: Int; def g: Boolean }].tag, fromRuntime[{ def a: Int; def g: Boolean }])\n      assertSameStrict(Tag[Int { def a: Int }].tag, fromRuntime[Int { def a: Int }])\n\n      assertSameStrict(Tag[With[str.type] with ({ type T = str.type with Int })].tag, fromRuntime[With[str.type] with ({ type T = str.type with Int })])\n      assertNotChildStrict(Tag[With[str.type] with ({ type T = str.type with Int })].tag, fromRuntime[With[str.type] with ({ type T = str.type with Long })])\n    }\n\n    \"Work for any abstract type with available Tag while preserving additional type refinement\" in {\n      def testTag[T: Tag] = Tag[T { type X = Int; type Y = String }]\n\n      assertSameStrict(testTag[String].tag, fromRuntime[String { type X = Int; type Y = String }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { type X = String; type Y = Boolean }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { type X = String; type Y = Boolean }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { type X = Int; type Y = Boolean }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { type X = Boolean; type Y = String }])\n    }\n\n    \"Work for any abstract type with available Tag while preserving additional method refinement\" in {\n      def testTag[T: Tag] = Tag[T { def x: Int; val y: String }]\n\n      assertSameStrict(testTag[String].tag, fromRuntime[String { def x: Int; val y: String }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { def x: String; val y: Boolean }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { def x: Int; val y: Boolean }])\n      assertNotChildStrict(testTag[String].tag, fromRuntime[String { def x: Boolean; val y: String }])\n    }\n\n    \"can resolve parameters in structural types\" in {\n      def t[X: Tag]: Tag[{ type T = X }] = Tag[{ type T = X }]\n\n      val t1 = t[Int].tag\n      val t2 = Tag[{ type T = Int }].tag\n      val t3 = Tag[{ type T = SubStrC }].tag\n\n      assertSame(t1, t2)\n      assertDifferent(t1, t3)\n    }\n\n    \"combine higher-kinded type members\" in {\n      def combine1[X[_[_], _]: TagTK, F[_]: TagK, A: Tag]: Tag[X[F, A]] = Tag[X[F, A]]\n      def combine2[F[_]: TagK, A: Tag]: Tag[F[A]] = Tag[F[A]]\n\n      val t1 = TagTK[HigherKindedTypeMember.T]\n      val t2 = TagK[HigherKindedTypeMember.T[IO[Throwable, *], *]]\n      val t3 = TagTK[HigherKindedTypeMember.G]\n\n      val tres1 = combine1[HigherKindedTypeMember.T, IO[Throwable, *], Int](t1, implicitly, implicitly)\n      val tres2 = combine2[HigherKindedTypeMember.T[IO[Throwable, *], *], Int](t2, implicitly)\n      val tres3 = combine1[HigherKindedTypeMember.G, IO[Throwable, *], Int](t3, implicitly, implicitly)\n\n      assertSameStrict(tres1.tag, Tag[HigherKindedTypeMember.T[IO[Throwable, *], Int]].tag)\n      assertSameStrict(tres2.tag, Tag[HigherKindedTypeMember.T[IO[Throwable, *], Int]].tag)\n      assertSameStrict(tres3.tag, Tag[HigherKindedTypeMember.G[IO[Throwable, *], Int]].tag)\n\n      assertChildStrict(tres1.tag, Tag[AnyVal].tag)\n      assertChildStrict(tres2.tag, Tag[AnyVal].tag)\n      assertChildStrict(tres3.tag, Tag[HigherKindedTypeMember.T[IO[Throwable, *], Int]].tag)\n      assertChildStrict(tres3.tag, Tag[AnyVal].tag)\n\n      // unnapliedInheritanceDB contains evidence that G <: T\n      val t3InhBases = t3.tag.idb(tres3.tag.ref.withoutArgs.asInstanceOf[LightTypeTagRef.NameReference])\n      assert(t3InhBases.contains(tres1.tag.ref.withoutArgs.asInstanceOf[LightTypeTagRef.NameReference]))\n    }\n\n    \"regression test: do not be confused by a type alias of Set of an abstract type referred via this-prefix on Scala 3\" in {\n      val t1 = Tag[RoleDep.RoleDeps[Int, Int]].tag\n      val t2 = Tag[Set[RoleDep.RoleDep[Int, Int]]].tag\n      val t3 = LTT[RoleDep.RoleDeps[Int, Int]]\n\n      assertSameStrict(t1, t2)\n      assertSameStrict(t1, t3)\n\n      assertDebugSame(t1, t2)\n      assertDebugSame(t1, t3)\n    }\n\n    \"support injecting runtime tags in place of type projections from type parameters / match types on type parameters\" in {\n      def tag[TC <: DiscoverableService](implicit tag: Tag[GetDiscoveryNode[TC]]): Tag[DiscoveryNodeProvider[GetDiscoveryNode[TC]]] = {\n        Tag[DiscoveryNodeProvider[GetDiscoveryNode[TC]]]\n      }\n\n      val t1 = tag[DiscoverableServiceImpl].tag\n      val t2 = Tag[DiscoveryNodeProvider[NodeIdImpl]].tag\n\n      assertSameStrict(t1, t2)\n      assertDebugSame(t1, t2)\n    }\n\n    \"regression test for: Scala 2, https://github.com/zio/izumi-reflect/issues/189, parameterized type alias with intersection produces incorrect output\" in {\n      def elementTag[F[_]: TagK]: Tag[SrcContextProcessor[F]] = Tag[TestModel.x.SrcContextProcessor[F]]\n      assert(elementTag[CIO].tag == Tag[TestModel.x.SrcContextProcessor[CIO]].tag)\n\n      type K[F[_]] = Set[TestModel.x.SrcContextProcessor[F]]\n      assert(TagT[K].tag.combine(TagK[CIO].tag) == Tag[Set[TestModel.x.SrcContextProcessor[CIO]]].tag)\n\n      def aliasedTag[F[_]: TagK]: Tag[Set[SrcContextProcessor[F]]] = Tag[K[F]]\n      assert(aliasedTag[CIO].tag == Tag[Set[TestModel.x.SrcContextProcessor[CIO]]].tag)\n\n      def directTag[F[_]: TagK]: Tag[Set[SrcContextProcessor[F]]] = Tag[Set[TestModel.x.SrcContextProcessor[F]]]\n      assert(directTag[CIO].tag == Tag[Set[TestModel.x.SrcContextProcessor[CIO]]].tag)\n    }\n\n    \"combining with wildcards is supported\" in {\n      def tag[F[_]: TagK]: Tag[OptionT[F, _ <: Int]] = Tag[OptionT[F, _ <: Int]]\n\n      val t1 = tag[Set]\n      val t2 = tag[List]\n      val t3 = tag[* => Int]\n\n      assertSameStrict(t1.tag, Tag[OptionT[Set, _ <: Int]].tag)\n      assertSameStrict(t2.tag, Tag[OptionT[List, _ <: Int]].tag)\n      assertSameStrict(t3.tag, Tag[OptionT[* => Int, _ <: Int]].tag)\n    }\n\n    \"other type members' bounds are not malformed when resolving parameters in structural types\" in {\n      def t[X: Tag]: Tag[{ type G >: Int <: AnyVal; type T = X }] = Tag[{ type G >: Int <: AnyVal; type T = X }]\n\n      val t1 = t[Int].tag\n      val t2 = Tag[{ type G >: Int <: AnyVal; type T = Int }].tag\n      val t3 = Tag[{ type G >: Int <: AnyVal; type T = SubStrC }].tag\n\n      assertSame(t1, t2)\n      assertDifferent(t1, t3)\n    }\n\n    \"form a correct type lambda for an equal-bounded abstract type\" in {\n      def tag[F[_, _]: TagKK]: Tag[F[Int, String]] = Tag[F[Int, String]]\n\n      val t1 = tag[RoleDep.RoleDep]\n      val t2 = tag[RoleDep.RoleDeps]\n\n      assertSameStrict(t1.tag, Tag[RoleDep.RoleDep[Int, String]].tag)\n      assertDifferent(t1.tag, Tag[Any].tag)\n      assertSameStrict(t2.tag, Tag[RoleDep.RoleDeps[Int, String]].tag)\n      assertDifferent(t2.tag, Tag[Any].tag)\n    }\n\n    \"eradicate intersection tautologies with Any/Object (Tag)\" in {\n      assertSameStrict(Tag[Any with Option[String]].tag, LTT[Option[String]])\n      assertSameStrict(Tag[AnyRef with Option[String]].tag, LTT[Option[String]])\n      assertSameStrict(Tag[Object with Option[String]].tag, LTT[Option[String]])\n    }\n\n    \"tautological intersections with Any/Object are discarded from internal structure (Tag)\" in {\n      assertSameStrict(Tag[(Object {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]].tag, LTT[Option[String]])\n      assertSameStrict(Tag[(Any {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]].tag, LTT[Option[String]])\n      assertSameStrict(Tag[(AnyRef {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]].tag, LTT[Option[String]])\n\n      assertDebugSame(Tag[(Object {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]].tag, LTT[Option[String]])\n      assertDebugSame(Tag[(Any {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]].tag, LTT[Option[String]])\n      assertDebugSame(Tag[(AnyRef {}) @IdAnnotation(\"x\") with Option[(String with Object) {}]].tag, LTT[Option[String]])\n    }\n\n    \"regression test for https://github.com/zio/izumi-reflect/issues/474\" in {\n      assertCompiles(\"Tag[Array[Byte]]\")\n    }\n\n    \"resolve parameters inside type bounds & wildcards\" in {\n      def getUpperBoundTag[T: Tag]: Tag[Set[_ <: T]] = Tag[Set[_ <: T]]\n\n      def getLowerBoundTag[T: Tag]: Tag[Set[_ >: T]] = Tag[Set[_ >: T]]\n\n      assertRepr(getUpperBoundTag[Int].tag, \"Set[=?: <Nothing..Int>]\")\n      assertSame(getUpperBoundTag[Int].tag, Tag[Set[_ <: Int]].tag)\n\n      assertRepr(getLowerBoundTag[Int].tag, \"Set[=?: <Int..Any>]\")\n      assertSame(getLowerBoundTag[Int].tag, Tag[Set[_ >: Int]].tag)\n\n      // for recursive bound case\n      def x[T[_]: TagK, U: Tag]: Tag[Set[_ <: T[U]]] = Tag[Set[_ <: T[U]]]\n      assertRepr(x[List, Long].tag, \"Set[=?: <Nothing..List[+Long]>]\")\n      assertSameStrict(x[List, Long].tag, Tag[Set[_ <: List[Long]]].tag)\n\n      def xcontra[T[_]: TagK, U: Tag]: Tag[(_ <: T[U]) => Int] = Tag[(_ <: T[U]) => Int]\n      assertRepr(xcontra[List, Long].tag, \"Function1[-?: <Nothing..List[+Long]>,+Int]\")\n      assertSameStrict(xcontra[List, Long].tag, Tag[(_ <: List[Long]) => Int].tag)\n    }\n  }\n\n}\n\ntrait SomeTrait {\n  type Abstract\n}\n\nobject SomeObject {\n  type Abstract\n}\n\n// https://github.com/scala/bug/issues/11139\nfinal case class testTag3[F[_]: TagK]() {\n  type X = OptionT[F, Int]\n  val res = Tag[X].tag\n}\n\nobject X76 {\n  sealed trait T[A]\n  val x = implicitly[Tag[T[Int]]]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/TagAssertions.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.macrortti.{LTT, LTag, LightTypeTag}\nimport org.scalatest.wordspec.AnyWordSpec\n\ntrait TagAssertions extends AnyWordSpec with TagLogging {\n\n  def assertRepr(t: LightTypeTag, expected: String): Unit = {\n    assert(t.toString == expected); ()\n  }\n\n  def assertDebugSame(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    val tDebug = t.debug(\"assert\")\n    val expectedDebug = expected.debug(\"assert\")\n    val clue = s\"${t.repr} debug== ${expected.repr}\"\n    def failClue = s\"debug1: $tDebug\\ndebug2: $expectedDebug\"\n    info(clue)\n    assert(tDebug == expectedDebug, s\"$clue\\n$failClue\"); ()\n  }\n\n  def assertSame(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    val clue = s\"${t.repr} =?= ${expected.repr}\"\n    info(clue)\n    assert(t =:= expected, clue)\n    assert(t.ref == expected.ref, s\"ref: $clue\"); ()\n  }\n\n  def assertSameRef(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    val clue = s\"${t.repr} =?= ${expected.repr}\"\n    info(clue)\n    assert(t.ref == expected.ref, s\"ref: $clue\"); ()\n  }\n\n  def assertDifferent(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    val clue = s\"${t.repr} =!= ${expected.repr}\"\n    info(clue)\n    assert(!(t =:= expected), clue); ()\n  }\n\n  def assertChild(child: LightTypeTag, parent: LightTypeTag): Unit = {\n    val clue = s\"${child.repr} <?< ${parent.repr}\"\n    def failClue = s\"1: ${child.debug()}\\n2: ${parent.debug()}\"\n    info(clue)\n    assert(child <:< parent, s\"$clue\\n$failClue\"); ()\n  }\n\n  def assertNotChild(child: LightTypeTag, parent: LightTypeTag): Unit = {\n    val clue = s\"${child.repr} <!< ${parent.repr}\"\n    def failClue = s\"notChild 1: ${child.debug()}\\nnotChild 2: ${parent.debug()}\"\n    info(clue)\n    assert(!(child <:< parent), s\"$clue\\n$failClue\"); ()\n  }\n\n  def assertCombine(outer: LightTypeTag, inner: Seq[LightTypeTag], expected: LightTypeTag): Unit = {\n    val combined = outer.combine(inner: _*)\n    val clue = s\"(${outer.repr})•(${inner.map(_.repr).mkString(\",\")}) => ${combined.repr} =?= ${expected.repr}\"\n    info(clue)\n    assert(combined =:= expected, clue); ()\n  }\n\n  def assertCombine(outer: LightTypeTag, inner: LightTypeTag, expected: LightTypeTag): Unit = {\n    val combined = outer.combine(inner)\n    val clue = s\"(${outer.repr})•(${inner.repr}) => ${combined.repr} =?= ${expected.repr}\"\n    info(clue)\n    assert(combined =:= expected, clue); ()\n  }\n\n  def assertCombineNonPos(outer: LightTypeTag, inner: Seq[Option[LightTypeTag]], expected: LightTypeTag): Unit = {\n    val combined = outer.combineNonPos(inner: _*)\n    val clue = s\"(${outer.repr})•(${inner.map(_.map(_.repr)).mkString(\",\")}) => ${combined.repr} =?= ${expected.repr}\"\n    info(clue)\n    assert(combined =:= expected, clue); ()\n  }\n\n  def assertIntersection(intersection: List[LightTypeTag], expected: LightTypeTag): Unit = {\n    val intersected = LightTypeTag.refinedType(intersection, structure = LTT[Any], additionalTypeMembers = Map.empty)\n    val clue = s\"(${intersection.map(_.repr).mkString(\" & \")}) => ${intersected.repr} =?= ${expected.repr}\"\n    info(clue)\n    assert(intersected =:= expected, clue)\n    assertDebugSame(intersected, expected)\n    ()\n  }\n\n  def assertSameStrict(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    assertSame(t, expected)\n    assertChild(t, expected)\n    assertChild(expected, t)\n  }\n\n  def assertChildStrict(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    assertChild(t, expected)\n    assertNotChild(expected, t)\n    assertDifferent(expected, t)\n  }\n\n  def assertNotChildStrict(t: LightTypeTag, expected: LightTypeTag): Unit = {\n    assertNotChild(t, expected)\n    assertNotChild(expected, t)\n    assertDifferent(expected, t)\n  }\n\n  def literalLtt(s: String)(implicit l: LTag[s.type]): LightTypeTag = l.tag\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/TagCombineTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti.LightTypeTag\nimport izumi.reflect.{Tag, TagK, TagK3}\n\nobject TagCombineTest {\n  trait P\n  trait C extends P\n  trait HuIO[-R, +E, +I]\n\n  class Case1[T] {\n    final def addHas[F[-_, +_, +_]: TagK3, E: Tag, I <: T: Tag](): LightTypeTag = {\n      val t1 = TagK[F[Any, E, *]]\n      val t2 = t1.tag.combine(Tag[I].tag)\n      t2\n    }\n  }\n\n}\n\nclass TagCombineTest extends TagAssertions {\n  import TagCombineTest._\n  \"Tag macro\" should {\n    \"reconstruct lambda tags\" in {\n      val expected = Tag[HuIO[Any, Int, C]].tag\n      val combined = TagK[HuIO[Any, Int, *]].tag.combine(Tag[C].tag)\n      assert(combined == expected)\n      val returned = new Case1[P]().addHas[HuIO, Int, C]()\n      assert(returned == expected)\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/TagLogging.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.internal.fundamentals.platform.assertions.IzAssert\nimport izumi.reflect.internal.fundamentals.platform.console.TrivialLogger\nimport izumi.reflect.macrortti.LightTypeTag\nimport org.scalatest.wordspec.AnyWordSpec\n\ntrait TagLogging extends AnyWordSpec {\n\n  // enable subtype comparison / .fromRuntime construction logging in tests\n  final def withDebugOutput(f: => Any): Unit = TagLogging.withDebugOutput { f; () }\n  final def withSanityChecks(f: => Any): Unit = TagLogging.withSanityChecks { f; () }\n\n  final def println(o: Any): Unit = info(o.toString)\n  final def println(o: LightTypeTag): Unit = info(o.ref.toString)\n\n}\n\nobject TagLogging {\n  def withDebugOutput[T](f: => T): T = {\n    synchronized {\n      val enabledBefore = TrivialLogger.statusLogs()\n\n      if (!enabledBefore) { TrivialLogger.enableLogs() }\n      try {\n        f\n      } finally {\n        if (!enabledBefore) { TrivialLogger.disableLogs() }\n      }\n    }\n  }\n  def withSanityChecks[T](f: => T): T = {\n    synchronized {\n      val enabledBefore = IzAssert.statusAsserts()\n      if (!enabledBefore) { IzAssert.enableAsserts() }\n      try {\n        f\n      } finally {\n        if (!enabledBefore) { IzAssert.disableAsserts() }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/TagProgressions.scala",
    "content": "package izumi.reflect.test\n\nimport org.scalatest.exceptions.TestFailedException\n\ntrait TagProgressions { this: TagAssertions =>\n\n  final def brokenOnScala3(f: => Any): Unit = {\n    if (IsScala3) broken(f) else f; ()\n  }\n  final def brokenOnScala2(f: => Any): Unit = {\n    if (!IsScala3) broken(f) else f; ()\n  }\n  final def brokenOnScala2MinorVersion(versions: Int*)(f: => Any): Unit = {\n    if (versions.contains(Scala2MinorVersion.scala2MinorVersion)) broken(f) else f; ()\n  }\n  final def broken(f: => Any): Unit = {\n    intercept[TestFailedException](f); ()\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala/izumi/reflect/test/TestModel.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.Tag\n\nimport scala.annotation.StaticAnnotation\nimport izumi.reflect.macrortti.{LTag, LightTypeTag}\n\nobject TestModel {\n\n  type BlockingIO[F[_, _]] = BlockingIO3[λ[(R, E, A) => F[E, A]]]\n\n  type BIO2[F[+_, +_]] = BIO3[λ[(`-R`, `+E`, `+A`) => F[E, A]]]\n\n  final class With[T] extends StaticAnnotation\n\n  final class IdAnnotation(val name: String) extends StaticAnnotation\n\n  trait YieldOpCounts {\n    def zioYieldOpCount: Int = 1024\n    def blockingYieldOpCount: Int = Int.MaxValue\n  }\n  object YieldOpCounts extends YieldOpCounts\n\n  trait T0[A[_], B[_]]\n  final val str = \"str\"\n\n  type Id[T] = T\n  type FP1[+T] = List[T]\n  type Ap1[+F[+_], +T] = F[T]\n  type FP[+T] = FP1[T]\n  type L[P] = List[P]\n  type LN[P <: Number] = List[P]\n\n  trait T1[U[_]]\n\n  type FI[IGNORE] = Unit\n\n  trait T2[U[_[_], _[_]]]\n\n  //  type K = T1[F]\n  //  val a: K = new T1[F] {}\n  trait C {\n    type A\n  }\n\n  trait R0[K, A <: R0[K, A]]\n  trait R1[K] extends R0[K, R1[K]]\n\n  type S[A, B] = Either[B, A]\n\n  trait W1\n\n  trait W2 extends W1\n\n  trait W3[X]\n\n  trait W4[A] extends W3[A]\n\n  trait W5[B] extends W2\n\n  type T3[A, B] = W5[A] with W4[B] with W1\n\n  trait I1\n\n  trait I2 extends I1\n\n  trait F1[+A]\n  trait F2[+A] extends F1[A]\n  trait F3 extends F2[Int]\n\n  trait FT1[+A[+_[+_]]]\n\n  trait FT2[+A[+_[+_]]] extends FT1[A]\n\n  trait IT1[+K[+_]]\n\n  trait IT2[+K[+_]] extends IT1[K]\n\n  trait FM1[+A, +B]\n\n  trait FM2[+A] extends FM1[A, Unit]\n\n  type NestedTL[G[_, _], A, B] = FM2[G[A, (B, A)]]\n\n  type NestedTL2[A, B, G[_]] = FM2[G[S[B, A]]]\n\n  type Const[A, B] = B\n\n  type XS <: { type X }\n  type WithX = { type X }\n  type FXS <: { type F[A] = A }\n\n  trait H1\n  trait H2 extends H1\n  trait H3 extends H2\n  trait H4 extends H3\n  trait H5 extends H4\n\n  trait J1[F[_]]\n  trait J2\n  trait J3\n  trait J[F[_]] extends J1[F] with J2 with J3\n\n  object TPrefix {\n    type T\n  }\n\n  trait P0[A[_], B[_]]\n  trait P1[A[_], B[_]] extends P0[B, A]\n  trait X1[x]\n  trait X2[x]\n\n  trait XP1[A[_]] extends P0[X2, A]\n\n  trait RoleParent[F[_]]\n  trait RoleChild[F[_, _]] extends RoleParent[F[Throwable, *]]\n  class RoleChild2[F[+_, +_], A, B] extends RoleParent[F[Throwable, *]]\n\n  class ApplePaymentProvider[F[_]] extends H1\n\n  trait ZIO[-R, +E, +A]\n  type IO[+E, +A] = ZIO[Any, E, A]\n\n  class BlockingIO3[F[_, _, _]]\n\n  object PDTNormA {\n    trait Service\n  }\n\n  val PDTNormB = PDTNormA\n\n  trait KT1[+A1, +B1]\n  trait KT2[+A2, +B2] extends KT1[B2, A2]\n  trait KK1[+A, +B, +U]\n  trait KK2[+A, +B] extends KK1[B, A, Unit]\n\n  class \\/[L, R](implicit val lt: LTag[L], val rt: LTag[R])\n  type SubStrA <: String\n  type SubStrB <: String\n  type SubStrC = String\n  type SubStrD = SubStrA\n  type SubSubStr <: SubStrA\n\n  final case class VarArgsAnyVal(args: String*) extends AnyVal\n\n  trait BIO3[F[-_, +_, +_]]\n\n  trait CIO[+A]\n  object x {\n    type SrcContextProcessor[F[_]] = SrcProcessor with ContextProcessor[F]\n  }\n  trait SrcProcessor\n  trait ContextProcessor[F[_]]\n\n  trait IntegrationCheck[+F[_]]\n\n  object ThisPrefixTest {\n    class ThisPrefix {\n      val tag: LightTypeTag = Tag[this.type].tag\n    }\n    object ThisPrefix {\n      val tag: LightTypeTag = Tag[this.type].tag\n    }\n  }\n\n  object BasicCases {\n    object BasicCase2 {\n      class TestImpl0Good\n    }\n  }\n\n  object HigherKindedTypeMember {\n    type T[F[_], A] >: Unit <: AnyVal\n    type G[F[_], A] >: Unit <: T[F, A]\n  }\n\n  object RoleDep {\n    type RoleDep[RoleId, C] >: Any\n    type RoleDeps[RoleId, C] = Set[this.RoleDep[RoleId, C]] // this-prefix is important, do not remove\n  }\n\n  trait Trait1 {\n    def dep: Any\n  }\n\n  trait Trait3[T] extends Trait1 {\n    def dep: T\n  }\n\n  trait Trait4\n\n  trait AbstractRole[F[_]]\n  class TargetRole extends AbstractRole[Id]\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/BasicDottyTestMirror.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nclass BasicDottyTestMirror extends CurrentDottySupportExtentTest\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/DiscoveryModel.scala",
    "content": "package izumi.reflect.test\n\nobject DiscoveryModel {\n\n  trait NodeId\n  trait DiscoverableService {\n    type DiscoveryNode <: NodeId\n  }\n  trait DiscoveryNodeProvider[Id <: NodeId]\n  trait DiscoverableServiceImpl extends DiscoverableService {\n    override type DiscoveryNode = NodeIdImpl\n  }\n  class NodeIdImpl extends NodeId\n\n  type GetDiscoveryNode[T <: DiscoverableService] = T#DiscoveryNode\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/IsScala3.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.internal.fundamentals.platform.language.unused\n\nimport scala.language.implicitConversions\n\nobject IsScala3 {\n  implicit def IsScala3(@unused t: this.type): Boolean = false\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/LightTypeTagProgressionTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nclass LightTypeTagProgressionTest extends SharedLightTypeTagProgressionTest {\n\n//  \"[progression] lightweight type tags (Scala 2)\" should {\n//\n//  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/LightTypeTagTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.macrortti._\n\nclass LightTypeTagTest extends SharedLightTypeTagTest {\n\n  import TestModel._\n\n  \"lightweight type tags (Scala 2)\" should {\n\n    \"support structural & refinement type equality (Scala 2 specific, generic type projection from an abstract type member)\" in {\n      val a1 = new C {\n        override type A = Int\n      }\n      object Z {\n        type X <: { type A = Int }\n      }\n      val _ = (a1, Z)\n\n      assertSame(LTT[a1.A], LTT[Z.X#A])\n    }\n\n    \"strong summons test (Scala 2 specific, generic type projection from an abstract type member)\" in {\n      assertCompiles(\"def x1 = { object x { type T <: { type Array } }; LTag[x.T#Array]; () }\")\n    }\n\n    \"there should be no unexpected lambdas in bases db produced from nested existential types (Scala 2 specific, unreducible application of higher-kinded type to wildcard arguments) (regression test https://github.com/zio/izumi-reflect/issues/345)\" in {\n      trait L[ARRG0]\n\n      trait Test0[+ARRG1]\n      trait Test1[+ARRG2] extends Test0[ARRG2]\n\n      type T1[AAA] = Test1[L[AAA]]\n\n      val list_ = LTT[T1[_]]\n      info(list_.debug())\n      assert(!list_.debug().contains(\"→ izumi.reflect.test.LightTypeTagProgressionTest.Test0[+izumi.reflect.test.LightTypeTagProgressionTest.L[=?]]\"))\n    }\n\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/TagProgressionTest.scala",
    "content": "package izumi.reflect.test\n\nclass TagProgressionTest extends SharedTagProgressionTest {\n  // All Scala 2 specific progression tests have been fixed and moved to TagTest\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2/izumi/reflect/test/TagTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect._\nimport izumi.reflect.macrortti._\nimport org.scalatest.exceptions.TestFailedException\n\nclass TagTest extends SharedTagTest {\n\n  import izumi.reflect.test.PlatformSpecific.fromRuntime\n\n  override final val tagZ = Tag[String]\n\n  trait T2[A, B, C[_[_], _], D[_], E]\n\n  trait Trait1 {\n    def dep: Dep\n  }\n  trait Trait3[T <: Dep] extends Trait1 {\n    def dep: T\n  }\n\n  \"Tag (Scala 2)\" should {\n\n    \"Work for an abstract type with available TagK when TagK is requested through an explicit implicit (Scala 2 HKTag Syntax)\" in {\n      def testTagK[F[_], T: Tag](implicit ev: HKTag[{ type Arg[C] = F[C] }]) = {\n        val _ = ev\n        Tag[F[T {}] {}]\n      }\n\n      assert(testTagK[Set, Int].tag == fromRuntime[Set[Int]])\n    }\n\n    \"Handle Tags outside of a predefined set (Scala 2 HKTag Syntax)\" in {\n      type TagX[T[_, _, _[_[_], _], _[_], _]] = HKTag[{ type Arg[A, B, C[_[_], _], D[_], E] = T[A, B, C, D, E] }]\n\n      def testTagX[F[_, _, _[_[_], _], _[_], _]: TagX, A: Tag, B: Tag, C[_[_], _]: TagTK, D[_]: TagK, E: Tag] = Tag[F[A, B, C, D, E]]\n\n      val value = testTagX[T2, Int, String, OptionT, List, Boolean]\n      assert(value.tag == fromRuntime[T2[Int, String, OptionT, List, Boolean]])\n    }\n\n    \"Can create custom type tags to support bounded generics, e.g. <: Dep in TagK (Scala 2 HKTag Syntax)\" in {\n      type `TagK<:Dep`[K[_ <: Dep]] = HKTag[{ type Arg[A <: Dep] = K[A] }]\n\n      implicitly[`TagK<:Dep`[Trait3]].tag.withoutArgs =:= LTag[Trait3[Nothing]].tag.withoutArgs\n    }\n\n    \"support HKTag for unapplied type lambdas with type bounds\" in {\n      type `TagK<:Dep`[K[_ <: Dep]] = HKTag[{ type Arg[A <: Dep] = K[A] }]\n\n      def t[T[_ <: Dep]: `TagK<:Dep`, A <: Dep: Tag] = Tag[T[A]]\n\n      assert(t[Trait3, Dep].tag == Tag[Trait3[Dep]].tag)\n    }\n\n    \"support HKTag for unapplied type lambdas with higher-kinded type bounds\" in {\n      class Trait4[K] extends Dep\n      class Trait5[T[_]]\n\n      type `TagKT<:Dep`[K[X[_] <: Dep]] = HKTag[{ type Arg[A[_] <: Dep] = K[A] }]\n\n      def t[T[_[_] <: Dep]: `TagKT<:Dep`, A[_] <: Dep: TagK] = Tag[T[A]]\n\n      assert(t[Trait5, Trait4].tag == Tag[Trait5[Trait4]].tag)\n    }\n\n    \"support HKTag for higher-kinded type lambdas with interdependent inner and outer type bounds\" in {\n      class Dep0\n      trait Trait30[T <: Dep0]\n      trait TraitK30[T[x <: Dep0] <: Trait30[x]]\n\n      type `TagK<:Dep0`[K[_ <: Dep0]] = HKTag[{ type Arg[A <: Dep0] = K[A] }]\n      type `TagKT<:Dep0`[K[T[x <: Dep0] <: Trait30[x]]] = HKTag[{ type Arg[T[x <: Dep0] <: Trait30[x]] = K[T] }]\n\n      def t[K[F[x <: Dep0] <: Trait30[x]]: `TagKT<:Dep0`, T[x <: Dep0] <: Trait30[x]: `TagK<:Dep0`] = Tag[K[T]]\n\n      assert(t[TraitK30, Trait30].tag == Tag[TraitK30[Trait30]].tag)\n    }\n\n    \"example in 3.0.9 release notes works\" in {\n      def printColType[F[+x] <: Iterable[x]: Tag.auto.T]: LightTypeTag = {\n        Tag[F[Int]].tag\n      }\n      assert(printColType[List] == LTT[List[Int]])\n    }\n\n    \"can find HKTag when obscured by type lambda (Scala 2 HKTag Syntax)\" in {\n      assertCompiles(\"HKTag.hktagFromTagMacro[{ type Arg[C] = Option[C] }]\")\n      assertCompiles(\"HKTag.hktagFromTagMacro[({ type l[F[_]] = { type Arg[C] = F[C] } })#l[Option]]\")\n    }\n\n    \"we no longer accidentally materialize tags for type parameters that are prefixes of type projections (Scala 2 specific, generic type projection)\" in {\n      class Path {\n        type Child\n      }\n      val path = new Path\n\n      // A has no tag and the definition of `getTag` should not compile at all. It's a bug that it compiles\n      val t = intercept[TestFailedException](\n        assertCompiles(\n          \"\"\"\n          def getTag[A <: Path]: Tag[A#Child] = Tag[A#Child]\n          \"\"\"\n        )\n      )\n      assert(\n        t.getMessage.contains(\"could not find implicit value\") ||\n        t.getMessage.contains(\"no implicit argument of type\") /*Dotty*/\n      )\n\n      def getTag[A <: Path](implicit t: Tag[A#Child]): Tag[A#Child] = Tag[A#Child]\n\n      val directChildTag = Tag[Path#Child].tag // Path::Child\n      val indirectChildTag = getTag[path.type].tag // A|<Nothing..Path>::Child\n\n      assertDifferent(indirectChildTag, directChildTag)\n      assertNotChild(directChildTag, indirectChildTag)\n      assertNotChild(indirectChildTag, directChildTag)\n\n      assertRepr(indirectChildTag, \"path::Child\")\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2.11/izumi/reflect/test/Scala2MinorVersion.scala",
    "content": "package izumi.reflect.test\n\nobject Scala2MinorVersion {\n  def scala2MinorVersion: Int = 11\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2.12/izumi/reflect/test/Scala2MinorVersion.scala",
    "content": "package izumi.reflect.test\n\nobject Scala2MinorVersion {\n  def scala2MinorVersion: Int = 12\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2.13/izumi/reflect/test/Scala2MinorVersion.scala",
    "content": "package izumi.reflect.test\n\nobject Scala2MinorVersion {\n  def scala2MinorVersion: Int = 13\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-2.13+/izumi/reflect/test/Scala213Plus_LightTypeTagTest.scala",
    "content": "package izumi.reflect.test\n\nimport org.scalatest.wordspec.AnyWordSpec\nimport izumi.reflect.macrortti.LTT\n\nclass Scala213Plus_LightTypeTagTest extends AnyWordSpec with TagAssertions with TagProgressions {\n\n  \"lightweight type tags (2.13+)\" should {\n    \"literal types behave in sane manner https://github.com/zio/izumi-reflect/issues/284\" in {\n      import izumi.reflect._\n\n      val v: \"a\" = \"a\"\n\n      type vt = v.type\n      object xa {\n        final val x = v\n        final val y = x\n      }\n\n      assertSameStrict(Tag[\"a\"].tag, Tag[vt].tag)\n      assertSameStrict(Tag[xa.x.type].tag, Tag[\"a\"].tag)\n      assertSameStrict(Tag[xa.y.type].tag, Tag[\"a\"].tag)\n      assertDebugSame(Tag[\"a\"].tag, Tag[vt].tag)\n      assertDebugSame(Tag[xa.x.type].tag, Tag[\"a\"].tag)\n      assertDebugSame(Tag[xa.y.type].tag, Tag[\"a\"].tag)\n      assertChildStrict(Tag[\"a\"].tag, Tag[String].tag)\n      assertChildStrict(Tag[vt].tag, Tag[String].tag)\n      assertChildStrict(Tag[xa.x.type].tag, Tag[String].tag)\n      assertChildStrict(Tag[xa.y.type].tag, Tag[String].tag)\n    }\n\n    \"support string constant types (Scala 2.13+ syntax)\" in {\n      assertDifferent(LTT[\"abc\"], LTT[String])\n      assertDifferent(LTT[\"abc\"], LTT[\"cba\"])\n      assertSameStrict(LTT[\"abc\"], LTT[\"abc\"])\n      assertChildStrict(LTT[\"abc\"], LTT[String])\n    }\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/BasicDottyTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nclass BasicDottyTest extends CurrentDottySupportExtentTest\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/DiscoveryModel.scala",
    "content": "package izumi.reflect.test\n\nobject DiscoveryModel {\n\n  trait NodeId\n  trait DiscoverableService {\n    type DiscoveryNode <: NodeId\n  }\n  trait DiscoveryNodeProvider[Id <: NodeId]\n  trait DiscoverableServiceImpl extends DiscoverableService {\n    override type DiscoveryNode = NodeIdImpl\n  }\n  class NodeIdImpl extends NodeId\n\n  type GetDiscoveryNode[T <: DiscoverableService] <: NodeId = T match {\n    case GetDiscoveryNodePattern[t] => t\n  }\n  type GetDiscoveryNodePattern[Id <: NodeId] = DiscoverableService { type DiscoveryNode = Id }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/DottyRegressionTests.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.Tag\n\nobject DottyRegressionTests {\n  // should compile\n  // https://github.com/zio/izumi-reflect/issues/135#issue-801046733\n  import zio._\n\n  trait DgraphClient\n\n  object Example extends scala.App {\n\n    type DgClient = Has[DgClient.Service]\n\n    object DgClient {\n\n      trait Service {\n        val dgraphClient: UIO[DgraphClient]\n      }\n\n      val getDgClient =\n        ZIO.accessM[DgClient](_.get.dgraphClient)\n    }\n  }\n\n  object zio {\n    type UIO[+A] = ZIO[Any, Nothing, A]\n    sealed trait ZIO[-R, +E, +A]\n    object ZIO {\n      def accessM[R]: AccessMPartiallyApplied[R] = new AccessMPartiallyApplied[R]()\n      final class AccessMPartiallyApplied[R](private val dummy: Boolean = false) extends AnyVal {\n        def apply[E, A](f: R => ZIO[R, E, A]): ZIO[R, E, A] = ???\n      }\n    }\n    trait Has[A]\n    object Has {\n      implicit final class HasSyntax[Self <: Has[_]](private val self: Self) extends AnyVal {\n        def get[B](implicit ev: Self <:< Has[B], tagged: Tag[B]): B = ???\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/IsScala3.scala",
    "content": "package izumi.reflect.test\n\ninline val IsScala3 = true\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/LightTypeTagProgressionTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti._\n\nclass LightTypeTagProgressionTest extends SharedLightTypeTagProgressionTest {\n\n  \"[progression] lightweight type tag (Dotty)\" should {\n\n    \"fails to support variance for type parameters of opaque types\" in {\n      object x {\n        opaque type T[+X] = X\n      }\n\n      broken {\n        assertChildStrict(LTT[x.T[Int]], LTT[x.T[AnyVal]])\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/LightTypeTagTest.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.Tag\nimport izumi.reflect.macrortti.*\nimport izumi.reflect.macrortti.LightTypeTagRef.{AbstractReference, AppliedNamedReference, Boundaries, Lambda}\n\nimport scala.collection.immutable.ListSet\nimport scala.collection.{BitSet, immutable, mutable}\n\nclass LightTypeTagTest extends SharedLightTypeTagTest {\n\n  import TestModel._\n\n  \"lightweight type tags (Dotty)\" should {\n\n    \"tautological intersections with Matchable are discarded from internal structure (Scala 3 specific, Matchable)\" in {\n      assertSameStrict(LTT[Matchable with Option[String]], LTT[Option[String]])\n      assertDebugSame(LTT[Matchable with Option[String]], LTT[Option[String]])\n    }\n\n    \"tautological intersections with Matchable are discarded from internal structure (Scala 3 specific, Matchable) (Tag)\" in {\n      assertSameStrict(Tag[Matchable with Option[String]].tag, LTT[Option[String]])\n      assertDebugSame(Tag[Matchable with Option[String]].tag, LTT[Option[String]])\n    }\n\n    \"tautological unions with Any/AnyRef/Matchable/Object are discarded from internal structure (Scala 3 specific, Matchable)\" in {\n      assertSameStrict(LTT[Any | Matchable | AnyRef | Object | Option[String] | Nothing], LTT[Any])\n      assertDebugSame(LTT[Any | Matchable | AnyRef | Object | Option[String] | Nothing], LTT[Any])\n\n      assertSameStrict(LTT[Matchable | AnyRef | Object | Option[String] | Nothing], LTT[Matchable])\n      assertDebugSame(LTT[Matchable | AnyRef | Object | Option[String] | Nothing], LTT[Matchable])\n\n      assertSameStrict(LTT[AnyRef | Object | Option[String] | Nothing], LTT[AnyRef])\n      assertDebugSame(LTT[AnyRef | Object | Option[String] | Nothing], LTT[AnyRef])\n\n      assertSameStrict(LTT[Object | Option[String] | Nothing], LTT[Object])\n      assertDebugSame(LTT[Object | Option[String] | Nothing], LTT[Object])\n\n      assertSameStrict(LTT[Option[String] | Nothing], LTT[Option[String]])\n      assertDebugSame(LTT[Option[String] | Nothing], LTT[Option[String]])\n    }\n\n    \"tautological unions with Any/AnyRef/Matchable/Object are discarded from internal structure (Scala 3 specific, Matchable) (Tag)\" in {\n      assertSameStrict(Tag[Any | Matchable | AnyRef | Object | Option[String] | Nothing].tag, LTT[Any])\n      assertDebugSame(Tag[Any | Matchable | AnyRef | Object | Option[String] | Nothing].tag, LTT[Any])\n\n      assertSameStrict(Tag[Matchable | AnyRef | Object | Option[String] | Nothing].tag, LTT[Matchable])\n      assertDebugSame(Tag[Matchable | AnyRef | Object | Option[String] | Nothing].tag, LTT[Matchable])\n\n      assertSameStrict(Tag[AnyRef | Object | Option[String] | Nothing].tag, LTT[AnyRef])\n      assertDebugSame(Tag[AnyRef | Object | Option[String] | Nothing].tag, LTT[AnyRef])\n\n      assertSameStrict(Tag[Object | Option[String] | Nothing].tag, LTT[Object])\n      assertDebugSame(Tag[Object | Option[String] | Nothing].tag, LTT[Object])\n\n      assertSameStrict(Tag[Option[String] | Nothing].tag, LTT[Option[String]])\n      assertDebugSame(Tag[Option[String] | Nothing].tag, LTT[Option[String]])\n    }\n\n    \"support top-level abstract types (Scala 3 specific, top level type aliases)\" in {\n      assertChildStrict(LTT[LightTypeTagTestT], LTT[String])\n    }\n\n    \"support opaque types\" in {\n      object x {\n        type T >: List[Int] <: List[Int]\n        opaque type Opaque = List[Int]\n        opaque type OpaqueSub <: List[Int] = List[Int]\n      }\n\n      assertNotChildStrict(LTT[x.Opaque], LTT[List[Int]])\n      assertNotChildStrict(LTT[x.Opaque], LTT[Seq[Int]])\n      assertNotChildStrict(LTT[x.Opaque], LTT[x.T])\n      assertNotChildStrict(LTT[x.Opaque], LTT[x.OpaqueSub])\n\n      assertChildStrict(LTT[x.OpaqueSub], LTT[List[Int]])\n      assertChildStrict(LTT[x.OpaqueSub], LTT[Seq[Int]])\n      assertChildStrict(LTT[x.T], LTT[Seq[Int]])\n      assertChildStrict(LTT[x.OpaqueSub], LTT[x.T])\n      assertDifferent(LTT[x.OpaqueSub], LTT[x.T])\n    }\n\n    \"basic support for polymorphic function types\" in {\n      val t1 = LTT[[A] => A => A]\n      val t2 = LTT[[B] => B => B]\n      assertSameStrict(t1, t2)\n    }\n\n  }\n}\n\ntype LightTypeTagTestT <: String\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/PlatformSpecific.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.test\n\nimport izumi.reflect.dottyreflection.Inspect\nimport izumi.reflect.macrortti.LightTypeTag\n\nobject PlatformSpecific {\n  inline def fromRuntime[T]: LightTypeTag = Inspect.inspect[T]\n  inline def fromRuntime[T](loud: Boolean): LightTypeTag = Inspect.inspect[T]\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/Scala2MinorVersion.scala",
    "content": "package izumi.reflect.test\n\nobject Scala2MinorVersion {\n  def scala2MinorVersion: Int = -1\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/TagProgressionTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.Tag\nimport izumi.reflect.test.TestModel.*\n\nclass TagProgressionTest extends SharedTagProgressionTest {\n\n  \"[progression] Tag (Dotty)\" should {\n\n    // Can't fix this atm because simplification happens even without .simplified call because of https://github.com/lampepfl/dotty/issues/17544\n    \"progression test: fails to don't lose tautological union components other than Nothing\" in {\n      def tag1[T: Tag]: Tag[T | Trait1] = Tag[T | Trait1]\n      def tag4[T: Tag]: Tag[T | Trait4] = Tag[T | Trait4]\n\n      val t1 = tag1[Trait3[Dep]].tag\n      val t2 = tag4[Trait3[Dep]].tag\n\n      val t10 = Tag[Trait3[Dep] | Trait1].tag\n      val t20 = Tag[Trait3[Dep] | Trait4].tag\n\n      brokenOnScala3 {\n        assertSameStrict(t1, t10)\n        assertDebugSame(t1, t10)\n      }\n\n      assertSameStrict(t2, t20)\n      assertDebugSame(t2, t20)\n    }\n\n    // We don't really want to fix it, because removing tautologies is quadratic, with two subtyping comparisions per step!\n    // Would make construction really expensive, all for an extremely rare corner case\n    \"progression test: union tautologies are not removed automatically when constructing combined union type\" in {\n      def tag1[T: Tag]: Tag[T | Trait1] = Tag[T | Trait1]\n\n      val t1 = tag1[Trait3[Dep]].tag\n\n      val t10 = t1.removeUnionTautologies\n\n      brokenOnScala3 {\n        assertSameStrict(t1, t10)\n        assertDebugSame(t1, t10)\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect/src/test/scala-3/izumi/reflect/test/TagTest.scala",
    "content": "package izumi.reflect.test\n\nimport izumi.reflect.macrortti.{LTT, LTag}\nimport izumi.reflect.{HKTag, Tag, TagK, TagTK}\nimport izumi.reflect.test.ID.*\nimport izumi.reflect.test.PlatformSpecific.fromRuntime\nimport izumi.reflect.test.TestModel.{Trait1, Trait3, Trait4}\nimport org.scalatest.exceptions.TestFailedException\n\nclass TagTest extends SharedTagTest with TagAssertions {\n\n  override final val tagZ = Tag[String]\n\n  trait Trait1 {\n    def dep: Dep\n  }\n  trait Trait3[T <: Dep] extends Trait1 {\n    def dep: T\n  }\n\n  \"Tag (Dotty)\" should {\n\n    \"Support union subtyping (Scala 3 specific, union types)\" in {\n      trait Animal\n      trait Dog extends Animal\n      assertChild(Tag[Dog].tag, Tag[Animal].tag)\n      assertChild(Tag[Dog | String].tag, Tag[Animal | String].tag)\n      assertNotChild(Tag[Animal | String].tag, Tag[Dog | String].tag)\n    }\n\n    \"Can create custom type tags to support bounded generics, e.g. <: Dep in TagK (Scala 3 HKTag Syntax)\" in {\n      type `TagK<:Dep`[K[_ <: Dep]] = Tag[K]\n\n      implicitly[`TagK<:Dep`[Trait3]].tag.withoutArgs =:= LTag[Trait3[Nothing]].tag.withoutArgs\n    }\n\n    \"combine union types (Scala 3 specific, union types)\" in {\n      def t1[A: Tag] = Tag[String | A]\n      def t2[A: Tag, B: Tag] = Tag[A | B]\n\n      assertSameStrict(t1[Int].tag, Tag[Int | String].tag)\n      assertSameStrict(t2[Int, String].tag, Tag[String | Int].tag)\n      assertSameStrict(t1[String].tag, Tag[String].tag)\n      assertSameStrict(t2[String, String].tag, Tag[String].tag)\n    }\n\n    \"type tags with bounds are successfully requested by TagMacro\" in {\n      type `TagK<:Dep`[K[_ <: Dep]] = Tag.auto.T[K]\n\n      def t[T[_ <: Dep]: `TagK<:Dep`, A <: Dep: Tag] = Tag[T[A]]\n\n      assertSameStrict(t[Trait3, Dep].tag, Tag[Trait3[Dep]].tag)\n    }\n\n    \"remove tautological unions with Nothing (LTT)\" in {\n      assertSameStrict(LTT[Nothing | Option[String]], LTT[Option[String]])\n    }\n\n    \"remove tautological unions with Nothing (Tag)\" in {\n      assertSameStrict(Tag[Nothing | Option[String]].tag, LTT[Option[String]])\n    }\n\n    \"combine intersection path-dependent intersection types with inner tags works on Scala 3\" in {\n      trait PDT {\n        type T\n        implicit def tag: Tag[T]\n\n        def badCombine(that: PDT): Tag[T with that.T] = {\n          Tag[T with that.T]\n        }\n        def goodCombine(that: PDT): Tag[T with that.T] = {\n          import that.tag\n          Tag[T with that.T]\n        }\n      }\n      def PDT[U: Tag]: PDT = new PDT { type T = U; override val tag: Tag[U] = Tag[U] }\n\n      val badCombine = PDT[Int].badCombine(PDT[Unit])\n      assertSameStrict(badCombine.tag, Tag[Int with Unit].tag)\n\n      val goodCombine = PDT[Int].goodCombine(PDT[Unit])\n      assertSameStrict(goodCombine.tag, Tag[Int with Unit].tag)\n    }\n\n  }\n\n}\n\ntrait Layer[A] {\n  def tag: Tag[A]\n}\n\nobject Layer {\n  def succeed[A: Tag](value: => A): Layer[A] =\n    new Layer[A] {\n      override def tag: Tag[A] = implicitly\n    }\n}\n\n// should compile\n// Example from here: https://github.com/zio/zio/issues/6071\nobject CachedRefinedTypeExample {\n\n  trait Animal\n  trait Dog extends Animal\n\n  trait Service {\n    def animal: Animal\n  }\n\n  val layer =\n    Layer.succeed {\n      new Service {\n        def animal: Dog = new Dog {}\n      }\n    }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.js/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/ReferenceEquality.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nprivate[boopickle] object ReferenceEquality {\n  @inline def eq(a: AnyRef, b: AnyRef): Boolean = a eq b\n  @inline def ne(a: AnyRef, b: AnyRef): Boolean = a ne b\n  @inline def identityHashCode(obj: AnyRef): Int = System.identityHashCode(obj)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.js/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/StringCodec.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\nimport java.nio.charset.StandardCharsets\n\nimport scala.scalajs.js\nimport scala.scalajs.js.annotation.JSGlobal\nimport scala.scalajs.js.typedarray.TypedArrayBufferOps._\nimport scala.scalajs.js.typedarray._\n\n/**\n  * This is a fork-point from original `boopickle` codebase.\n  *\n  * LightTypeTags are encoded at compile-time and decoded at run-time,\n  * but Scala does not use the JVM version of the artifact to run macros\n  * from. Instead it tries to run the Scala.js version compiled for JVM,\n  * but the optimized encoder in boopickle is using native JavaScript classes\n  * so it can't work.\n  *\n  * Here we include both the JVM and JS versions of StringCodec and use the JVM\n  * version for encode* methods and JS version for decode* methods.\n  */\nprivate[reflect] object StringCodec extends StringCodecBase {\n  @inline override def decodeFast(len: Int, buf: ByteBuffer): String = {\n    JSStringCodec.decodeFast(len, buf)\n  }\n\n  @inline override def decodeUTF8(len: Int, buf: ByteBuffer): String = {\n    JSStringCodec.decodeUTF8(len, buf)\n  }\n\n  @inline override def decodeUTF16(len: Int, buf: ByteBuffer): String = {\n    JSStringCodec.decodeUTF16(len, buf)\n  }\n\n  @inline override def encodeUTF8(str: String): ByteBuffer = {\n    JVMStringCodec.encodeUTF8(str)\n  }\n\n  @inline override def encodeUTF16(str: String): ByteBuffer = {\n    JVMStringCodec.encodeUTF16(str)\n  }\n}\n\n/**\n  * This is a fork-point from original `boopickle` codebase.\n  *\n  * ByteBufferProvider is only used for encoding. JVM encoder is incompatible with `DirectByteBufferProvider`,\n  * so use `HeapByteBufferProvider`\n  */\nprivate[reflect] object DefaultByteBufferProvider extends DefaultByteBufferProviderFuncs {\n//  override def provider = new DirectByteBufferProvider\n  override def provider = new HeapByteBufferProvider\n}\n\nprivate[boopickle] object JVMStringCodec extends StringCodecBase {\n  override def decodeUTF8(len: Int, buf: ByteBuffer): String = {\n    val a = new Array[Byte](len)\n    buf.get(a)\n    new String(a, StandardCharsets.UTF_8)\n  }\n\n  override def encodeUTF8(str: String): ByteBuffer = {\n    ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))\n  }\n\n  override def decodeUTF16(len: Int, buf: ByteBuffer): String = {\n    val a = new Array[Byte](len)\n    buf.get(a)\n    new String(a, StandardCharsets.UTF_16LE)\n  }\n\n  override def encodeUTF16(str: String): ByteBuffer = {\n    ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_16LE))\n  }\n}\n\n/**\n  * Facade for native JS engine provided TextDecoder\n  */\n@js.native\n@JSGlobal\nprivate[boopickle] class TextDecoder(utfLabel: js.UndefOr[String] = js.undefined) extends js.Object {\n  def decode(data: ArrayBufferView): String = js.native\n}\n\n/**\n  * Facade for native JS engine provided TextEncoder\n  */\n@js.native\n@JSGlobal\nprivate[boopickle] class TextEncoder(utfLabel: js.UndefOr[String] = js.undefined) extends js.Object {\n  def encode(str: String): Int8Array = js.native\n}\n\nprivate[boopickle] object JSStringCodec extends StringCodecBase {\n  private lazy val utf8decoder: (Int8Array) => String = {\n    val td = new TextDecoder\n    // use native TextDecoder\n    (data: Int8Array) => td.decode(data)\n  }\n\n  private lazy val utf8encoder: (String) => Int8Array = {\n    val te = new TextEncoder\n    // use native TextEncoder\n    (str: String) => new Int8Array(te.encode(str))\n  }\n\n  private lazy val utf16decoder: (Uint16Array) => String = {\n    /*\n      try {\n          // do not use native TextDecoder as it's slow\n          val td = new TextDecoder(\"utf-16none\")\n          (data: Uint16Array) => td.decode(data)\n        } catch {\n          case e: Throwable =>\n     */\n    (data: Uint16Array) =>\n      js.Dynamic.global.String.fromCharCode.applyDynamic(\"apply\")(null, data).asInstanceOf[String]\n  }\n\n  private lazy val utf16encoder: (String) => Int8Array = {\n    /*\n      try {\n          // do not use native TextEncoder as it's slow\n          val te = new TextEncoder(\"utf-16none\")\n          (str: String) => te.encode(str)\n        } catch {\n          case e: Throwable =>\n          }\n     */\n    (str: String) =>\n      {\n        val ta = new Uint16Array(str.length)\n        var i = 0\n        while (i < str.length) {\n          ta(i) = str.charAt(i).toInt\n          i += 1\n        }\n        new Int8Array(ta.buffer)\n      }\n  }\n\n  override def decodeUTF8(len: Int, buf: ByteBuffer): String = {\n    if (buf.isDirect && !js.isUndefined(js.Dynamic.global.TextDecoder)) {\n      // get the underlying Int8Array\n      val ta = buf.typedArray()\n      val s = utf8decoder(ta.subarray(buf.position(), buf.position() + len))\n      (buf: java.nio.Buffer).position(buf.position() + len)\n      s\n    } else {\n      val a = new Array[Byte](len)\n      buf.get(a)\n      new String(a, StandardCharsets.UTF_8)\n    }\n  }\n\n  override def encodeUTF8(str: String): ByteBuffer = {\n    if (js.isUndefined(js.Dynamic.global.TextEncoder)) {\n      ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))\n    } else {\n      TypedArrayBuffer.wrap(utf8encoder(str))\n    }\n  }\n\n  override def decodeUTF16(len: Int, buf: ByteBuffer): String = {\n    if (buf.isDirect) {\n      val ta = new Uint16Array(buf.typedArray().buffer, buf.position() + buf.typedArray().byteOffset, len / 2)\n      (buf: java.nio.Buffer).position(buf.position() + len)\n      utf16decoder(ta)\n      // new String(ta.toArray) // alt implementation\n    } else {\n      val a = new Array[Byte](len)\n      buf.get(a)\n      new String(a, StandardCharsets.UTF_16LE)\n    }\n  }\n\n  override def encodeUTF16(str: String): ByteBuffer = {\n    TypedArrayBuffer.wrap(utf16encoder(str))\n  }\n\n  override def decodeFast(len: Int, buf: ByteBuffer): String = {\n    if (buf.hasArray)\n      decodeFastArray(len, buf)\n    else\n      decodeFastTypedArray(len, buf)\n  }\n\n  override def encodeFast(s: String, bb: ByteBuffer): Unit = {\n    if (bb.hasArray)\n      encodeFastArray(s, bb)\n    else\n      encodeFastTypedArray(s, bb)\n  }\n\n  protected def encodeFastTypedArray(s: String, bb: ByteBuffer): Unit = {\n    val len = s.length()\n    val buf = bb.typedArray()\n    var dst = bb.position()\n    var src = 0\n    var c: Char = ' '\n    // start by encoding ASCII only\n    while ((src < len) && { c = s.charAt(src); c < 0x80 }) {\n      buf(dst) = c.toByte\n      src += 1\n      dst += 1\n    }\n\n    // next stage, encode also non-ASCII\n    while (src < len) {\n      c = s.charAt(src)\n      if (c < 0x80) {\n        buf(dst) = c.toByte\n        dst += 1\n      } else if (c < 0x4000) {\n        buf(dst) = (0x80 | (c & 0x3F)).toByte\n        buf(dst + 1) = (c >> 6 & 0xFF).toByte\n        dst += 2\n      } else {\n        buf(dst) = (0xC0 | (c & 0x3F)).toByte\n        buf(dst + 1) = (c >> 6 & 0xFF).toByte\n        buf(dst + 2) = (c >> 14).toByte\n        dst += 3\n      }\n      src += 1\n    }\n    (bb: java.nio.Buffer).position(dst)\n  }\n\n  private def charArray2String(chars: js.Array[Int], offset: Int, len: Int): String = {\n    // for some reason, on Chrome, calling `cp.jsSlice` makes `fromCharCode` 2-3x faster!\n    js.Dynamic.global.String.fromCharCode\n      .applyDynamic(\"apply\")(null, chars.jsSlice(offset, offset + len))\n      .asInstanceOf[String]\n  }\n\n  protected def decodeFastTypedArray(len: Int, buf: ByteBuffer): String = {\n    val cp = new js.Array[Int](len)\n    val src = buf.typedArray()\n    var offset = buf.position()\n    var dst = 0\n    while (dst < len) {\n      val b = src(offset) & 0xFF\n      offset += 1\n      if ((b & 0x80) == 0) {\n        cp(dst) = b\n      } else if ((b & 0xC0) == 0x80) {\n        val b1 = src(offset) & 0xFF\n        offset += 1\n        cp(dst) = b & 0x3F | b1 << 6\n      } else {\n        val b1 = src(offset) & 0xFF\n        val b2 = src(offset + 1) & 0xFF\n        offset += 2\n        cp(dst) = b & 0x3F | b1 << 6 | b2 << 14\n      }\n      dst += 1\n    }\n    (buf: java.nio.Buffer).position(offset)\n\n    // for really long strings, convert in pieces to avoid JS engine overflows\n    if (len > 4096) {\n      offset = 0\n      var s = \"\"\n      while (offset < len) {\n        s += charArray2String(cp, offset, math.min(4096, len - offset))\n        offset += 4096\n      }\n      s\n    } else {\n      charArray2String(cp, 0, len)\n    }\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.jvm/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/DefaultByteBufferProvider.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nprivate[reflect] object DefaultByteBufferProvider extends DefaultByteBufferProviderFuncs {\n  override def provider = new HeapByteBufferProvider\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.jvm/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/ReferenceEquality.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nprivate[boopickle] object ReferenceEquality {\n  @inline def eq(a: AnyRef, b: AnyRef): Boolean = a eq b\n  @inline def ne(a: AnyRef, b: AnyRef): Boolean = a ne b\n  @inline def identityHashCode(obj: AnyRef): Int = System.identityHashCode(obj)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.jvm/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/StringCodec.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\nimport java.nio.charset.StandardCharsets\n\nprivate[reflect] object StringCodec extends StringCodecBase {\n  override def decodeUTF8(len: Int, buf: ByteBuffer): String = {\n    val a = new Array[Byte](len)\n    buf.get(a)\n    new String(a, StandardCharsets.UTF_8)\n  }\n\n  override def encodeUTF8(str: String): ByteBuffer = {\n    ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))\n  }\n\n  override def decodeUTF16(len: Int, buf: ByteBuffer): String = {\n    val a = new Array[Byte](len)\n    buf.get(a)\n    new String(a, StandardCharsets.UTF_16LE)\n  }\n\n  override def encodeUTF16(str: String): ByteBuffer = {\n    ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_16LE))\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.native/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/DefaultByteBufferProvider.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nobject DefaultByteBufferProvider extends DefaultByteBufferProviderFuncs {\n  override def provider = new HeapByteBufferProvider\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.native/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/ReferenceEquality.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nobject ReferenceEquality {\n  @inline def eq(a: AnyRef, b: AnyRef): Boolean = a == b\n  @inline def ne(a: AnyRef, b: AnyRef): Boolean = a != b\n  @inline def identityHashCode(obj: AnyRef): Int = obj.hashCode()\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/.native/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/StringCodec.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\nimport java.nio.charset.StandardCharsets\n\nobject StringCodec extends StringCodecBase {\n  override def decodeUTF8(len: Int, buf: ByteBuffer): String = {\n    val a = new Array[Byte](len)\n    buf.get(a)\n    new String(a, StandardCharsets.UTF_8)\n  }\n\n  override def encodeUTF8(str: String): ByteBuffer = {\n    ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))\n  }\n\n  override def decodeUTF16(len: Int, buf: ByteBuffer): String = {\n    val a = new Array[Byte](len)\n    buf.get(a)\n    new String(a, StandardCharsets.UTF_16LE)\n  }\n\n  override def encodeUTF16(str: String): ByteBuffer = {\n    ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_16LE))\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/BufferPool.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\nimport java.util.concurrent.atomic.AtomicInteger\n\nprivate[reflect] object BufferPool {\n\n  // two pools for two different size categories\n  private final val poolEntrySize0 = ByteBufferProvider.initSize\n  private final val poolEntrySize1 = ByteBufferProvider.expandSize + 16\n  // maximum size of a ByteBuffer to be included in a pool\n  private final val maxBufferSize = poolEntrySize1 * 2\n  private final val entryCount = 1024\n\n  private var disablePool = false\n\n  final class Pool {\n    private val pool0 = new Array[ByteBuffer](entryCount)\n    private val pool1 = new Array[ByteBuffer](entryCount)\n    private val allocIdx0 = new AtomicInteger(0)\n    private val allocIdx1 = new AtomicInteger(0)\n    private val releaseIdx0 = new AtomicInteger(0)\n    private val releaseIdx1 = new AtomicInteger(0)\n\n    // for collecting some performance characteristics\n    var allocOk = 0\n    var allocMiss = 0\n\n    def allocate(minSize: Int): Option[ByteBuffer] = {\n      if (disablePool) {\n        None\n      } else if (minSize > poolEntrySize1) {\n        allocMiss += 1\n        None\n      } else if (minSize > poolEntrySize0 || allocIdx0.get() == releaseIdx0.get()) {\n        // allocate from pool1\n        val aIdx = allocIdx1.get()\n        val rIdx = releaseIdx1.get()\n        val aNext = (aIdx + 1) % entryCount\n        if (aIdx != rIdx) {\n          // try to allocate\n          val result = Some(pool1(aNext))\n          if (allocIdx1.compareAndSet(aIdx, aNext)) {\n            allocOk += 1\n            result\n          } else {\n            allocMiss += 1\n            None\n          }\n        } else {\n          allocMiss += 1\n          None\n        }\n      } else {\n        // allocate from pool0\n        val aIdx = allocIdx0.get()\n        val rIdx = releaseIdx0.get()\n        val aNext = (aIdx + 1) % entryCount\n        if (aIdx != rIdx) {\n          // try to allocate\n          val result = Some(pool0(aNext))\n          if (allocIdx0.compareAndSet(aIdx, aNext)) {\n            allocOk += 1\n            result\n          } else {\n            allocMiss += 1\n            None\n          }\n        } else {\n          allocMiss += 1\n          None\n        }\n      }\n    }\n\n    def release(bb: ByteBuffer): Unit = {\n      if (!disablePool) {\n        // do not take large buffers into the pool, as their reallocation is relatively cheap\n        val bufSize = bb.capacity\n        if (bufSize < maxBufferSize && bufSize >= poolEntrySize0) {\n          if (bufSize >= poolEntrySize1) {\n            val aIdx = allocIdx1.get()\n            val rIdx = releaseIdx1.get()\n            val rNext = (rIdx + 1) % entryCount\n            if (rNext != aIdx) {\n              // try to release the buffer\n              (bb: java.nio.Buffer).clear()\n              pool1(rNext) = bb\n              releaseIdx1.compareAndSet(rIdx, rNext)\n              ()\n            }\n          } else {\n            val aIdx = allocIdx0.get()\n            val rIdx = releaseIdx0.get()\n            val rNext = (rIdx + 1) % entryCount\n            if (rNext != aIdx) {\n              // try to release the buffer\n              (bb: java.nio.Buffer).clear()\n              pool0(rNext) = bb\n              releaseIdx0.compareAndSet(rIdx, rNext)\n              ()\n            }\n          }\n        }\n      }\n    }\n  }\n\n  val heapPool = new Pool\n  val directPool = new Pool\n\n  def allocate(minSize: Int): Option[ByteBuffer] = {\n    heapPool.allocate(minSize)\n  }\n\n  def allocateDirect(minSize: Int): Option[ByteBuffer] = {\n    directPool.allocate(minSize)\n  }\n\n  def release(bb: ByteBuffer): Unit = {\n    if (bb.isDirect)\n      directPool.release(bb)\n    else\n      heapPool.release(bb)\n  }\n\n  def isDisabled = disablePool\n\n  def disable(): Unit = disablePool = true\n\n  def enable(): Unit = disablePool = false\n\n  def allocOk = heapPool.allocOk + directPool.allocOk\n  def allocMiss = heapPool.allocMiss + directPool.allocMiss\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/BufferProvider.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.{ByteBuffer, ByteOrder}\n\nprivate[reflect] trait BufferProvider {\n\n  /**\n    * Makes sure the ByteBuffer has enough space for new data. If not, allocates a new ByteBuffer\n    * and returns it. The returned ByteBuffer must have little-endian ordering.\n    *\n    * @param size Number of bytes needed for new data\n    * @return\n    */\n  def alloc(size: Int): ByteBuffer\n\n  /**\n    * Completes the encoding and returns the ByteBuffer, merging the chain of buffers if necessary\n    *\n    * @return\n    */\n  def asByteBuffer: ByteBuffer\n}\n\nprivate[reflect] abstract class ByteBufferProvider extends BufferProvider {\n  import ByteBufferProvider._\n  protected val pool = BufferPool\n  protected var buffers: List[ByteBuffer] = Nil\n  protected var currentBuf: ByteBuffer = allocate(initSize)\n\n  protected def allocate(size: Int): ByteBuffer\n\n  final private def newBuffer(size: Int): Unit = {\n    // flip current buffer (prepare for reading and set limit)\n    (currentBuf: java.nio.Buffer).flip()\n    buffers = currentBuf :: buffers\n    // replace current buffer with the new one, align to 16-byte border for small sizes\n    currentBuf = allocate((math.max(size, expandSize) & ~15) + 16)\n  }\n\n  @inline final def alloc(size: Int): ByteBuffer = {\n    if (currentBuf.remaining() < size)\n      newBuffer(size)\n    currentBuf\n  }\n\n  def asByteBuffer = {\n    (currentBuf: java.nio.Buffer).flip()\n    if (buffers.isEmpty) currentBuf\n    else {\n      val bufList = (currentBuf :: buffers).reverse\n      // create a new buffer and combine all buffers into it\n      val comb = allocate(bufList.map(_.limit()).sum)\n      bufList.foreach(buf => comb.put(buf))\n      (comb: java.nio.Buffer).flip()\n      comb\n    }\n  }\n}\n\nprivate[reflect] object ByteBufferProvider {\n  final val initSize = 512\n  final val expandSize = initSize * 8\n}\n\nprivate[reflect] class HeapByteBufferProvider extends ByteBufferProvider {\n  override protected def allocate(size: Int) = {\n    if (pool.isDisabled)\n      ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN)\n    else\n      pool.allocate(size).getOrElse(ByteBuffer.allocate(size).order(ByteOrder.LITTLE_ENDIAN))\n  }\n\n  override def asByteBuffer = {\n    (currentBuf: java.nio.Buffer).flip()\n    if (buffers.isEmpty) currentBuf\n    else {\n      // create a new buffer and combine all buffers into it\n      val bufList = (currentBuf :: buffers).reverse\n      val comb = allocate(bufList.map(_.limit()).sum)\n      bufList.foreach {\n        buf =>\n          // use fast array copy\n          java.lang.System.arraycopy(buf.array(), buf.arrayOffset(), comb.array(), comb.position(), buf.limit())\n          (comb: java.nio.Buffer).position(comb.position() + buf.limit())\n          // release to the pool\n          pool.release(buf)\n      }\n      (comb: java.nio.Buffer).flip()\n      comb\n    }\n  }\n}\n\nprivate[reflect] trait DefaultByteBufferProviderFuncs {\n  def provider: ByteBufferProvider\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/CodecSize.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\n\nprivate[reflect] class DecoderSize(val buf: ByteBuffer) extends Decoder {\n  val stringCodec: StringCodecBase = StringCodec\n\n  /** Decodes a single byte\n    *\n    * @return\n    */\n  def readByte: Byte = {\n    buf.get\n  }\n\n  /** Decodes a 32-bit integer (1-5 bytes)\n    * <pre>\n    * 0XXX XXXX                            = 0 to 127\n    * 1000 XXXX  b0                        = 128 to 4095\n    * 1001 XXXX  b0                        = -1 to -4095\n    * 1010 XXXX  b0 b1                     = 4096 to 1048575\n    * 1011 XXXX  b0 b1                     = -4096 to -1048575\n    * 1100 XXXX  b0 b1 b2                  = 1048576 to 268435455\n    * 1101 XXXX  b0 b1 b2                  = -1048576 to -268435455\n    * 1110 0000  b0 b1 b2 b3               = MinInt to MaxInt\n    * 1111 ????                            = reserved for special codings\n    * </pre>\n    *\n    * @return\n    */\n  def readInt: Int = {\n    val b = buf.get & 0xFF\n    if ((b & 0x80) != 0) {\n      // special coding, expand sign bit\n      val sign = if ((b & 0x10) == 0) 1 else -1\n      val b0 = b & 0xF\n      b >> 4 match {\n        case 0x8 | 0x9 =>\n          val b1 = buf.get & 0xFF\n          sign * (b0 << 8 | b1)\n        case 0xA | 0xB =>\n          val b1 = buf.get & 0xFF\n          val b2 = buf.get & 0xFF\n          sign * (b0 << 16 | b1 << 8 | b2)\n        case 0xC | 0xD =>\n          val b1 = buf.get & 0xFF\n          val b2 = buf.get & 0xFF\n          val b3 = buf.get & 0xFF\n          sign * (b0 << 24 | b1 << 16 | b2 << 8 | b3)\n        case 0xE if b == 0xE0 =>\n          sign * readRawInt\n        case _ =>\n          throw new IllegalArgumentException(\"Unknown integer coding\")\n      }\n    } else {\n      b\n    }\n  }\n\n  def readRawInt: Int = {\n    buf.getInt\n  }\n\n  /** Decodes a UTF-8 encoded string\n    *\n    * @return\n    */\n  def readString: String = {\n    // read string length\n    val len = readInt\n    stringCodec.decodeFast(len, buf)\n  }\n\n  /** Decodes a UTF-8 encoded string whose length is already known\n    *\n    * @param len Length of the string (in bytes)\n    * @return\n    */\n  def readString(len: Int): String = {\n    stringCodec.decodeFast(len, buf)\n  }\n\n}\n\nprivate[reflect] class EncoderSize(bufferProvider: BufferProvider = DefaultByteBufferProvider.provider) extends Encoder {\n  val stringCodec: StringCodecBase = StringCodec\n\n  @inline private def alloc(size: Int): ByteBuffer = bufferProvider.alloc(size)\n\n  /** Encodes a single byte\n    *\n    * @param b Byte to encode\n    * @return\n    */\n  def writeByte(b: Byte): Encoder = {\n    alloc(1).put(b)\n    this\n  }\n\n  /** Encodes an integer efficiently in 1 to 5 bytes\n    * <pre>\n    * 0XXX XXXX                            = 0 to 127\n    * 1000 XXXX  b0                        = 128 to 4095\n    * 1001 XXXX  b0                        = -1 to -4095\n    * 1010 XXXX  b0 b1                     = 4096 to 1048575\n    * 1011 XXXX  b0 b1                     = -4096 to -1048575\n    * 1100 XXXX  b0 b1 b2                  = 1048575 to 268435455\n    * 1101 XXXX  b0 b1 b2                  = -1048575 to -268435455\n    * 1110 0000  b0 b1 b2 b3               = MinInt to MaxInt\n    * 1111 ????                            = reserved for special codings\n    * </pre>\n    *\n    * @param i Integer to encode\n    */\n  def writeInt(i: Int): Encoder = {\n    // check for a short number\n    if (i >= 0 && i < 128) {\n      alloc(1).put(i.toByte)\n    } else {\n      if (i > -268435456 && i < 268435456) {\n        val mask = i >>> 31 << 4\n        val a = Math.abs(i)\n        if (a < 4096) {\n          alloc(2).put((mask | 0x80 | (a >> 8)).toByte).put((a & 0xFF).toByte)\n        } else if (a < 1048576) {\n          alloc(3).put((mask | 0xA0 | (a >> 16)).toByte).put(((a >> 8) & 0xFF).toByte).put((a & 0xFF).toByte)\n        } else {\n          alloc(4)\n            .put((mask | 0xC0 | (a >> 24)).toByte)\n            .put(((a >> 16) & 0xFF).toByte)\n            .put(((a >> 8) & 0xFF).toByte)\n            .put((a & 0xFF).toByte)\n        }\n      } else {\n        alloc(5).put(0xE0.toByte).putInt(i)\n      }\n    }\n    this\n  }\n\n  /** Encodes a string using UTF8\n    *\n    * @param s String to encode\n    * @return\n    */\n  def writeString(s: String): Encoder = {\n    writeInt(s.length)\n    val bb = alloc(s.length * 3)\n    stringCodec.encodeFast(s, bb)\n    this\n  }\n\n  /** Completes the encoding and returns the ByteBuffer\n    *\n    * @return\n    */\n  def asByteBuffer: ByteBuffer = bufferProvider.asByteBuffer\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/Codecs.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\n\nprivate[reflect] trait Decoder {\n\n  /** Decodes a single byte\n    */\n  def readByte: Byte\n\n  /** Decodes a 32-bit integer\n    */\n  def readInt: Int\n\n  /** Decodes a string\n    */\n  def readString: String\n\n  /** Decodes a string whose length is already known\n    *\n    * @param len Length of the string (in bytes)\n    */\n  def readString(len: Int): String\n}\n\nprivate[reflect] trait Encoder {\n\n  /** Encodes a single byte\n    *\n    * @param b Byte to encode\n    */\n  def writeByte(b: Byte): Encoder\n\n  /** Encodes an integer\n    */\n  def writeInt(i: Int): Encoder\n\n  /** Encodes a string\n    *\n    * @param s String to encode\n    */\n  def writeString(s: String): Encoder\n\n  /** Completes the encoding and returns the ByteBuffer\n    */\n  def asByteBuffer: ByteBuffer\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/CompositePicklers.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport scala.collection.mutable\nimport scala.reflect.ClassTag\n\n/** Encodes a class belonging to a type hierarchy. Type is identified by the index in the `picklers` sequence, so care\n  * must be taken to ensure picklers are added in the same order.\n  */\nprivate[reflect] class CompositePickler[A] extends Pickler[A] {\n\n  import Constants._\n\n  private var picklerClasses = IdentMap.empty\n  private val picklers = mutable.ArrayBuffer.empty[(Class[_], Pickler[_])]\n\n  override def pickle(obj: A)(implicit state: PickleState): Unit = {\n    if (obj == null) {\n      state.enc.writeInt(NullObject)\n    } else {\n      val clz = obj.getClass\n      picklerClasses(clz) match {\n        case None =>\n          throw new IllegalArgumentException(s\"This CompositePickler doesn't know class '${clz.getName}'.\")\n        case Some(idx) =>\n          val pickler = picklers(idx - 2)._2\n          state.enc.writeInt(idx - 1)\n          pickler.asInstanceOf[Pickler[A]].pickle(obj)\n      }\n    }\n  }\n\n  override def unpickle(implicit state: UnpickleState): A = {\n    val idx = state.dec.readInt\n    if (idx == NullObject) null.asInstanceOf[A]\n    else {\n      if (idx < 0 || idx > picklers.size)\n        throw new IllegalStateException(s\"Index $idx is not defined in this CompositePickler\")\n      picklers(idx - 1)._2.asInstanceOf[Pickler[A]].unpickle\n    }\n  }\n\n  private def addPickler[B](pickler: Pickler[B], tag: ClassTag[B]): Unit = {\n    val clz = tag.runtimeClass\n    if (picklerClasses(clz).isDefined)\n      throw new IllegalArgumentException(s\"Cannot add same class (${clz.getName}) twice to a composite pickler\")\n    picklerClasses = picklerClasses.updated(clz)\n    picklers.append((clz, pickler))\n  }\n\n  @noinline def addConcreteType[B <: A](implicit pickler: Pickler[B], tag: ClassTag[B]): CompositePickler[A] = {\n    addPickler(pickler, tag)\n    this\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/Constants.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nprivate[boopickle] object Constants {\n  final val NullRef = -1\n  final val NullObject = 0\n\n  // codes for Option\n  final val OptionNone: Int = 1\n  final val OptionSome: Int = 2\n\n  // common strings that can be used as references\n  val immutableInitData = Seq(\"null\", \"true\", \"false\", \"0\", \"1\", \"-1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\")\n\n  val identityInitData = Seq(None)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/Default.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\nimport java.nio.charset.StandardCharsets\n\nprivate[reflect] trait BasicImplicitPicklers extends PicklerHelper with XCompatImplicitPicklers {\n  implicit def booleanPickler: P[Boolean] = BasicPicklers.BooleanPickler\n  implicit def intPickler: P[Int] = BasicPicklers.IntPickler\n  implicit def stringPickler: P[String] = BasicPicklers.StringPickler\n\n  implicit def optionPickler[T: P]: P[Option[T]] = BasicPicklers.OptionPickler[T]\n}\n\nprivate[reflect] object PickleImpl {\n  @inline def apply[A](value: A)(implicit state: PickleState, p: Pickler[A]): PickleState = {\n    p.pickle(value)(state)\n    state\n  }\n\n  @inline def intoBytes[A](value: A)(implicit state: PickleState, p: Pickler[A]): ByteBuffer = {\n    apply(value).toByteBuffer\n  }\n\n  @inline private[reflect] def serializeIntoString[A](a: A, pickler: Pickler[A]): String = {\n    val pickleState = PickleState.pickleStateSpeed\n    val buf = PickleImpl.intoBytes(a)(pickleState, pickler)\n    new String(buf.array(), buf.arrayOffset(), buf.limit(), StandardCharsets.ISO_8859_1)\n  }\n}\n\nprivate[reflect] trait Base {\n  type Pickler[A] = _root_.izumi.reflect.thirdparty.internal.boopickle.Pickler[A]\n  type PickleState = _root_.izumi.reflect.thirdparty.internal.boopickle.PickleState\n}\n\nprivate[reflect] object NoMacro extends Base with BasicImplicitPicklers with TuplePicklers\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/IdentList.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport scala.collection.mutable\n\n/**\n  * Specialized fast and cheap to initialize identity list for unpickle state identifier refs\n  */\nprivate[reflect] abstract class IdentList {\n  @noinline def apply(idx: Int): AnyRef\n\n  @noinline def updated(obj: AnyRef): IdentList\n}\n\nprivate[reflect] object IdentList {\n\n  private[boopickle] final class Entry(val obj: AnyRef, var next: Entry)\n  private[boopickle] val maxSize = 32\n}\n\nprivate[reflect] object EmptyIdentList extends IdentList {\n  override def apply(idx: Int): AnyRef = throw new IndexOutOfBoundsException\n\n  override def updated(obj: AnyRef): IdentList = new IdentList1Plus(obj)\n}\n\n/**\n  * A fast and simple linked list implementation for identifier list\n  *\n  * @param o1 First object\n  */\nprivate[boopickle] final class IdentList1Plus(o1: AnyRef) extends IdentList {\n  import IdentList.Entry\n  var last: Entry = new Entry(o1, null)\n  var head: Entry = last\n  var switchOver = false\n  var size = 0\n\n  override def apply(idx: Int): AnyRef = {\n    // first time something is looked up, we switch to the more efficient implementation\n    switchOver = true\n    var i = 0\n    var e = head\n    while (i < idx && e != null) {\n      i += 1\n      e = e.next\n    }\n    if (e == null)\n      throw new IndexOutOfBoundsException\n    e.obj\n  }\n\n  override def updated(obj: AnyRef): IdentList = {\n    val e = new Entry(obj, null)\n    last.next = e\n    last = e\n    size += 1\n    if (switchOver || size > IdentList.maxSize)\n      new IdentListBig(head, size)\n    else\n      this\n  }\n}\n\n/**\n  * A more scalable implementation for an identifier list\n  *\n  * @param first First entry in a list of entries\n  */\nprivate[boopickle] final class IdentListBig(first: IdentList.Entry, size: Int) extends IdentList {\n  // transform the linked list into an array buffer\n  val b = mutable.ArrayBuffer.newBuilder[AnyRef]\n  b.sizeHint(size)\n  var e = first\n  while (e != null) {\n    b += e.obj\n    e = e.next\n  }\n  val entries = b.result()\n\n  override def apply(idx: Int): AnyRef = {\n    entries(idx)\n  }\n\n  override def updated(obj: AnyRef): IdentList = {\n    entries += obj\n    this\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/IdentMap.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\n/**\n  * Specialized fast and cheap to initialize identity map for pickle state identifier map\n  */\nprivate[reflect] abstract class IdentMap {\n  def apply(obj: AnyRef): Option[Int]\n\n  def updated(obj: AnyRef): IdentMap\n}\n\nprivate[reflect] object IdentMap {\n  def empty: IdentMap = EmptyIdentMap\n}\n\nprivate[reflect] object EmptyIdentMap extends IdentMap {\n  override def apply(obj: AnyRef): Option[Int] = None\n\n  override def updated(obj: AnyRef): IdentMap = new IdentMap1(obj)\n}\n\nprivate[boopickle] final class IdentMap1(o1: AnyRef) extends IdentMap {\n  override def apply(obj: AnyRef): Option[Int] = {\n    if (ReferenceEquality.eq(obj, o1))\n      Some(2)\n    else None\n  }\n\n  override def updated(obj: AnyRef): IdentMap = new IdentMap2(o1, obj)\n}\n\nprivate[boopickle] final class IdentMap2(o1: AnyRef, o2: AnyRef) extends IdentMap {\n  override def apply(obj: AnyRef): Option[Int] = {\n    if (ReferenceEquality.eq(obj, o1))\n      Some(2)\n    else if (ReferenceEquality.eq(obj, o2))\n      Some(3)\n    else None\n  }\n\n  override def updated(obj: AnyRef): IdentMap = new IdentMap3Plus(o1, o2, obj)\n}\n\nprivate[reflect] object IdentMap3Plus {\n\n  private[boopickle] class Entry(val hash: Int, val obj: AnyRef, val idx: Int, var next: Entry)\n\n}\n\nprivate[boopickle] final class IdentMap3Plus(o1: AnyRef, o2: AnyRef, o3: AnyRef) extends IdentMap {\n  import IdentMap3Plus.Entry\n\n  var hashSize = 64\n  val maxDepth = 1\n  var hashTable = new Array[Entry](hashSize)\n  // indices 0 (not used) and 1 (for null) are reserved\n  var curIdx = 2\n\n  // initialize with data\n  updated(o1)\n  updated(o2)\n  updated(o3)\n\n  @inline private def hashIdx(hash: Int) = {\n    val h = scala.util.hashing.byteswap32(hash)\n    ((h >> 16) ^ (h >> 8) ^ h) & (hashSize - 1)\n  }\n\n  override def apply(obj: AnyRef): Option[Int] = {\n    val hash = ReferenceEquality.identityHashCode(obj)\n    val tableIdx = hashIdx(hash)\n    var e = hashTable(tableIdx)\n    while ((e != null) && ReferenceEquality.ne(e.obj, obj)) e = e.next\n    if (e == null)\n      None\n    else\n      Some(e.idx)\n  }\n\n  override def updated(obj: AnyRef): IdentMap = {\n    val hash = ReferenceEquality.identityHashCode(obj)\n    val tableIdx = hashIdx(hash)\n    hashTable(tableIdx) = new Entry(hash, obj, curIdx, hashTable(tableIdx))\n    curIdx += 1\n    // should we switch to next gear?\n    if (curIdx > hashSize * maxDepth)\n      resize()\n    this\n  }\n\n  /**\n    * Resizes the underlying hash table to make indexing fast as the number of entries grows\n    */\n  private def resize(): Unit = {\n    val newSize = hashSize * 4\n    val newTable = new Array[Entry](newSize)\n    // copy old entries\n    var i = hashSize - 1\n    hashSize = newSize\n    while (i >= 0) {\n      var e = hashTable(i)\n      while (e != null) {\n        val tableIdx = hashIdx(e.hash)\n        val n = e.next\n        e.next = newTable(tableIdx)\n        newTable(tableIdx) = e\n        e = n\n      }\n      i -= 1\n    }\n    hashTable = newTable\n  }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/Pickler.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\nimport scala.collection.mutable\n\nprivate[reflect] trait Pickler[A] {\n  def pickle(obj: A)(implicit state: PickleState): Unit\n  def unpickle(implicit state: UnpickleState): A\n\n  def xmap[B](ab: A => B)(ba: B => A): Pickler[B] = {\n    val self = this\n    new Pickler[B] {\n      override def unpickle(implicit state: UnpickleState): B = {\n        ab(self.unpickle(state))\n      }\n      override def pickle(obj: B)(implicit state: PickleState): Unit = {\n        self.pickle(ba(obj))\n      }\n    }\n  }\n}\n\nprivate[reflect] trait PicklerHelper {\n  protected type P[A] = Pickler[A]\n\n  /** Helper function to write pickled types\n    */\n  protected def write[A](value: A)(implicit state: PickleState, p: P[A]): Unit = p.pickle(value)(state)\n\n  /** Helper function to unpickle a type\n    */\n  protected def read[A](implicit state: UnpickleState, u: P[A]): A = u.unpickle\n}\n\nprivate[reflect] object BasicPicklers extends PicklerHelper with XCompatPicklers {\n\n  import Constants._\n\n  object BooleanPickler extends P[Boolean] {\n    @inline override def pickle(value: Boolean)(implicit state: PickleState): Unit = state.enc.writeByte(if (value) 1 else 0)\n    @inline override def unpickle(implicit state: UnpickleState): Boolean = {\n      state.dec.readByte match {\n        case 1 => true\n        case 0 => false\n        case x => throw new IllegalArgumentException(s\"Invalid value $x for Boolean\")\n      }\n    }\n  }\n\n  object IntPickler extends P[Int] {\n    @inline override def pickle(value: Int)(implicit state: PickleState): Unit = state.enc.writeInt(value)\n    @inline override def unpickle(implicit state: UnpickleState): Int = state.dec.readInt\n  }\n\n  object StringPickler extends P[String] {\n    override def pickle(s: String)(implicit state: PickleState): Unit = {\n      state.immutableRefFor(s) match {\n        case Some(idx) =>\n          state.enc.writeInt(-idx)\n        case None =>\n          if (s.isEmpty) {\n            state.enc.writeInt(0)\n          } else {\n            state.enc.writeString(s)\n            state.addImmutableRef(s)\n          }\n      }\n    }\n\n    override def unpickle(implicit state: UnpickleState): String = {\n      val len = state.dec.readInt\n      if (len < 0) {\n        state.immutableFor[String](-len)\n      } else if (len == 0) {\n        \"\"\n      } else {\n        val s = state.dec.readString(len)\n        state.addImmutableRef(s)\n        s\n      }\n    }\n  }\n\n  def OptionPickler[T: P]: P[Option[T]] = new P[Option[T]] {\n    override def pickle(obj: Option[T])(implicit state: PickleState): Unit = {\n      obj match {\n        case null =>\n          state.enc.writeInt(NullObject)\n        case Some(x) =>\n          state.enc.writeInt(OptionSome.toInt)\n          write[T](x)\n        case None =>\n          // `None` is always encoded as zero\n          state.enc.writeInt(OptionNone.toInt)\n      }\n    }\n\n    override def unpickle(implicit state: UnpickleState): Option[T] = {\n      state.dec.readInt match {\n        case NullObject =>\n          null\n        case OptionSome =>\n          val o = Some(read[T])\n          o\n        case OptionNone =>\n          None\n        case _ =>\n          throw new IllegalArgumentException(\"Invalid coding for Option type\")\n      }\n    }\n  }\n\n}\n\n/** Manage state for a pickling \"session\".\n  *\n  * @param enc            Encoder instance to use\n  * @param dedupImmutable Set to `false` if you want to disable deduplication of immutable values (like Strings)\n  */\nprivate[reflect] final class PickleState(val enc: Encoder, dedupImmutable: Boolean = true) {\n\n  @inline def identityRefFor(obj: AnyRef): Option[Int] = None\n\n  @inline def addIdentityRef(obj: AnyRef): Unit = ()\n\n  /** Object reference for immutable pickled objects\n    */\n  private[this] var immutableRefs: mutable.AnyRefMap[AnyRef, Int] = null\n  private[this] var immutableIdx = 2\n\n  @inline def immutableRefFor(obj: AnyRef): Option[Int] = {\n    if (obj == null)\n      Some(1)\n    else if (!dedupImmutable)\n      None\n    else if (immutableRefs != null)\n      immutableRefs.get(obj)\n    else\n      None\n  }\n\n  @inline def addImmutableRef(obj: AnyRef): Unit = {\n    if (dedupImmutable) {\n      if (immutableRefs == null)\n        immutableRefs = mutable.AnyRefMap.empty\n      immutableRefs.update(obj, immutableIdx)\n      immutableIdx += 1\n    }\n  }\n\n  @inline def pickle[A](value: A)(implicit p: Pickler[A]): PickleState = {\n    p.pickle(value)(this)\n    this\n  }\n\n  def toByteBuffer: ByteBuffer = enc.asByteBuffer\n}\n\nprivate[reflect] object PickleState {\n\n  /** Provides a default PickleState if none is available implicitly\n    *\n    * @return\n    */\n  implicit def pickleStateSpeed: PickleState = new PickleState(new EncoderSize, dedupImmutable = true)\n}\n\n/** Manage state for an unpickling \"session\"\n  *\n  * @param dec            Decoder instance to use\n  * @param deduplicate    Set to `false` if you want to disable deduplication\n  * @param dedupImmutable Set to `false` if you want to disable deduplication of immutable values (like Strings)\n  */\nprivate[reflect] final class UnpickleState(val dec: Decoder, deduplicate: Boolean = true, dedupImmutable: Boolean = true) {\n\n  /** Object reference for pickled objects (use identity for equality comparison)\n    *\n    * Index 0 is not used\n    * Index 1 = null\n    * Index 2-n, references to pickled objects\n    */\n  private[this] var identityRefs: IdentList = EmptyIdentList\n\n  @noinline def codingError(code: Int): Nothing = {\n    throw new IllegalArgumentException(s\"Unknown object coding: $code\")\n  }\n\n  @noinline def identityFor[A <: AnyRef](ref: Int): A = {\n    if (ref < 2)\n      null.asInstanceOf[A]\n    else if (!deduplicate)\n      throw new Exception(\"Deduplication is disabled, but identityFor was called.\")\n    else\n      identityRefs(ref - 2).asInstanceOf[A]\n  }\n\n  @inline def addIdentityRef(obj: AnyRef): Unit =\n    if (deduplicate)\n      identityRefs = identityRefs.updated(obj)\n\n  /** Object reference for immutable pickled objects\n    */\n  private[this] var immutableRefs: IdentList = EmptyIdentList\n\n  @noinline def immutableFor[A <: AnyRef](ref: Int): A = {\n    if (ref < 2)\n      null.asInstanceOf[A]\n    else if (dedupImmutable)\n      immutableRefs(ref - 2).asInstanceOf[A]\n    else\n      throw new Exception(\"Deduplication for immutable objects is disabled, but immutableFor was called.\")\n  }\n\n  @inline def addImmutableRef(obj: AnyRef): Unit = {\n    if (dedupImmutable)\n      immutableRefs = immutableRefs.updated(obj)\n  }\n\n  @inline def unpickle[A](implicit u: Pickler[A]): A = u.unpickle(this)\n}\n\nprivate[reflect] object UnpickleState {\n  def apply(bytes: ByteBuffer) = new UnpickleState(new DecoderSize(bytes))\n\n  def apply(decoder: Decoder, deduplicate: Boolean = false, dedupImmutable: Boolean = false) =\n    new UnpickleState(decoder, deduplicate)\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/StringCodecBase.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport java.nio.ByteBuffer\n\nprivate[reflect] abstract class StringCodecFast {\n\n  /**\n    * String decoding function for a special 1-3 byte encoding of 16-bit char values\n    *\n    * @param len How many bytes to decode\n    * @param buf Buffer containing the data\n    * @return String with decoded data\n    */\n  def decodeFast(len: Int, buf: ByteBuffer): String = {\n    if (buf.hasArray)\n      decodeFastArray(len, buf)\n    else\n      decodeFastBuf(len, buf)\n  }\n\n  /**\n    * String encoding function for a special 1-3 byte encoding of 16-bit char values\n    *\n    * @param s String to encode\n    * @return `ByteBuffer` with the encoded data\n    */\n  def encodeFast(s: String, bb: ByteBuffer): Unit = {\n    if (bb.hasArray)\n      encodeFastArray(s, bb)\n    else\n      encodeFastBuf(s, bb)\n  }\n\n  def encodeFastArray(s: String, bb: ByteBuffer): Unit = {\n    val len = s.length()\n    val buf = bb.array()\n    var dst = bb.arrayOffset() + bb.position()\n    var src = 0\n    var c: Char = ' '\n    // start by encoding ASCII only\n    while ((src < len) && { c = s.charAt(src); c < 0x80 }) {\n      buf(dst) = c.toByte\n      src += 1\n      dst += 1\n    }\n\n    // next stage, encode also non-ASCII\n    while (src < len) {\n      c = s.charAt(src)\n      if (c < 0x80) {\n        buf(dst) = c.toByte\n        dst += 1\n      } else if (c < 0x4000) {\n        buf(dst) = (0x80 | (c & 0x3F)).toByte\n        buf(dst + 1) = (c >> 6 & 0xFF).toByte\n        dst += 2\n      } else {\n        buf(dst) = (0xC0 | (c & 0x3F)).toByte\n        buf(dst + 1) = (c >> 6 & 0xFF).toByte\n        buf(dst + 2) = (c >> 14).toByte\n        dst += 3\n      }\n      src += 1\n    }\n    (bb: java.nio.Buffer).position(dst - bb.arrayOffset())\n  }\n\n  def encodeFastBuf(s: String, bb: ByteBuffer): Unit = {\n    val len = s.length()\n    // worst case scenario produces 3 bytes per character\n    var src = 0\n    var c: Char = ' '\n    // start by encoding ASCII only\n    while ((src < len) && { c = s.charAt(src); c < 0x80 }) {\n      bb.put(c.toByte)\n      src += 1\n    }\n\n    // next stage, encode also non-ASCII\n    while (src < len) {\n      c = s.charAt(src)\n      if (c < 0x80) {\n        bb.put(c.toByte)\n      } else if (c < 0x4000) {\n        bb.put((0x80 | (c & 0x3F)).toByte)\n        bb.put((c >> 6 & 0xFF).toByte)\n      } else {\n        bb.put((0xC0 | (c & 0x3F)).toByte)\n        bb.put((c >> 6 & 0xFF).toByte)\n        bb.put((c >> 14).toByte)\n      }\n      src += 1\n    }\n  }\n\n  /**\n    * Faster decoding for array backed buffers\n    */\n  protected def decodeFastArray(len: Int, buf: ByteBuffer): String = {\n    val cp = new Array[Char](len)\n    val src = buf.array()\n    var offset = buf.arrayOffset() + buf.position()\n    var dst = 0\n    while (dst < len) {\n      val b = src(offset)\n      offset += 1\n      if ((b & 0x80) == 0) {\n        cp(dst) = (b & 0x7F).toChar\n      } else if ((b & 0xC0) == 0x80) {\n        val b1 = src(offset)\n        offset += 1\n        cp(dst) = (b & 0x3F | (b1.toShort & 0xFF) << 6).toChar\n      } else {\n        val b1 = src(offset)\n        val b2 = src(offset + 1)\n        offset += 2\n        cp(dst) = (b & 0x3F | (b1.toShort & 0xFF) << 6 | (b2.toShort << 14)).toChar\n      }\n      dst += 1\n    }\n    (buf: java.nio.Buffer).position(offset - buf.arrayOffset())\n    new String(cp)\n  }\n\n  /**\n    * Decoding for normal non-array `ByteBuffer`\n    */\n  protected def decodeFastBuf(len: Int, buf: ByteBuffer): String = {\n    val cp = new Array[Char](len)\n    var i = 0\n    var dst = 0\n    while (dst < len) {\n      val b = buf.get()\n      if ((b & 0x80) == 0) {\n        cp(dst) = (b & 0x7F).toChar\n      } else if ((b & 0xC0) == 0x80) {\n        val b1 = buf.get()\n        i += 1\n        cp(dst) = (b & 0x3F | (b1.toShort & 0xFF) << 6).toChar\n      } else {\n        val b1 = buf.get()\n        val b2 = buf.get()\n        i += 2\n        cp(dst) = (b & 0x3F | (b1.toShort & 0xFF) << 6 | (b2.toShort << 14)).toChar\n      }\n      i += 1\n      dst += 1\n    }\n    new String(cp)\n  }\n}\n\nprivate[reflect] abstract class StringCodecBase extends StringCodecFast {\n  def decodeUTF8(len: Int, buf: ByteBuffer): String\n\n  def encodeUTF8(s: String): ByteBuffer\n\n  def decodeUTF16(len: Int, buf: ByteBuffer): String\n\n  def encodeUTF16(s: String): ByteBuffer\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala/izumi/reflect/thirdparty/internal/boopickle/TuplePicklers.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nprivate[reflect] trait TuplePicklers extends PicklerHelper {\n\n  implicit def Tuple2Pickler[T1: P, T2: P]: P[(T1, T2)] = new P[(T1, T2)] {\n    override def pickle(x: (T1, T2))(implicit state: PickleState): Unit = { write[T1](x._1); write[T2](x._2) }\n    override def unpickle(implicit state: UnpickleState): (T1, T2) = (read[T1], read[T2])\n  }\n\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala-2.12-/izumi/reflect/thirdparty/internal/boopickle/XCompat.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\npackage izumi.reflect.thirdparty.internal.boopickle\n\nimport izumi.reflect.thirdparty.internal.boopickle.Constants.NullRef\n\nimport scala.collection.generic.CanBuildFrom\n\nprivate[reflect] trait XCompatImplicitPicklers {\n  this: PicklerHelper =>\n\n  implicit def mapPickler[T: P, S: P, V[_, _] <: scala.collection.Map[_, _]](\n    implicit cbf: CanBuildFrom[Nothing, (T, S), V[T, S]]\n  ): P[V[T, S]] =\n    BasicPicklers.MapPickler[T, S, V]\n  implicit def iterablePickler[T: P, V[_] <: Iterable[_]](implicit cbf: CanBuildFrom[Nothing, T, V[T]]): P[V[T]] =\n    BasicPicklers.IterablePickler[T, V]\n}\n\nprivate[reflect] trait XCompatPicklers {\n  this: PicklerHelper =>\n\n  /**\n    * This pickler works on all collections that derive from Iterable[T] (Vector, Set, List, etc)\n    *\n    * @tparam T type of the values\n    * @tparam V type of the collection\n    * @return\n    */\n  def IterablePickler[T: P, V[_] <: Iterable[_]](implicit cbf: CanBuildFrom[Nothing, T, V[T]]): P[V[T]] = new P[V[T]] {\n    override def pickle(iterable: V[T])(implicit state: PickleState): Unit = {\n      if (iterable == null) {\n        state.enc.writeInt(NullRef)\n      } else {\n        // encode length\n        state.enc.writeInt(iterable.size)\n        // encode contents\n        iterable.iterator.asInstanceOf[Iterator[T]].foreach(a => write[T](a))\n      }\n    }\n\n    override def unpickle(implicit state: UnpickleState): V[T] = {\n      state.dec.readInt match {\n        case NullRef =>\n          null.asInstanceOf[V[T]]\n        case 0 =>\n          // empty sequence\n          val res = cbf().result()\n          res\n        case len =>\n          val b = cbf()\n          b.sizeHint(len)\n          var i = 0\n          while (i < len) {\n            b += read[T]\n            i += 1\n          }\n          val res = b.result()\n          res\n      }\n    }\n  }\n\n  /**\n    * Maps require a specific pickler as they have two type parameters.\n    *\n    * @tparam T Type of keys\n    * @tparam S Type of values\n    * @return\n    */\n  def MapPickler[T: P, S: P, V[_, _] <: scala.collection.Map[_, _]](\n    implicit cbf: CanBuildFrom[Nothing, (T, S), V[T, S]]\n  ): P[V[T, S]] =\n    new P[V[T, S]] {\n      override def pickle(map: V[T, S])(implicit state: PickleState): Unit = {\n        if (map == null) {\n          state.enc.writeInt(NullRef)\n        } else {\n          // encode length\n          state.enc.writeInt(map.size)\n          // encode contents as a sequence\n          val kPickler = implicitly[P[T]]\n          val vPickler = implicitly[P[S]]\n          map.asInstanceOf[scala.collection.Map[T, S]].foreach {\n            kv =>\n              kPickler.pickle(kv._1)(state)\n              vPickler.pickle(kv._2)(state)\n          }\n        }\n      }\n\n      override def unpickle(implicit state: UnpickleState): V[T, S] = {\n        state.dec.readInt match {\n          case NullRef =>\n            null.asInstanceOf[V[T, S]]\n          case 0 =>\n            // empty map\n            val res = cbf().result()\n            res\n          case idx if idx < 0 =>\n            state.identityFor[V[T, S]](-idx)\n          case len =>\n            val b = cbf()\n            b.sizeHint(len)\n            val kPickler = implicitly[P[T]]\n            val vPickler = implicitly[P[S]]\n            var i = 0\n            while (i < len) {\n              b += kPickler.unpickle(state) -> vPickler.unpickle(state)\n              i += 1\n            }\n            val res = b.result()\n            res\n        }\n      }\n    }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/main/scala-2.13+/izumi/reflect/thirdparty/internal/boopickle/XCompat.scala",
    "content": "package izumi.reflect.thirdparty.internal.boopickle\n\nimport Constants.NullRef\nimport scala.collection.Factory\n\nprivate[reflect] trait XCompatImplicitPicklers {\n  this: PicklerHelper =>\n\n  implicit def mapPickler[T: P, S: P, V[_, _] <: scala.collection.Map[_, _]](\n    implicit cbf: Factory[(T, S), V[T, S]]\n  ): P[V[T, S]] = BasicPicklers.MapPickler[T, S, V]\n  implicit def iterablePickler[T: P, V[_] <: Iterable[_]](implicit cbf: Factory[T, V[T]]): P[V[T]] =\n    BasicPicklers.IterablePickler[T, V]\n}\n\nprivate[reflect] trait XCompatPicklers {\n  this: PicklerHelper =>\n\n  /**\n    * This pickler works on all collections that derive from Iterable[T] (Vector, Set, List, etc)\n    *\n    * @tparam T type of the values\n    * @tparam V type of the collection\n    * @return\n    */\n  def IterablePickler[T: P, V[_] <: Iterable[_]](implicit cbf: Factory[T, V[T]]): P[V[T]] = new P[V[T]] {\n    override def pickle(iterable: V[T])(implicit state: PickleState): Unit = {\n      if (iterable == null) {\n        state.enc.writeInt(NullRef)\n      } else {\n        // encode length\n        state.enc.writeInt(iterable.size)\n        // encode contents\n        iterable.iterator.asInstanceOf[Iterator[T]].foreach(a => write[T](a))\n      }\n    }\n\n    override def unpickle(implicit state: UnpickleState): V[T] = {\n      state.dec.readInt match {\n        case NullRef =>\n          null.asInstanceOf[V[T]]\n        case 0 =>\n          // empty sequence\n          val res = cbf.newBuilder.result()\n          res\n        case len =>\n          val b = cbf.newBuilder\n          b.sizeHint(len)\n          var i = 0\n          while (i < len) {\n            b += read[T]\n            i += 1\n          }\n          val res = b.result()\n          res\n      }\n    }\n  }\n\n  /**\n    * Maps require a specific pickler as they have two type parameters.\n    *\n    * @tparam T Type of keys\n    * @tparam S Type of values\n    * @return\n    */\n  def MapPickler[T: P, S: P, V[_, _] <: scala.collection.Map[_, _]](implicit cbf: Factory[(T, S), V[T, S]]): P[V[T, S]] =\n    new P[V[T, S]] {\n      override def pickle(map: V[T, S])(implicit state: PickleState): Unit = {\n        if (map == null) {\n          state.enc.writeInt(NullRef)\n        } else {\n          // encode length\n          state.enc.writeInt(map.size)\n          // encode contents as a sequence\n          val kPickler = implicitly[P[T]]\n          val vPickler = implicitly[P[S]]\n          map.asInstanceOf[scala.collection.Map[T, S]].foreach {\n            kv =>\n              kPickler.pickle(kv._1)(state)\n              vPickler.pickle(kv._2)(state)\n          }\n        }\n      }\n\n      override def unpickle(implicit state: UnpickleState): V[T, S] = {\n        state.dec.readInt match {\n          case NullRef =>\n            null.asInstanceOf[V[T, S]]\n          case 0 =>\n            // empty map\n            val res = cbf.newBuilder.result()\n            res\n          case idx if idx < 0 =>\n            state.identityFor[V[T, S]](-idx)\n          case len =>\n            val b = cbf.newBuilder\n            b.sizeHint(len)\n            val kPickler = implicitly[P[T]]\n            val vPickler = implicitly[P[S]]\n            var i = 0\n            while (i < len) {\n              b += kPickler.unpickle(state) -> vPickler.unpickle(state)\n              i += 1\n            }\n            val res = b.result()\n            res\n        }\n      }\n    }\n}\n"
  },
  {
    "path": "izumi-reflect/izumi-reflect-thirdparty-boopickle-shaded/src/test/scala/izumi/reflect/.keep",
    "content": ""
  },
  {
    "path": "keys.sh",
    "content": "#!/bin/bash -e\n\nEMAIL=${EMAIL:-pshirshov@gmail.com}\nSSHKEYNAME=travis-deploy-key\n\nPASSPHRASE=$(uuidgen)\nOPENSSL_KEY=`openssl rand -hex 32`\nOPENSSL_IV=`openssl rand -hex 16`\n\nSECRETS=./.secrets\nGPGHOME=$SECRETS/gnupg.home\nGPGTARGET=$SECRETS/gnupg\nLOCALSBT=$SECRETS/local.sbt\nGPGTMP=/tmp/gpginput\nPUBRING=$GPGTARGET/pubring.gpg\nSECRING=$GPGTARGET/secring.gpg\nSSHKEY=$SECRETS/$SSHKEYNAME\n\necho \"GPG Passphrase: $PASSPHRASE\"\necho \"SECRETS ENCRYPTION:\"\necho \"OPENSSL_KEY=$OPENSSL_KEY\"\necho \"OPENSSL_IV=$OPENSSL_IV\"\n\nrm -rf $GPGTARGET\nrm -rf $GPGHOME\nmkdir -p $GPGTARGET\nmkdir -p $GPGHOME\nchmod 700 $GPGHOME\n\ncat >$GPGTMP <<EOF\n     %echo Generating a basic OpenPGP key\n     Key-Type: RSA\n     Key-Length: 1024\n     Key-Usage: encrypt,sign,auth\n     Name-Real: Pavel Shirshov\n     Name-Comment: izumi-r2 sonatype key\n     Name-Email: $EMAIL\n     Expire-Date: 0\n     Passphrase: $PASSPHRASE\n     %commit\n     %echo done\nEOF\n\n#     Subkey-Type: RSA\n#     Subkey-Length: 2048\n#     Subkey-Usage: encrypt,sign,auth\n\ngpg --homedir $GPGHOME --batch --full-generate-key $GPGTMP\nrm -f $GPGTMP\n\n# export\ngpg --homedir $GPGHOME --list-keys --keyid-format short\ngpg --homedir $GPGHOME --batch --yes --passphrase $PASSPHRASE --pinentry-mode loopback --export-secret-keys  > $SECRING\ngpg --homedir $GPGHOME --batch --yes --passphrase $PASSPHRASE --pinentry-mode loopback --export > $PUBRING\n\n#sbt shim\nrm -f local.sbt\ncat >$LOCALSBT <<EOF\npgpPassphrase := Some(\"$PASSPHRASE\".toCharArray)\npgpSecretRing := file(\"$SECRING\")\npgpPublicRing := file(\"$PUBRING\")\nuseGpg := false\nEOF\nln -s $LOCALSBT .\n\n# publish\nfor fpr in $(gpg --homedir $GPGHOME --list-keys --with-colons  | awk -F: '/fpr:/ {print $10}' | sort -u); do\n    gpg --homedir $GPGHOME --send-keys --keyserver ipv4.pool.sks-keyservers.net $fpr\n    gpg --homedir $GPGHOME --send-keys --keyserver keyserver.ubuntu.com $fpr\ndone\n\n#ssh key\nssh-keygen -N \"\" -t rsa -m PEM -b 4096 -C $SSHKEYNAME -f $SSHKEY && cat $SSHKEY.pub\n\n\ntar cvf secrets.tar -v --exclude=gnupg.home .secrets\nopenssl aes-256-cbc -K ${OPENSSL_KEY} -iv ${OPENSSL_IV} -in secrets.tar -out secrets.tar.enc\n\n"
  },
  {
    "path": "project/Deps.sc",
    "content": "import $ivy.`io.7mind.izumi.sbt:sbtgen_2.13:0.0.107`\nimport izumi.sbtgen._\nimport izumi.sbtgen.model._\n\nobject Izumi {\n\n  object V {\n    val kind_projector = Version.VExpr(\"V.kind_projector\")\n    val scalatest = Version.VExpr(\"V.scalatest\")\n    val sbtgen = Version.VExpr(\"V.sbtgen\")\n  }\n\n  object PV {\n    val sbt_scoverage = Version.VExpr(\"PV.sbt_scoverage\")\n    val sbt_pgp = Version.VExpr(\"PV.sbt_pgp\")\n\n    val scala_js_version = Version.VExpr(\"PV.scala_js_version\")\n    val scala_native_version = Version.VExpr(\"PV.scala_native_version\")\n    val crossproject_version = Version.VExpr(\"PV.crossproject_version\")\n    val scalajs_bundler_version = Version.VExpr(\"PV.scalajs_bundler_version\")\n    val sbt_mima_version = Version.VExpr(\"PV.sbt_mima_version\")\n    val zio_sbt_website = Version.VExpr(\"PV.zio_sbt_website\")\n  }\n\n  final val scala211 = ScalaVersion(\"2.11.12\")\n  final val scala212 = ScalaVersion(\"2.12.20\")\n  final val scala213 = ScalaVersion(\"2.13.14\")\n  final val scala300 = ScalaVersion(\"3.3.6\")\n\n  // launch with `./sbtgen.sc 2` to use 2.13 in Intellij\n  var targetScala = Seq(scala300, scala213, scala212, scala211)\n\n  def entrypoint(args: Seq[String]) = {\n    val newArgs = args diff Seq(\n      args\n        .collectFirst {\n          case s @ s\"3${_}\" => s -> scala300\n          case s @ \"2.12\" => s -> scala212\n          case s @ \"2.11\" => s -> scala211\n          case s @ s\"2${_}\" => s -> scala213\n        }.map {\n          case (s, target) =>\n            targetScala = target :: targetScala.filterNot(_ == target).toList\n            s\n        }.orNull\n    )\n    if (args.contains(\"--help\")) {\n      println(\n        \"launch with `./sbtgen.sc 3` to use Scala 3 in IDEA, launch with `./sbtgen.sc 2` to use Scala 2\"\n      )\n    }\n    println(s\"Scala targets: $targetScala\")\n    Entrypoint.main(izumi_reflect, settings, Seq(\"-o\", \".\") ++ newArgs)\n  }\n\n  val settings = GlobalSettings(\n    groupId = \"dev.zio\",\n    sbtVersion = None,\n    scalaJsVersion = Version.VExpr(\"PV.scala_js_version\"),\n    scalaNativeVersion = Version.VExpr(\"PV.scala_native_version\"),\n    crossProjectVersion = Version.VExpr(\"PV.sbt_crossproject_version\")\n  )\n\n  object Deps {\n    final val scalatest = Library(\"org.scalatest\", \"scalatest\", V.scalatest, LibraryType.Auto)\n\n    final val scala_reflect = Library(\"org.scala-lang\", \"scala-reflect\", Version.VExpr(\"scalaVersion.value\"), LibraryType.Invariant)\n    final val scala3_compiler = Library(\"org.scala-lang\", \"scala3-compiler\", Version.VExpr(\"scalaVersion.value\"), LibraryType.AutoJvm)\n\n    final val projector = Library(\"org.typelevel\", \"kind-projector\", V.kind_projector, LibraryType.Invariant)\n      .more(LibSetting.Raw(\"cross CrossVersion.full\"))\n  }\n\n  import Deps._\n\n  object Groups {\n    final val izumi_reflect = Set(Group(\"izumi-reflect\"))\n  }\n\n  object Targets {\n    def targetScala = Izumi.targetScala\n    private val jvmPlatform = PlatformEnv(\n      platform = Platform.Jvm,\n      language = targetScala\n    )\n    private val jsPlatform = PlatformEnv(\n      platform = Platform.Js,\n      language = targetScala.filterNot(_ == Izumi.scala211),\n      settings = Seq(\n        \"coverageEnabled\" := false,\n        \"scalaJSLinkerConfig\" in (SettingScope.Project, Platform.Js) := \"scalaJSLinkerConfig.value.withModuleKind(ModuleKind.CommonJSModule)\".raw\n      )\n    )\n    private val nativePlatform = PlatformEnv(\n      platform = Platform.Native,\n      language = targetScala.filterNot(_ == Izumi.scala211), // scala-native abandoned 2.11\n      settings = Seq(\n        \"coverageEnabled\" := false\n      )\n    )\n    final val crossNative = Seq(jvmPlatform, jsPlatform, nativePlatform)\n  }\n\n  object Projects {\n\n    object root {\n      final val id = ArtifactId(\"izumi-reflect-root\")\n      final val plugins = Plugins(\n        enabled = Seq(Plugin(\"SbtgenVerificationPlugin\")),\n        disabled = Seq.empty\n      )\n      final val settings = Seq()\n\n      final val sharedAggSettings = Seq(\n        \"crossScalaVersions\" := Targets.targetScala.map(_.value),\n        \"scalaVersion\" := \"crossScalaVersions.value.head\".raw\n      )\n\n      final val rootSettings = Defaults.RootOptions ++ Seq(\n        \"crossScalaVersions\" := \"Nil\".raw,\n        \"organization\" in SettingScope.Build := \"dev.zio\",\n        \"publishTo\" in SettingScope.Build :=\n          \"\"\"{\n            |  if (isSnapshot.value) {\n            |    Some(\n            |      \"central-snapshots\" at \"https://central.sonatype.com/repository/maven-snapshots/\"\n            |    )\n            |  } else {\n            |    localStaging.value\n            |  }\n            |}\"\"\".stripMargin.raw,\n        \"credentials\" in SettingScope.Build ++=\n          \"\"\"\n            |{\n            |Seq(\n            |  Path.userHome / \".sbt\" / \"secrets\" / \"credentials.sonatype-zio-new.properties\",\n            |  file(\".\") / \".secrets\" / \"credentials.sonatype-nexus.properties\"\n            |)\n            |  .filter(_.exists())\n            |  .map(Credentials.apply)\n            |}\"\"\".stripMargin.raw,\n        \"homepage\" in SettingScope.Build := \"\"\"Some(url(\"https://zio.dev\"))\"\"\".raw,\n        \"licenses\" in SettingScope.Build := \"\"\"Seq(\"Apache-2.0\" -> url(\"http://www.apache.org/licenses/LICENSE-2.0\"))\"\"\".raw,\n        \"developers\" in SettingScope.Build :=\n          \"\"\"List(\n          Developer(id = \"jdegoes\", name = \"John De Goes\", url = url(\"http://degoes.net\"), email = \"john@degoes.net\"),\n          Developer(id = \"7mind\", name = \"Septimal Mind\", url = url(\"https://github.com/7mind\"), email = \"team@7mind.io\"),\n        )\"\"\".raw,\n        \"scmInfo\" in SettingScope.Build := \"\"\"Some(ScmInfo(url(\"https://github.com/zio/izumi-reflect\"), \"scm:git:https://github.com/zio/izumi-reflect.git\"))\"\"\".raw,\n        \"mimaBinaryIssueFilters\" in SettingScope.Build ++= Seq(\n          // ignore deletion of old ParsedLightTypeTag* classes, they were made package private more than a year ago, they shouldn't appear in library sources anymore - or in the first place\n          \"\"\"ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTag\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTag110\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTag210\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[MissingClassProblem](\"izumi.reflect.macrortti.LightTypeTag$ParsedLightTypeTagM8\")\"\"\".raw,\n          // dotty-only ProductX case class inheritance breakage\n          \"\"\"ProblemFilters.exclude[IncompatibleResultTypeProblem](\"izumi.reflect.macrortti.LightTypeTagRef#FullReference._1\")\"\"\".raw,\n          // new inherited methods added (2.11 problem only?)\n          \"\"\"ProblemFilters.exclude[InheritedNewAbstractMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef*\")\"\"\".raw,\n          // new methods added\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LTTRenderables.r_LambdaParameterName\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTag.binaryFormatVersion\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.repr\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LTTRenderables.r_Wildcard\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LTTRenderables.prefixSplitter\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.longNameWithPrefix\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.longNameInternalSymbol\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef#AppliedNamedReference.symName\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef#AppliedNamedReference.prefix\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.scalaStyledName\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagRef.scalaStyledRepr\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.AnyTag.=:=\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[ReversedMissingMethodProblem](\"izumi.reflect.AnyTag.<:<\")\"\"\".raw,\n          // compile-time only\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.TagMacro.*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.macrortti.LightTypeTagImpl.*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.macrortti.LightTypeTagImpl#*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.dottyreflection.*\")\"\"\".raw,\n          // private packages\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.thirdparty.*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.internal.*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem](\"izumi.reflect.ReflectionUtil*\")\"\"\".raw,\n          // private methods\n          \"\"\"ProblemFilters.exclude[DirectMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagImpl.norm\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[DirectMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagImpl.izumi$reflect$macrortti$LightTypeTagImpl$$*\")\"\"\".raw,\n          // private types\n          \"\"\"ProblemFilters.exclude[DirectMissingMethodProblem](\"izumi.reflect.macrortti.LightTypeTagInheritance.CtxExt\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[MissingFieldProblem](\"izumi.reflect.macrortti.LightTypeTagInheritance.CtxExt\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[FinalClassProblem](\"izumi.reflect.macrortti.LightTypeTagInheritance$CtxExt\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[MissingTypesProblem]       (\"izumi.reflect.macrortti.LightTypeTagInheritance$Ctx*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem]                   (\"izumi.reflect.macrortti.LightTypeTagInheritance#Ctx*\")\"\"\".raw,\n          \"\"\"ProblemFilters.exclude[Problem]                   (\"izumi.reflect.macrortti.LightTypeTagUnpacker*\")\"\"\".raw\n        ),\n        \"mimaFailOnProblem\" in SettingScope.Build := true,\n        \"mimaFailOnNoPrevious\" in SettingScope.Build := false,\n        \"useGpg\" in SettingScope.Build := false,\n\n        // scala-steward workaround\n        // add sbtgen version to sbt build to allow scala-steward to find it and update it in .sc files\n        // https://github.com/scala-steward-org/scala-steward/issues/696#issuecomment-545800968\n        \"libraryDependencies\" += s\"\"\"\"io.7mind.izumi.sbt\" % \"sbtgen_2.13\" % \"${Version.SbtGen.value}\" % Provided\"\"\".raw\n      )\n\n      final val sharedSettings =\n        Defaults.CrossScalaPlusSources ++\n        Defaults.CrossScalaRangeSources ++\n        Seq(\n          \"test\" in Platform.Native := \"{}\".raw,\n          \"test\" in (SettingScope.Test, Platform.Native) := \"{}\".raw,\n          \"sources\" in SettingScope.Raw(\"Compile / doc\") := Seq(\n            SettingKey(Some(scala300), None) := Seq.empty[String],\n            SettingKey.Default := \"(Compile / doc / sources).value\".raw\n          ),\n          \"testOptions\" in SettingScope.Test += \"\"\"Tests.Argument(\"-oDF\")\"\"\".raw,\n          // \"testOptions\" in (SettingScope.Test, Platform.Jvm) ++= s\"\"\"Seq(Tests.Argument(\"-u\"), Tests.Argument(s\"$${target.value}/junit-xml-$${scalaVersion.value}\"))\"\"\".raw,\n          \"scalacOptions\" ++= {\n            val removedOpts = Set[Const](\n              \"-P:kind-projector:underscore-placeholders\",\n              \"-Vimplicits\",\n              \"-Xsource:3\", // FIXME return after dropping 2.11 (NB: may cause bincompat issues)\n              \"-Xsource:3-cross\" // FIXME return after dropping 2.11 (NB: may cause bincompat issues)\n            )\n            val addedOpts = Seq[Const](\n              \"-Wconf:msg=nowarn:silent\"\n            )\n            Seq(\n              SettingKey(Some(scala211), None) := Const.EmptySeq,\n              SettingKey(Some(scala212), None) := Defaults.Scala212Options.filterNot(removedOpts) ++ addedOpts,\n              SettingKey(Some(scala213), None) := Defaults.Scala213Options.filterNot(removedOpts) ++ addedOpts,\n              SettingKey.Default := Seq(\n                \"-Ykind-projector\",\n                \"-no-indent\",\n                \"-language:implicitConversions\"\n              )\n            )\n          },\n          \"scalacOptions\" -= \"-Wconf:any:error\",\n          \"mimaPreviousArtifacts\" := Seq(\n            SettingKey(Some(scala300), None) := \"\"\"Set(organization.value %% name.value % \"2.2.5\", organization.value %% name.value % \"2.1.0\")\"\"\".raw,\n            SettingKey.Default := \"\"\"Set(organization.value %% name.value % \"2.2.5\", organization.value %% name.value % \"2.1.0\", organization.value %% name.value % \"1.0.0\")\"\"\".raw\n          ),\n          \"scalacOptions\" ++= Seq(\n            SettingKey(Some(scala213), None) := Seq(\n              // workaround for https://github.com/scala/bug/issues/12103\n              \"-Xlint:-implicit-recursion\"\n            ),\n            SettingKey.Default := Const.EmptySeq\n          ),\n          \"scalacOptions\" ++= {\n            val inlineOpts = Seq(\n              \"-opt:l:inline\",\n              \"-opt-inline-from:izumi.reflect.**\"\n            )\n            Seq(\n              SettingKey(Some(scala212), Some(true)) := inlineOpts,\n              SettingKey(Some(scala213), Some(true)) := inlineOpts,\n              SettingKey.Default := Const.EmptySeq\n            )\n          },\n          // For compatibility with Java 9+ module system;\n          // without Automatic-Module-Name, the module name is derived from the jar file which is invalid because of the scalaVersion suffix.\n          \"packageOptions\" in SettingScope.Raw(\"Compile / packageBin\") +=\n            s\"\"\"Package.ManifestAttributes(\"Automatic-Module-Name\" -> s\"$${organization.value.replaceAll(\"-\",\".\")}.$${moduleName.value.replaceAll(\"-\",\".\")}\")\"\"\".raw\n        )\n    }\n\n    object izumi_reflect_aggregate {\n      final val id = ArtifactId(\"izumi-reflect-aggregate\")\n      final val basePath = Seq(\"izumi-reflect\")\n\n      final val izumi_reflect = ArtifactId(\"izumi-reflect\")\n      final val thirdpartyBoopickleShaded = ArtifactId(\"izumi-reflect-thirdparty-boopickle-shaded\")\n    }\n\n  }\n\n  final lazy val izumi_reflect_aggregate = Aggregate(\n    name = Projects.izumi_reflect_aggregate.id,\n    artifacts = Seq(\n      Artifact(\n        name = Projects.izumi_reflect_aggregate.thirdpartyBoopickleShaded,\n        libs = Seq.empty,\n        depends = Seq.empty,\n        settings = Seq(\n          SettingDef.RawSettingDef(\n            \"\"\"Compile / scalacOptions --= Seq(\"-Ywarn-value-discard\",\"-Ywarn-unused:_\", \"-Wvalue-discard\", \"-Wunused:_\")\"\"\",\n            FullSettingScope(SettingScope.Compile, Platform.All)\n          )\n        )\n      ),\n      Artifact(\n        name = Projects.izumi_reflect_aggregate.izumi_reflect,\n        libs = Seq.empty,\n        depends = Seq(\n          Projects.izumi_reflect_aggregate.thirdpartyBoopickleShaded\n        )\n      )\n    ),\n    pathPrefix = Projects.izumi_reflect_aggregate.basePath,\n    groups = Groups.izumi_reflect,\n    defaultPlatforms = Targets.crossNative,\n    enableProjectSharedAggSettings = false,\n    settings = Seq(\n      \"crossScalaVersions\" := \"Nil\".raw\n    )\n  )\n\n  final lazy val izumi_reflect: Project = Project(\n    name = Projects.root.id,\n    aggregates = Seq(\n      izumi_reflect_aggregate\n    ),\n    topLevelSettings = Projects.root.settings,\n    sharedSettings = Projects.root.sharedSettings,\n    sharedAggSettings = Projects.root.sharedAggSettings,\n    rootSettings = Projects.root.rootSettings,\n    imports = Seq(\n      Import(\"com.typesafe.tools.mima.core._\")\n    ),\n    globalLibs = Seq(\n      ScopedLibrary(projector, FullDependencyScope(Scope.Compile, Platform.All).scalaVersion(ScalaVersionScope.AllScala2), compilerPlugin = true),\n      scala_reflect in Scope.Provided.all.scalaVersion(ScalaVersionScope.AllScala2),\n      scala3_compiler in Scope.Provided.all.scalaVersion(ScalaVersionScope.AllScala3),\n      scalatest in Scope.Test.all\n    ),\n    rootPlugins = Projects.root.plugins,\n    globalPlugins = Plugins(),\n    pluginConflictRules = Map.empty,\n    appendPlugins = Defaults.SbtGenPlugins ++ Seq(\n      SbtPlugin(\"com.github.sbt\", \"sbt-pgp\", PV.sbt_pgp),\n      SbtPlugin(\"org.scoverage\", \"sbt-scoverage\", PV.sbt_scoverage),\n      SbtPlugin(\"com.typesafe\", \"sbt-mima-plugin\", PV.sbt_mima_version),\n      SbtPlugin(\"dev.zio\", \"zio-sbt-website\", PV.zio_sbt_website)\n    )\n  )\n}\n"
  },
  {
    "path": "project/Settings.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\nimport sbt.settingKey\n\nobject DocKeys {\n  lazy val prefix = settingKey[String](\"\")\n}\n"
  },
  {
    "path": "project/Versions.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\nobject V {\n  val kind_projector = \"0.13.3\"\n  val scalatest = \"3.2.19\"\n}\n"
  },
  {
    "path": "project/build.properties",
    "content": "#\n# Copyright 2019-2020 Septimal Mind Ltd\n# Copyright 2020 John A. De Goes and the ZIO Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# You may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#       http://www.apache.org/licenses/LICENSE-2.0\n#\n#  Unless required by applicable law or agreed to in writing, software\n#  distributed under the License is distributed on an \"AS IS\" BASIS,\n#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n#  See the License for the specific language governing permissions and\n#  limitations under the License.\n#\n#\nsbt.version=1.11.2\n"
  },
  {
    "path": "project/plugins.sbt",
    "content": "// DO NOT EDIT THIS FILE\n// IT IS AUTOGENERATED BY `sbtgen.sc` SCRIPT\n// ALL CHANGES WILL BE LOST\n// https://www.scala-js.org/\naddSbtPlugin(\"org.scala-js\" % \"sbt-scalajs\" % PV.scala_js_version)\n\n// https://github.com/portable-scala/sbt-crossproject\naddSbtPlugin(\"org.portable-scala\" % \"sbt-scalajs-crossproject\" % PV.sbt_crossproject_version)\n\n// https://scalacenter.github.io/scalajs-bundler/\naddSbtPlugin(\"ch.epfl.scala\" % \"sbt-scalajs-bundler\" % \"0.21.1\")\n\n// https://github.com/scala-js/jsdependencies\naddSbtPlugin(\"org.scala-js\" % \"sbt-jsdependencies\" % \"1.0.2\")\naddSbtPlugin(\"org.portable-scala\" % \"sbt-scala-native-crossproject\" % PV.sbt_crossproject_version)\n\naddSbtPlugin(\"org.scala-native\"   % \"sbt-scala-native\"              % PV.scala_native_version)\n\n////////////////////////////////////////////////////////////////////////////////\n\naddSbtPlugin(\"io.7mind.izumi.sbt\" % \"sbt-izumi\" % \"0.0.107\")\n\naddSbtPlugin(\"com.github.sbt\" % \"sbt-pgp\" % PV.sbt_pgp)\n\naddSbtPlugin(\"org.scoverage\" % \"sbt-scoverage\" % PV.sbt_scoverage)\n\naddSbtPlugin(\"com.typesafe\" % \"sbt-mima-plugin\" % PV.sbt_mima_version)\n\naddSbtPlugin(\"dev.zio\" % \"zio-sbt-website\" % PV.zio_sbt_website)\n\n// Ignore scala-xml version conflict between scoverage where `coursier` requires scala-xml v2\n// and scoverage requires scala-xml v1 on Scala 2.12,\n// introduced when updating scoverage from 1.9.3 to 2.0.5\nlibraryDependencySchemes += \"org.scala-lang.modules\" %% \"scala-xml\" % VersionScheme.Always\n"
  },
  {
    "path": "project/project/PluginVersions.scala",
    "content": "/*\n * Copyright 2019-2020 Septimal Mind Ltd\n * Copyright 2020 John A. De Goes and the ZIO Contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * You may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n *\n */\n\nobject PV {\n  val sbt_scoverage = \"2.3.1\"\n  \n  val sbt_pgp = \"2.3.1\"\n\n  val sbt_mima_version = \"1.1.0\"\n\n  // last 2.11 version is 1.12.0, so we excluded 2.11 from JS builds, see nscplugin on maven central\n  val scala_js_version = \"1.17.0\"\n\n  // last 2.11 version is 0.4.9, so we excluded 2.11 from Native builds, see nscplugin on maven central\n  val scala_native_version = \"0.5.7\"\n\n  val sbt_crossproject_version = \"1.3.2\"\n\n  val zio_sbt_website = \"0.4.0-alpha.31\"\n}\n"
  },
  {
    "path": "sbtgen.sc",
    "content": "#!/bin/sh\ncs launch com.lihaoyi:ammonite_2.13.13:3.0.0-M1 --fork -M ammonite.Main -- sbtgen.sc $*\nexit\n!#\nimport $file.project.Deps, Deps._\n\n@main\ndef entrypoint(args: String*) = Izumi.entrypoint(args)\n"
  },
  {
    "path": "version.sbt",
    "content": "ThisBuild / version := \"3.0.10-SNAPSHOT\"\n"
  }
]