We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Scala import extraction for inference
Inference for Scala will require (at a minimum) import extraction from Scala sources. In v1 this was accomplished with https://scalameta.org/, which still seems to be active.

https://scalameta.org/docs/trees/guide.html#parse-trees

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/python/pants/backend/scala/dependency_inference/rules.py`
Content:
```
1 # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
2 # Licensed under the Apache License, Version 2.0 (see LICENSE).
3 from __future__ import annotations
4 
5 import logging
6 
7 from pants.backend.scala.dependency_inference import scala_parser, symbol_mapper
8 from pants.backend.scala.dependency_inference.scala_parser import ScalaSourceDependencyAnalysis
9 from pants.backend.scala.subsystems.scala_infer import ScalaInferSubsystem
10 from pants.backend.scala.target_types import ScalaSourceField
11 from pants.build_graph.address import Address
12 from pants.core.util_rules.source_files import SourceFilesRequest
13 from pants.engine.internals.selectors import Get, MultiGet
14 from pants.engine.rules import collect_rules, rule
15 from pants.engine.target import (
16     Dependencies,
17     DependenciesRequest,
18     ExplicitlyProvidedDependencies,
19     InferDependenciesRequest,
20     InferredDependencies,
21     WrappedTarget,
22 )
23 from pants.engine.unions import UnionRule
24 from pants.jvm.dependency_inference.symbol_mapper import FirstPartySymbolMapping
25 from pants.util.ordered_set import OrderedSet
26 
27 logger = logging.getLogger(__name__)
28 
29 
30 class InferScalaSourceDependencies(InferDependenciesRequest):
31     infer_from = ScalaSourceField
32 
33 
34 @rule(desc="Inferring Scala dependencies by analyzing sources")
35 async def infer_scala_dependencies_via_source_analysis(
36     request: InferScalaSourceDependencies,
37     scala_infer_subsystem: ScalaInferSubsystem,
38     first_party_symbol_map: FirstPartySymbolMapping,
39 ) -> InferredDependencies:
40     if not scala_infer_subsystem.imports:
41         return InferredDependencies([])
42 
43     address = request.sources_field.address
44     wrapped_tgt = await Get(WrappedTarget, Address, address)
45     explicitly_provided_deps, analysis = await MultiGet(
46         Get(ExplicitlyProvidedDependencies, DependenciesRequest(wrapped_tgt.target[Dependencies])),
47         Get(ScalaSourceDependencyAnalysis, SourceFilesRequest([request.sources_field])),
48     )
49 
50     symbols: OrderedSet[str] = OrderedSet()
51     if scala_infer_subsystem.imports:
52         symbols.update(analysis.all_imports())
53 
54     dependencies: OrderedSet[Address] = OrderedSet()
55     for symbol in symbols:
56         matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)
57         if not matches:
58             continue
59 
60         explicitly_provided_deps.maybe_warn_of_ambiguous_dependency_inference(
61             matches,
62             address,
63             import_reference="type",
64             context=f"The target {address} imports `{symbol}`",
65         )
66 
67         maybe_disambiguated = explicitly_provided_deps.disambiguated(matches)
68         if maybe_disambiguated:
69             dependencies.add(maybe_disambiguated)
70 
71     return InferredDependencies(dependencies)
72 
73 
74 def rules():
75     return [
76         *collect_rules(),
77         *scala_parser.rules(),
78         *symbol_mapper.rules(),
79         UnionRule(InferDependenciesRequest, InferScalaSourceDependencies),
80     ]
81
```

Path: `src/python/pants/backend/java/subsystems/java_infer.py`
Content:
```
1 # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
2 # Licensed under the Apache License, Version 2.0 (see LICENSE).
3 from typing import cast
4 
5 from pants.option.subsystem import Subsystem
6 from pants.util.docutil import git_url
7 
8 
9 class JavaInferSubsystem(Subsystem):
10     options_scope = "java-infer"
11     help = "Options controlling which dependencies will be inferred for Java targets."
12 
13     @classmethod
14     def register_options(cls, register):
15         super().register_options(register)
16         register(
17             "--imports",
18             default=True,
19             type=bool,
20             help=("Infer a target's dependencies by parsing import statements from sources."),
21         )
22         register(
23             "--consumed-types",
24             default=True,
25             type=bool,
26             help=("Infer a target's dependencies by parsing consumed types from sources."),
27         )
28         register(
29             "--third-party-imports",
30             default=True,
31             type=bool,
32             help="Infer a target's third-party dependencies using Java import statements.",
33         )
34         _default_package_mapping_url = git_url(
35             "src/python/pants/backend/java/dependency_inference/jvm_artifact_mappings.py"
36         )
37         register(
38             "--third-party-import-mapping",
39             type=dict,
40             help=(
41                 "A dictionary mapping a Java package path to a JVM artifact coordinate (GROUP:ARTIFACT) "
42                 "without the version. The package path may be made recursive to match symbols in subpackages "
43                 "by adding `.**` to the end of the package path. For example, specify `{'org.junit.**': 'junit:junit'} `"
44                 "to infer a dependency on junit:junit for any file importing a symbol from org.junit or its "
45                 f"subpackages. Pants also supplies a default package mapping ({_default_package_mapping_url})."
46             ),
47         )
48 
49     @property
50     def imports(self) -> bool:
51         return cast(bool, self.options.imports)
52 
53     @property
54     def consumed_types(self) -> bool:
55         return cast(bool, self.options.consumed_types)
56 
57     @property
58     def third_party_imports(self) -> bool:
59         return cast(bool, self.options.third_party_imports)
60 
61     @property
62     def third_party_import_mapping(self) -> dict:
63         return cast(dict, self.options.third_party_import_mapping)
64
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/python/pants/backend/java/subsystems/java_infer.py b/src/python/pants/backend/java/subsystems/java_infer.py
--- a/src/python/pants/backend/java/subsystems/java_infer.py
+++ b/src/python/pants/backend/java/subsystems/java_infer.py
@@ -34,6 +34,7 @@
         _default_package_mapping_url = git_url(
             "src/python/pants/backend/java/dependency_inference/jvm_artifact_mappings.py"
         )
