From d4f836e5c3c34bb48098cfcee4cd9f046d019c21 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 14 May 2025 16:07:57 +0200 Subject: [PATCH] Fix production of SemanticDB of shadowed parameters --- .../dotty/tools/dotc/semanticdb/TypeOps.scala | 4 +- .../expect/ShadowedParameters.expect.scala | 27 ++++++ .../expect/ShadowedParameters.scala | 27 ++++++ tests/semanticdb/metac.expect | 87 +++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 tests/semanticdb/expect/ShadowedParameters.expect.scala create mode 100644 tests/semanticdb/expect/ShadowedParameters.scala diff --git a/compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala b/compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala index 2d98535657a2..aa7b8f0dd29a 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/TypeOps.scala @@ -96,7 +96,9 @@ class TypeOps: // We try to find the "actual" binder of : `inner`, // and register them to the symbol table with `(, inner) -> ` // instead of `("y", outer) -> ` - if lam.paramNames.contains(sym.name) then + // We must also check for parameter shadowing such as def shadowParam(x: Int) = {val x = true} + + if (sym.is(Flags.Param) || !sym.owner.info.isInstanceOf[LambdaType]) && lam.paramNames.contains(sym.name) then paramRefSymtab((lam, sym.name)) = sym else enterParamRef(lam.resType) diff --git a/tests/semanticdb/expect/ShadowedParameters.expect.scala b/tests/semanticdb/expect/ShadowedParameters.expect.scala new file mode 100644 index 000000000000..10cc77d08c44 --- /dev/null +++ b/tests/semanticdb/expect/ShadowedParameters.expect.scala @@ -0,0 +1,27 @@ +package example + +class Shadow/*<-example::Shadow#*/{ + + def shadowParam/*<-example::Shadow#shadowParam().*/(x/*<-example::Shadow#shadowParam().(x)*/: Int/*->scala::Int#*/)= { + val x/*<-local0*/ = true + } + + def curriedParams/*<-example::Shadow#curriedParams().*/(x/*<-example::Shadow#curriedParams().(x)*/: Int/*->scala::Int#*/)(y/*<-example::Shadow#curriedParams().(y)*/: List/*->scala::package.List#*/[Int/*->scala::Int#*/]) = { + val x/*<-local1*/ = "shadow" + val y/*<-local2*/ = 1 + } + + + def multiParams/*<-example::Shadow#multiParams().*/(x/*<-example::Shadow#multiParams().(x)*/: List/*->scala::package.List#*/[Int/*->scala::Int#*/], y/*<-example::Shadow#multiParams().(y)*/: String/*->scala::Predef.String#*/) = { + val x/*<-local3*/ = 1 + val y/*<-local4*/ = List/*->scala::package.List.*/(1,2,3) + } + + + def shadowInParamBlock/*<-example::Shadow#shadowInParamBlock().*/(x/*<-example::Shadow#shadowInParamBlock().(x)*/: Int/*->scala::Int#*/, y/*<-example::Shadow#shadowInParamBlock().(y)*/: Int/*->scala::Int#*/) = { + val y/*<-local5*/ = 1 + { + val x/*<-local6*/ = 2 + } + } +} \ No newline at end of file diff --git a/tests/semanticdb/expect/ShadowedParameters.scala b/tests/semanticdb/expect/ShadowedParameters.scala new file mode 100644 index 000000000000..3b191e1b1c3f --- /dev/null +++ b/tests/semanticdb/expect/ShadowedParameters.scala @@ -0,0 +1,27 @@ +package example + +class Shadow{ + + def shadowParam(x: Int)= { + val x = true + } + + def curriedParams(x: Int)(y: List[Int]) = { + val x = "shadow" + val y = 1 + } + + + def multiParams(x: List[Int], y: String) = { + val x = 1 + val y = List(1,2,3) + } + + + def shadowInParamBlock(x: Int, y: Int) = { + val y = 1 + { + val x = 2 + } + } +} \ No newline at end of file diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index f674c6fb4159..3f904b6bdda0 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -3484,6 +3484,93 @@ Diagnostics: [10:29..10:33): [warning] with as a type operator has been deprecated; use & instead This construct can be rewritten automatically under -rewrite -source 3.4-migration. +expect/ShadowedParameters.scala +------------------------------- + +Summary: +Schema => SemanticDB v4 +Uri => ShadowedParameters.scala +Text => empty +Language => Scala +Symbols => 20 entries +Occurrences => 31 entries +Diagnostics => 14 entries +Synthetics => 1 entries + +Symbols: +example/Shadow# => class Shadow extends Object { self: Shadow => +5 decls } +example/Shadow#``(). => primary ctor (): Shadow +example/Shadow#curriedParams(). => method curriedParams (param x: Int)(param y: List[Int]): Unit +example/Shadow#curriedParams().(x) => param x: Int +example/Shadow#curriedParams().(y) => param y: List[Int] +example/Shadow#multiParams(). => method multiParams (param x: List[Int], param y: String): Unit +example/Shadow#multiParams().(x) => param x: List[Int] +example/Shadow#multiParams().(y) => param y: String +example/Shadow#shadowInParamBlock(). => method shadowInParamBlock (param x: Int, param y: Int): Unit +example/Shadow#shadowInParamBlock().(x) => param x: Int +example/Shadow#shadowInParamBlock().(y) => param y: Int +example/Shadow#shadowParam(). => method shadowParam (param x: Int): Unit +example/Shadow#shadowParam().(x) => param x: Int +local0 => val local x: Boolean +local1 => val local x: String +local2 => val local y: Int +local3 => val local x: Int +local4 => val local y: List[Int] +local5 => val local y: Int +local6 => val local x: Int + +Occurrences: +[0:8..0:15): example <- example/ +[2:6..2:12): Shadow <- example/Shadow# +[4:4..4:4): <- example/Shadow#``(). +[4:8..4:19): shadowParam <- example/Shadow#shadowParam(). +[4:20..4:21): x <- example/Shadow#shadowParam().(x) +[4:23..4:26): Int -> scala/Int# +[5:12..5:13): x <- local0 +[8:8..8:21): curriedParams <- example/Shadow#curriedParams(). +[8:22..8:23): x <- example/Shadow#curriedParams().(x) +[8:25..8:28): Int -> scala/Int# +[8:30..8:31): y <- example/Shadow#curriedParams().(y) +[8:33..8:37): List -> scala/package.List# +[8:38..8:41): Int -> scala/Int# +[9:12..9:13): x <- local1 +[10:12..10:13): y <- local2 +[14:8..14:19): multiParams <- example/Shadow#multiParams(). +[14:20..14:21): x <- example/Shadow#multiParams().(x) +[14:23..14:27): List -> scala/package.List# +[14:28..14:31): Int -> scala/Int# +[14:34..14:35): y <- example/Shadow#multiParams().(y) +[14:37..14:43): String -> scala/Predef.String# +[15:12..15:13): x <- local3 +[16:12..16:13): y <- local4 +[16:16..16:20): List -> scala/package.List. +[20:8..20:26): shadowInParamBlock <- example/Shadow#shadowInParamBlock(). +[20:27..20:28): x <- example/Shadow#shadowInParamBlock().(x) +[20:30..20:33): Int -> scala/Int# +[20:35..20:36): y <- example/Shadow#shadowInParamBlock().(y) +[20:38..20:41): Int -> scala/Int# +[21:12..21:13): y <- local5 +[23:16..23:17): x <- local6 + +Diagnostics: +[4:20..4:21): [warning] unused explicit parameter +[5:12..5:13): [warning] unused local definition +[8:22..8:23): [warning] unused explicit parameter +[8:30..8:31): [warning] unused explicit parameter +[9:12..9:13): [warning] unused local definition +[10:12..10:13): [warning] unused local definition +[14:20..14:21): [warning] unused explicit parameter +[14:34..14:35): [warning] unused explicit parameter +[15:12..15:13): [warning] unused local definition +[16:12..16:13): [warning] unused local definition +[20:27..20:28): [warning] unused explicit parameter +[20:35..20:36): [warning] unused explicit parameter +[21:12..21:13): [warning] unused local definition +[23:16..23:17): [warning] unused local definition + +Synthetics: +[16:16..16:20):List => *.apply[Int] + expect/StructuralTypes.scala ----------------------------