diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index df220271ba4c..33997c4656f5 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -1518,7 +1518,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { * @param selectorPredicate A test to find the selector to use. * @return The symbols imported. */ - def importedSymbols(imp: Import, + def importedSymbols(imp: ImportOrExport, selectorPredicate: untpd.ImportSelector => Boolean = util.common.alwaysTrue) (using Context): List[Symbol] = imp.selectors.find(selectorPredicate) match diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 4f779e4a9c71..75f738abd00e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1296,7 +1296,7 @@ class Namer { typer: Typer => val ddef = tpd.DefDef(forwarder.asTerm, prefss => { val forwarderCtx = ctx.withOwner(forwarder) val (pathRefss, methRefss) = prefss.splitAt(extensionParamsCount(path.tpe.widen)) - val ref = path.appliedToArgss(pathRefss).select(sym.asTerm) + val ref = path.appliedToArgss(pathRefss).select(sym.asTerm).withSpan(span.focus) val rhs = ref.appliedToArgss(adaptForwarderParams(Nil, sym.info, methRefss)) .etaExpandCFT(using forwarderCtx) if forwarder.isInlineMethod then diff --git a/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala b/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala index 8c3e52080c93..60a884eb2934 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/MetalsInteractive.scala @@ -135,7 +135,7 @@ object MetalsInteractive: (sym, sym.info, None) ) - case (imp: Import) :: _ => + case (imp: ImportOrExport) :: _ => importedSymbols(imp, _.span.contains(pos.span)).map(sym => (sym, sym.info, None) ) diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala index d145272ba01d..52a6299c79fe 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcCollector.scala @@ -63,7 +63,8 @@ trait PcCollector[T]: o.span.exists && o.span.point == named.symbol.owner.span.point ) - def soughtOrOverride(sym: Symbol) = + def soughtOrOverride(sym0: Symbol) = + val sym = if sym0.is(Flags.Exported) then sym0.sourceSymbol else sym0 sought(sym) || sym.allOverriddenSymbols.exists(sought(_)) def soughtTreeFilter(tree: Tree): Boolean = @@ -76,7 +77,7 @@ trait PcCollector[T]: case df: NamedDefTree if soughtOrOverride(df.symbol) && !df.symbol.isSetter => true - case imp: Import if owners(imp.expr.symbol) => true + case imp: ImportOrExport if owners(imp.expr.symbol) => true case _ => false def soughtFilter(f: Symbol => Boolean): Boolean = @@ -115,11 +116,13 @@ trait PcCollector[T]: */ case ident: Ident if ident.isCorrectSpan && filter(ident) => // symbols will differ for params in different ext methods, but source pos will be the same - if soughtFilter(_.sourcePos == ident.symbol.sourcePos) + val symbol = if ident.symbol.is(Flags.Exported) then ident.symbol.sourceSymbol else ident.symbol + if soughtFilter(_.sourcePos == symbol.sourcePos) then occurrences + collect( ident, - ident.sourcePos + ident.sourcePos, + Some(symbol) ) else occurrences /** @@ -228,7 +231,7 @@ trait PcCollector[T]: * For traversing import selectors: * import scala.util.<> */ - case imp: Import if filter(imp) => + case imp: ImportOrExport if filter(imp) => imp.selectors .collect { case sel: ImportSelector diff --git a/presentation-compiler/src/main/dotty/tools/pc/PcSymbolSearch.scala b/presentation-compiler/src/main/dotty/tools/pc/PcSymbolSearch.scala index fd3d74f16c16..7d1e53e1ddb2 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/PcSymbolSearch.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/PcSymbolSearch.scala @@ -49,7 +49,7 @@ trait PcSymbolSearch: lazy val soughtSymbols: Option[(Set[Symbol], SourcePosition)] = soughtSymbols(path) - def soughtSymbols(path: List[Tree]): Option[(Set[Symbol], SourcePosition)] = + private def soughtSymbols(path: List[Tree]): Option[(Set[Symbol], SourcePosition)] = val sought = path match /* reference of an extension paramter * extension [EF](<>: List[EF]) @@ -148,7 +148,7 @@ trait PcSymbolSearch: /* Import selectors: * import scala.util.Tr@@y */ - case (imp: Import) :: _ if imp.span.contains(pos.span) => + case (imp: ImportOrExport) :: _ if imp.span.contains(pos.span) => imp .selector(pos.span) .map(sym => (symbolAlternatives(sym), sym.sourcePos)) diff --git a/presentation-compiler/src/main/dotty/tools/pc/WithCompilationUnit.scala b/presentation-compiler/src/main/dotty/tools/pc/WithCompilationUnit.scala index 8110db269b3b..56be6614bbd4 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/WithCompilationUnit.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/WithCompilationUnit.scala @@ -76,7 +76,9 @@ class WithCompilationUnit( } else Set.empty val all = - if sym.is(Flags.ModuleClass) then + if sym.is(Flags.Exported) then + Set(sym, sym.sourceSymbol) + else if sym.is(Flags.ModuleClass) then Set(sym, sym.companionModule, sym.companionModule.companion) else if sym.isClass then Set(sym, sym.companionModule, sym.companion.moduleClass) diff --git a/presentation-compiler/src/main/dotty/tools/pc/utils/InteractiveEnrichments.scala b/presentation-compiler/src/main/dotty/tools/pc/utils/InteractiveEnrichments.scala index fb5e56085e15..43a3e3c28be4 100644 --- a/presentation-compiler/src/main/dotty/tools/pc/utils/InteractiveEnrichments.scala +++ b/presentation-compiler/src/main/dotty/tools/pc/utils/InteractiveEnrichments.scala @@ -339,7 +339,7 @@ object InteractiveEnrichments extends CommonMtagsEnrichments: end enclosedChildren end extension - extension (imp: Import) + extension (imp: ImportOrExport) def selector(span: Span)(using Context): Option[Symbol] = for sel <- imp.selectors.find(_.span.contains(span)) yield imp.expr.symbol.info.member(sel.name).symbol diff --git a/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala index a3f09b97d3f8..b530e37f3ebd 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/definition/PcDefinitionSuite.scala @@ -28,7 +28,8 @@ class PcDefinitionSuite extends BasePcDefinitionSuite: MockLocation("scala/Predef.Ensuring#ensuring(+2).", "Predef.scala"), MockLocation("scala/Predef.Ensuring#ensuring(+3).", "Predef.scala"), MockLocation("scala/collection/immutable/List#`::`().", "List.scala"), - MockLocation("scala/package.List.", "package.scala") + MockLocation("scala/package.List.", "package.scala"), + MockLocation("scala/collection/immutable/Vector.", "Vector.scala"), ) override def definitions(offsetParams: OffsetParams): List[Location] = @@ -603,3 +604,38 @@ class PcDefinitionSuite extends BasePcDefinitionSuite: |""".stripMargin ) + @Test def i7256 = + check( + """|object Test: + | def <>: Unit = ??? + |export Test.me@@thodA + |""".stripMargin + ) + + @Test def `i7256-2` = + check( + """|object Test: + | def <>: Unit = ??? + | def methodB: Unit = ??? + |export Test.{me@@thodA, methodB} + |""".stripMargin + ) + + @Test def `i7256-3` = + check( + """|object Test: + | def <>: Unit = ??? + | def methodB: Unit = ??? + |export Test.{methodA, methodB} + | + |val i = met@@hodA + |""".stripMargin + ) + + @Test def i7427 = + check( + """|package a + |object Repro: + | export scala.collection.immutable.V/*scala/collection/immutable/Vector. Vector.scala*/@@ector + |""".stripMargin + ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala index 4809bc5cd5b8..5c29b18fee28 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/highlight/DocumentHighlightSuite.scala @@ -1486,5 +1486,45 @@ class DocumentHighlightSuite extends BaseDocumentHighlightSuite: |""".stripMargin ) + @Test def i7256 = + check( + """|package a + |object Test: + | def <>: Unit = ??? + |export Test.<> + |val i = <> + |""".stripMargin + ) + + @Test def `i7256-2` = + check( + """|object Test: + | def <>: Unit = ??? + | def methodB: Unit = ??? + |export Test.{<>, methodB} + |val i = <> + |""".stripMargin + ) + + + @Test def `i7256-3` = + check( + """|object Test: + | def <>: Unit = ??? + | def methodB: Unit = ??? + |export Test.<> + |val i = <> + |val j = <> + |""".stripMargin + ) + + @Test def `i7256-4` = + check( + """|object Test: + | class <> + | object <> + |export Test.<> + |""".stripMargin + ) end DocumentHighlightSuite diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala index f4ce4473e60a..6a544fb3a6bc 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverDefnSuite.scala @@ -238,3 +238,20 @@ class HoverDefnSuite extends BaseHoverSuite: |""".stripMargin, "val foo: Int".hover ) + + @Test def i7256 = + check( + """|object Test: + | def methodA: Unit = ??? + |export Test.me@@thodA + |""".stripMargin, + """|**Expression type**: + |```scala + |=> Unit + |``` + |**Symbol signature**: + |```scala + |def methodA: Unit + |``` + |""".stripMargin + ) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala index aebdf7f6c04e..e3cb3edbd8ba 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/tokens/SemanticTokensSuite.scala @@ -459,3 +459,11 @@ class SemanticTokensSuite extends BaseSemanticTokensSuite: | end <>/*class,definition*/ |""".stripMargin ) + + @Test def i7256 = + check( + """|object <>/*class*/: + | def <>/*method,definition*/: <>/*class,abstract*/ = <>/*method*/ + |export <>/*class*/.<>/*method*/ + |""".stripMargin + )