Skip to content

Commit

Permalink
[internal] scala: infer dependencies from consumed symbols and inter…
Browse files Browse the repository at this point in the history
…mediate scopes (#13758)

Infer Scala source dependencies based on consumed symbols provided by ancestor scopes that are not the immediately-enclosing scope.

Fixes #13655.

[ci skip-rust]
  • Loading branch information
Tom Dyas authored Dec 1, 2021
1 parent 4b066ac commit 4a395db
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 15 deletions.
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

0 comments on commit 4a395db

Please sign in to comment.