Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[internal] scala: infer dependencies from consumed symbols and intermediate scopes #13758

Merged
merged 1 commit into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/python/pants/backend/scala/dependency_inference/rules_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,37 @@ class C {}
assert rule_runner.request(
InferredDependencies, [InferScalaSourceDependencies(target_c[ScalaSourceField])]
) == InferredDependencies(dependencies=[Address("a_one", relative_file_path="A.scala")])


def test_infer_unqualified_symbol_from_intermediate_scope(rule_runner: RuleRunner) -> None:
rule_runner.write_files(
{
"foo/BUILD": "scala_sources()",
"foo/A.scala": dedent(
"""\
package org.pantsbuild.outer
package intermediate

object A {
def main(args: Array[String]): Unit = {
println(B.Foo)
}
}
"""
),
"bar/BUILD": "scala_sources()",
"bar/B.scala": dedent(
"""\
package org.pantsbuild.outer
object B {
val Foo = 3
}
"""
),
}
)
tgt = rule_runner.get_target(Address("foo", relative_file_path="A.scala"))
deps = rule_runner.request(
InferredDependencies, [InferScalaSourceDependencies(tgt[ScalaSourceField])]
)
assert deps == InferredDependencies([Address("bar", relative_file_path="B.scala")])
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,6 @@ def fully_qualified_consumed_symbols(self) -> Iterator[str]:
have been provided by any wildcard import in scope, as well as being declared in the current
package.
"""
# TODO: We compute "the package" as the "shortest scope in the file" to handle the most
# common case of consuming a type from within your package. But this doesn't account
# for the fact that any of the intermediate scopes might be relevant as well. Solving that
# would require resolving the type recursively upward.
package = min(
(*self.imports_by_scope.keys(), *self.consumed_symbols_by_scope.keys()),
key=len,
default="",
)

# Collect all wildcard imports.
wildcard_imports_by_scope = {}
for scope, imports in self.imports_by_scope.items():
Expand All @@ -155,9 +145,9 @@ def fully_qualified_consumed_symbols(self) -> Iterator[str]:
if scope.startswith(s)
}
for symbol in consumed_symbols:
if package:
yield f"{package}.{symbol}"
if not package or "." in symbol:
for scope in self.scopes:
yield f"{scope}.{symbol}"
if not self.scopes or "." in symbol:
# TODO: Similar to #13545: we assume that a symbol containing a dot might already
# be fully qualified.
yield symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pants.jvm.resolve.coursier_fetch import rules as coursier_fetch_rules
from pants.jvm.resolve.coursier_setup import rules as coursier_setup_rules
from pants.jvm.target_types import JvmDependencyLockfile
from pants.testutil.rule_runner import PYTHON_BOOTSTRAP_ENV, QueryRule, RuleRunner, logging
from pants.testutil.rule_runner import PYTHON_BOOTSTRAP_ENV, QueryRule, RuleRunner
from pants.util.frozendict import FrozenDict
from pants.util.ordered_set import FrozenOrderedSet

Expand All @@ -48,7 +48,6 @@ def rule_runner() -> RuleRunner:
return rule_runner


@logging
def test_parser_simple(rule_runner: RuleRunner) -> None:
rule_runner.write_files(
{
Expand Down Expand Up @@ -304,6 +303,24 @@ def this(bar: SomeTypeInSecondaryConstructor) {
"org.pantsbuild.example.LambdaTypeArg2",
"org.pantsbuild.example.TupleTypeArg1",
"org.pantsbuild.example.TupleTypeArg2",
"org.pantsbuild.+",
"org.pantsbuild.ABaseClass",
"org.pantsbuild.AParameterType",
"org.pantsbuild.ATrait1",
"org.pantsbuild.ATrait2.Nested",
"org.pantsbuild.BaseWithConstructor",
"org.pantsbuild.Integer",
"org.pantsbuild.LambdaReturnType",
"org.pantsbuild.LambdaTypeArg1",
"org.pantsbuild.LambdaTypeArg2",
"org.pantsbuild.OuterObject.NestedVal",
"org.pantsbuild.SomeTypeInSecondaryConstructor",
"org.pantsbuild.String",
"org.pantsbuild.TupleTypeArg1",
"org.pantsbuild.TupleTypeArg2",
"org.pantsbuild.Unit",
"org.pantsbuild.bar",
"org.pantsbuild.foo",
}


Expand Down