+        # TODO: Move to `coursier` or a generic `jvm` subsystem.
         register(
             "--third-party-import-mapping",
             type=dict,
diff --git a/src/python/pants/backend/scala/dependency_inference/rules.py b/src/python/pants/backend/scala/dependency_inference/rules.py
--- a/src/python/pants/backend/scala/dependency_inference/rules.py
+++ b/src/python/pants/backend/scala/dependency_inference/rules.py
@@ -21,6 +21,12 @@
     WrappedTarget,
 )
 from pants.engine.unions import UnionRule
+from pants.jvm.dependency_inference import artifact_mapper
+from pants.jvm.dependency_inference.artifact_mapper import (
+    AvailableThirdPartyArtifacts,
+    ThirdPartyPackageToArtifactMapping,
+    find_artifact_mapping,
+)
 from pants.jvm.dependency_inference.symbol_mapper import FirstPartySymbolMapping
 from pants.util.ordered_set import OrderedSet
 
@@ -36,6 +42,8 @@
     request: InferScalaSourceDependencies,
     scala_infer_subsystem: ScalaInferSubsystem,
     first_party_symbol_map: FirstPartySymbolMapping,
+    third_party_artifact_mapping: ThirdPartyPackageToArtifactMapping,
+    available_artifacts: AvailableThirdPartyArtifacts,
 ) -> InferredDependencies:
     if not scala_infer_subsystem.imports:
         return InferredDependencies([])
@@ -53,7 +61,11 @@
 
     dependencies: OrderedSet[Address] = OrderedSet()
     for symbol in symbols:
-        matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)
+        first_party_matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)
+        third_party_matches = find_artifact_mapping(
+            symbol, third_party_artifact_mapping, available_artifacts
+        )
+        matches = first_party_matches.union(third_party_matches)
         if not matches:
             continue
 
@@ -74,6 +86,7 @@
 def rules():
     return [
         *collect_rules(),
+        *artifact_mapper.rules(),
         *scala_parser.rules(),
         *symbol_mapper.rules(),
         UnionRule(InferDependenciesRequest, InferScalaSourceDependencies),

{"golden_diff": "diff --git a/src/python/pants/backend/java/subsystems/java_infer.py b/src/python/pants/backend/java/subsystems/java_infer.py\n--- a/src/python/pants/backend/java/subsystems/java_infer.py\n+++ b/src/python/pants/backend/java/subsystems/java_infer.py\n@@ -34,6 +34,7 @@\n         _default_package_mapping_url = git_url(\n             \"src/python/pants/backend/java/dependency_inference/jvm_artifact_mappings.py\"\n         )\n+        # TODO: Move to `coursier` or a generic `jvm` subsystem.\n         register(\n             \"--third-party-import-mapping\",\n             type=dict,\ndiff --git a/src/python/pants/backend/scala/dependency_inference/rules.py b/src/python/pants/backend/scala/dependency_inference/rules.py\n--- a/src/python/pants/backend/scala/dependency_inference/rules.py\n+++ b/src/python/pants/backend/scala/dependency_inference/rules.py\n@@ -21,6 +21,12 @@\n     WrappedTarget,\n )\n from pants.engine.unions import UnionRule\n+from pants.jvm.dependency_inference import artifact_mapper\n+from pants.jvm.dependency_inference.artifact_mapper import (\n+    AvailableThirdPartyArtifacts,\n+    ThirdPartyPackageToArtifactMapping,\n+    find_artifact_mapping,\n+)\n from pants.jvm.dependency_inference.symbol_mapper import FirstPartySymbolMapping\n from pants.util.ordered_set import OrderedSet\n \n@@ -36,6 +42,8 @@\n     request: InferScalaSourceDependencies,\n     scala_infer_subsystem: ScalaInferSubsystem,\n     first_party_symbol_map: FirstPartySymbolMapping,\n+    third_party_artifact_mapping: ThirdPartyPackageToArtifactMapping,\n+    available_artifacts: AvailableThirdPartyArtifacts,\n ) -> InferredDependencies:\n     if not scala_infer_subsystem.imports:\n         return InferredDependencies([])\n@@ -53,7 +61,11 @@\n \n     dependencies: OrderedSet[Address] = OrderedSet()\n     for symbol in symbols:\n-        matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)\n+        first_party_matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)\n+        third_party_matches = find_artifact_mapping(\n+            symbol, third_party_artifact_mapping, available_artifacts\n+        )\n+        matches = first_party_matches.union(third_party_matches)\n         if not matches:\n             continue\n \n@@ -74,6 +86,7 @@\n def rules():\n     return [\n         *collect_rules(),\n+        *artifact_mapper.rules(),\n         *scala_parser.rules(),\n         *symbol_mapper.rules(),\n         UnionRule(InferDependenciesRequest, InferScalaSourceDependencies),\n", "issue": "Scala import extraction for inference\nInference for Scala will require (at a minimum) import extraction from Scala sources. In v1 this was accomplished with https://scalameta.org/, which still seems to be active.\r\n\r\nhttps://scalameta.org/docs/trees/guide.html#parse-trees\n", "before_files": [{"content": "# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\nfrom __future__ import annotations\n\nimport logging\n\nfrom pants.backend.scala.dependency_inference import scala_parser, symbol_mapper\nfrom pants.backend.scala.dependency_inference.scala_parser import ScalaSourceDependencyAnalysis\nfrom pants.backend.scala.subsystems.scala_infer import ScalaInferSubsystem\nfrom pants.backend.scala.target_types import ScalaSourceField\nfrom pants.build_graph.address import Address\nfrom pants.core.util_rules.source_files import SourceFilesRequest\nfrom pants.engine.internals.selectors import Get, MultiGet\nfrom pants.engine.rules import collect_rules, rule\nfrom pants.engine.target import (\n    Dependencies,\n    DependenciesRequest,\n    ExplicitlyProvidedDependencies,\n    InferDependenciesRequest,\n    InferredDependencies,\n    WrappedTarget,\n)\nfrom pants.engine.unions import UnionRule\nfrom pants.jvm.dependency_inference.symbol_mapper import FirstPartySymbolMapping\nfrom pants.util.ordered_set import OrderedSet\n\nlogger = logging.getLogger(__name__)\n\n\nclass InferScalaSourceDependencies(InferDependenciesRequest):\n    infer_from = ScalaSourceField\n\n\n@rule(desc=\"Inferring Scala dependencies by analyzing sources\")\nasync def infer_scala_dependencies_via_source_analysis(\n    request: InferScalaSourceDependencies,\n    scala_infer_subsystem: ScalaInferSubsystem,\n    first_party_symbol_map: FirstPartySymbolMapping,\n) -> InferredDependencies:\n    if not scala_infer_subsystem.imports:\n        return InferredDependencies([])\n\n    address = request.sources_field.address\n    wrapped_tgt = await Get(WrappedTarget, Address, address)\n    explicitly_provided_deps, analysis = await MultiGet(\n        Get(ExplicitlyProvidedDependencies, DependenciesRequest(wrapped_tgt.target[Dependencies])),\n        Get(ScalaSourceDependencyAnalysis, SourceFilesRequest([request.sources_field])),\n    )\n\n    symbols: OrderedSet[str] = OrderedSet()\n    if scala_infer_subsystem.imports:\n        symbols.update(analysis.all_imports())\n\n    dependencies: OrderedSet[Address] = OrderedSet()\n    for symbol in symbols:\n        matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)\n        if not matches:\n            continue\n\n        explicitly_provided_deps.maybe_warn_of_ambiguous_dependency_inference(\n            matches,\n            address,\n            import_reference=\"type\",\n            context=f\"The target {address} imports `{symbol}`\",\n        )\n\n        maybe_disambiguated = explicitly_provided_deps.disambiguated(matches)\n        if maybe_disambiguated:\n            dependencies.add(maybe_disambiguated)\n\n    return InferredDependencies(dependencies)\n\n\ndef rules():\n    return [\n        *collect_rules(),\n        *scala_parser.rules(),\n        *symbol_mapper.rules(),\n        UnionRule(InferDependenciesRequest, InferScalaSourceDependencies),\n    ]\n", "path": "src/python/pants/backend/scala/dependency_inference/rules.py"}, {"content": "# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\nfrom typing import cast\n\nfrom pants.option.subsystem import Subsystem\nfrom pants.util.docutil import git_url\n\n\nclass JavaInferSubsystem(Subsystem):\n    options_scope = \"java-infer\"\n    help = \"Options controlling which dependencies will be inferred for Java targets.\"\n\n    @classmethod\n    def register_options(cls, register):\n        super().register_options(register)\n        register(\n            \"--imports\",\n            default=True,\n            type=bool,\n            help=(\"Infer a target's dependencies by parsing import statements from sources.\"),\n        )\n        register(\n            \"--consumed-types\",\n            default=True,\n            type=bool,\n            help=(\"Infer a target's dependencies by parsing consumed types from sources.\"),\n        )\n        register(\n            \"--third-party-imports\",\n            default=True,\n            type=bool,\n            help=\"Infer a target's third-party dependencies using Java import statements.\",\n        )\n        _default_package_mapping_url = git_url(\n            \"src/python/pants/backend/java/dependency_inference/jvm_artifact_mappings.py\"\n        )\n        register(\n            \"--third-party-import-mapping\",\n            type=dict,\n            help=(\n                \"A dictionary mapping a Java package path to a JVM artifact coordinate (GROUP:ARTIFACT) \"\n                \"without the version. The package path may be made recursive to match symbols in subpackages \"\n                \"by adding `.**` to the end of the package path. For example, specify `{'org.junit.**': 'junit:junit'} `\"\n                \"to infer a dependency on junit:junit for any file importing a symbol from org.junit or its \"\n                f\"subpackages. Pants also supplies a default package mapping ({_default_package_mapping_url}).\"\n            ),\n        )\n\n    @property\n    def imports(self) -> bool:\n        return cast(bool, self.options.imports)\n\n    @property\n    def consumed_types(self) -> bool:\n        return cast(bool, self.options.consumed_types)\n\n    @property\n    def third_party_imports(self) -> bool:\n        return cast(bool, self.options.third_party_imports)\n\n    @property\n    def third_party_import_mapping(self) -> dict:\n        return cast(dict, self.options.third_party_import_mapping)\n", "path": "src/python/pants/backend/java/subsystems/java_infer.py"}], "after_files": [{"content": "# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\nfrom __future__ import annotations\n\nimport logging\n\nfrom pants.backend.scala.dependency_inference import scala_parser, symbol_mapper\nfrom pants.backend.scala.dependency_inference.scala_parser import ScalaSourceDependencyAnalysis\nfrom pants.backend.scala.subsystems.scala_infer import ScalaInferSubsystem\nfrom pants.backend.scala.target_types import ScalaSourceField\nfrom pants.build_graph.address import Address\nfrom pants.core.util_rules.source_files import SourceFilesRequest\nfrom pants.engine.internals.selectors import Get, MultiGet\nfrom pants.engine.rules import collect_rules, rule\nfrom pants.engine.target import (\n    Dependencies,\n    DependenciesRequest,\n    ExplicitlyProvidedDependencies,\n    InferDependenciesRequest,\n    InferredDependencies,\n    WrappedTarget,\n)\nfrom pants.engine.unions import UnionRule\nfrom pants.jvm.dependency_inference import artifact_mapper\nfrom pants.jvm.dependency_inference.artifact_mapper import (\n    AvailableThirdPartyArtifacts,\n    ThirdPartyPackageToArtifactMapping,\n    find_artifact_mapping,\n)\nfrom pants.jvm.dependency_inference.symbol_mapper import FirstPartySymbolMapping\nfrom pants.util.ordered_set import OrderedSet\n\nlogger = logging.getLogger(__name__)\n\n\nclass InferScalaSourceDependencies(InferDependenciesRequest):\n    infer_from = ScalaSourceField\n\n\n@rule(desc=\"Inferring Scala dependencies by analyzing sources\")\nasync def infer_scala_dependencies_via_source_analysis(\n    request: InferScalaSourceDependencies,\n    scala_infer_subsystem: ScalaInferSubsystem,\n    first_party_symbol_map: FirstPartySymbolMapping,\n    third_party_artifact_mapping: ThirdPartyPackageToArtifactMapping,\n    available_artifacts: AvailableThirdPartyArtifacts,\n) -> InferredDependencies:\n    if not scala_infer_subsystem.imports:\n        return InferredDependencies([])\n\n    address = request.sources_field.address\n    wrapped_tgt = await Get(WrappedTarget, Address, address)\n    explicitly_provided_deps, analysis = await MultiGet(\n        Get(ExplicitlyProvidedDependencies, DependenciesRequest(wrapped_tgt.target[Dependencies])),\n        Get(ScalaSourceDependencyAnalysis, SourceFilesRequest([request.sources_field])),\n    )\n\n    symbols: OrderedSet[str] = OrderedSet()\n    if scala_infer_subsystem.imports:\n        symbols.update(analysis.all_imports())\n\n    dependencies: OrderedSet[Address] = OrderedSet()\n    for symbol in symbols:\n        first_party_matches = first_party_symbol_map.symbols.addresses_for_symbol(symbol)\n        third_party_matches = find_artifact_mapping(\n            symbol, third_party_artifact_mapping, available_artifacts\n        )\n        matches = first_party_matches.union(third_party_matches)\n        if not matches:\n            continue\n\n        explicitly_provided_deps.maybe_warn_of_ambiguous_dependency_inference(\n            matches,\n            address,\n            import_reference=\"type\",\n            context=f\"The target {address} imports `{symbol}`\",\n        )\n\n        maybe_disambiguated = explicitly_provided_deps.disambiguated(matches)\n        if maybe_disambiguated:\n            dependencies.add(maybe_disambiguated)\n\n    return InferredDependencies(dependencies)\n\n\ndef rules():\n    return [\n        *collect_rules(),\n        *artifact_mapper.rules(),\n        *scala_parser.rules(),\n        *symbol_mapper.rules(),\n        UnionRule(InferDependenciesRequest, InferScalaSourceDependencies),\n    ]\n", "path": "src/python/pants/backend/scala/dependency_inference/rules.py"}, {"content": "# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\nfrom typing import cast\n\nfrom pants.option.subsystem import Subsystem\nfrom pants.util.docutil import git_url\n\n\nclass JavaInferSubsystem(Subsystem):\n    options_scope = \"java-infer\"\n    help = \"Options controlling which dependencies will be inferred for Java targets.\"\n\n    @classmethod\n    def register_options(cls, register):\n        super().register_options(register)\n        register(\n            \"--imports\",\n            default=True,\n            type=bool,\n            help=(\"Infer a target's dependencies by parsing import statements from sources.\"),\n        )\n        register(\n            \"--consumed-types\",\n            default=True,\n            type=bool,\n            help=(\"Infer a target's dependencies by parsing consumed types from sources.\"),\n        )\n        register(\n            \"--third-party-imports\",\n            default=True,\n            type=bool,\n            help=\"Infer a target's third-party dependencies using Java import statements.\",\n        )\n        _default_package_mapping_url = git_url(\n            \"src/python/pants/backend/java/dependency_inference/jvm_artifact_mappings.py\"\n        )\n        # TODO: Move to `coursier` or a generic `jvm` subsystem.\n        register(\n            \"--third-party-import-mapping\",\n            type=dict,\n            help=(\n                \"A dictionary mapping a Java package path to a JVM artifact coordinate (GROUP:ARTIFACT) \"\n                \"without the version. The package path may be made recursive to match symbols in subpackages \"\n                \"by adding `.**` to the end of the package path. For example, specify `{'org.junit.**': 'junit:junit'} `\"\n                \"to infer a dependency on junit:junit for any file importing a symbol from org.junit or its \"\n                f\"subpackages. Pants also supplies a default package mapping ({_default_package_mapping_url}).\"\n            ),\n        )\n\n    @property\n    def imports(self) -> bool:\n        return cast(bool, self.options.imports)\n\n    @property\n    def consumed_types(self) -> bool:\n        return cast(bool, self.options.consumed_types)\n\n    @property\n    def third_party_imports(self) -> bool:\n        return cast(bool, self.options.third_party_imports)\n\n    @property\n    def third_party_import_mapping(self) -> dict:\n        return cast(dict, self.options.third_party_import_mapping)\n", "path": "src/python/pants/backend/java/subsystems/java_infer.py"}]}