diff options
author | Som Snytt <som.snytt@gmail.com> | 2015-02-09 13:01:30 -0800 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2015-02-09 13:01:30 -0800 |
commit | e1c6f0eacd5372e5ee4fe267c6c5b7124cd162f3 (patch) | |
tree | 56a227d57c7251bf3f087ea28fed4fd90f352e75 | |
parent | 40bef79974de3ed00f0173a65fdf7aa19170900e (diff) | |
download | scala-e1c6f0eacd5372e5ee4fe267c6c5b7124cd162f3.tar.gz scala-e1c6f0eacd5372e5ee4fe267c6c5b7124cd162f3.tar.bz2 scala-e1c6f0eacd5372e5ee4fe267c6c5b7124cd162f3.zip |
SI-9140 Allow omitting pleonastic parameter name
Enable simply:
```
scala> def f(@deprecatedName foo: String) = foo.reverse
f: (foo: String)String
scala> f(foo = "bar")
<console>:9: warning: naming parameter foo has been deprecated.
f(foo = "bar")
^
res0: String = rab
```
`Symbol.deprecatedParamName` conventionally returns `NO_NAME`
when the name is omitted.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 10 | ||||
-rw-r--r-- | src/library/scala/deprecatedName.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 2 | ||||
-rw-r--r-- | test/files/neg/names-defaults-neg.check | 45 | ||||
-rw-r--r-- | test/files/neg/names-defaults-neg.scala | 2 |
5 files changed, 37 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 119b415d51..ba4c962f34 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -554,15 +554,19 @@ trait NamesDefaults { self: Analyzer => arg match { case arg @ AssignOrNamedArg(Ident(name), rhs) => def matchesName(param: Symbol) = { - def checkDeprecation = when(param.deprecatedParamName) { case Some(`name`) => true } + def checkDeprecation(anonOK: Boolean) = + when (param.deprecatedParamName) { + case Some(`name`) => true + case Some(nme.NO_NAME) => anonOK + } def checkName = { val res = param.name == name - if (res && checkDeprecation) + if (res && checkDeprecation(true)) context0.deprecationWarning(arg.pos, param, s"naming parameter $name has been deprecated.") res } def checkAltName = { - val res = checkDeprecation + val res = checkDeprecation(false) if (res) context0.deprecationWarning(arg.pos, param, s"the parameter name $name has been deprecated. Use ${param.name} instead.") res diff --git a/src/library/scala/deprecatedName.scala b/src/library/scala/deprecatedName.scala index 07c5c8925c..a0d3aa829b 100644 --- a/src/library/scala/deprecatedName.scala +++ b/src/library/scala/deprecatedName.scala @@ -29,4 +29,6 @@ import scala.annotation.meta._ * @since 2.8.1 */ @param -class deprecatedName(name: Symbol) extends scala.annotation.StaticAnnotation +class deprecatedName(name: Symbol) extends scala.annotation.StaticAnnotation { + def this() = this(Symbol("<none>")) +} diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index f2aa14b866..293af68c5f 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -858,7 +858,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isDeprecated = hasAnnotation(DeprecatedAttr) def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0) def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1) - def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0) + def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0 orElse Some(nme.NO_NAME)) def hasDeprecatedInheritanceAnnotation = hasAnnotation(DeprecatedInheritanceAttr) def deprecatedInheritanceMessage diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index 249d227e93..d929cf23ec 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -121,68 +121,71 @@ names-defaults-neg.scala:93: error: parameter 'b' is already specified at parame names-defaults-neg.scala:96: warning: naming parameter deprNam4Arg has been deprecated. deprNam4(deprNam4Arg = null) ^ -names-defaults-neg.scala:100: error: unknown parameter name: m +names-defaults-neg.scala:98: warning: naming parameter deprNam5Arg has been deprecated. + deprNam5(deprNam5Arg = null) + ^ +names-defaults-neg.scala:102: error: unknown parameter name: m f3818(y = 1, m = 1) ^ -names-defaults-neg.scala:133: error: reference to var2 is ambiguous; it is both a method parameter and a variable in scope. +names-defaults-neg.scala:135: error: reference to var2 is ambiguous; it is both a method parameter and a variable in scope. delay(var2 = 40) ^ -names-defaults-neg.scala:136: error: missing parameter type for expanded function ((x$1) => a = x$1) +names-defaults-neg.scala:138: error: missing parameter type for expanded function ((x$1) => a = x$1) val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ -names-defaults-neg.scala:136: error: not found: value a +names-defaults-neg.scala:138: error: not found: value a val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ -names-defaults-neg.scala:136: error: not found: value get +names-defaults-neg.scala:138: error: not found: value get val taf2: Int => Unit = testAnnFun(a = _, b = get("+")) ^ -names-defaults-neg.scala:137: error: parameter 'a' is already specified at parameter position 1 +names-defaults-neg.scala:139: error: parameter 'a' is already specified at parameter position 1 val taf3 = testAnnFun(b = _: String, a = get(8)) ^ -names-defaults-neg.scala:138: error: missing parameter type for expanded function ((x$3) => testAnnFun(x$3, ((x$4) => b = x$4))) +names-defaults-neg.scala:140: error: missing parameter type for expanded function ((x$3) => testAnnFun(x$3, ((x$4) => b = x$4))) val taf4: (Int, String) => Unit = testAnnFun(_, b = _) ^ -names-defaults-neg.scala:138: error: missing parameter type for expanded function ((x$4) => b = x$4) +names-defaults-neg.scala:140: error: missing parameter type for expanded function ((x$4) => b = x$4) val taf4: (Int, String) => Unit = testAnnFun(_, b = _) ^ -names-defaults-neg.scala:138: error: not found: value b +names-defaults-neg.scala:140: error: not found: value b val taf4: (Int, String) => Unit = testAnnFun(_, b = _) ^ -names-defaults-neg.scala:146: error: variable definition needs type because 'x' is used as a named argument in its body. +names-defaults-neg.scala:148: error: variable definition needs type because 'x' is used as a named argument in its body. def t3 { var x = t.f(x = 1) } ^ -names-defaults-neg.scala:149: error: variable definition needs type because 'x' is used as a named argument in its body. +names-defaults-neg.scala:151: error: variable definition needs type because 'x' is used as a named argument in its body. object t6 { var x = t.f(x = 1) } ^ -names-defaults-neg.scala:149: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment +names-defaults-neg.scala:151: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for x. object t6 { var x = t.f(x = 1) } ^ -names-defaults-neg.scala:152: error: variable definition needs type because 'x' is used as a named argument in its body. +names-defaults-neg.scala:154: error: variable definition needs type because 'x' is used as a named argument in its body. class t9 { var x = t.f(x = 1) } ^ -names-defaults-neg.scala:152: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment +names-defaults-neg.scala:154: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for x. class t9 { var x = t.f(x = 1) } ^ -names-defaults-neg.scala:166: error: variable definition needs type because 'x' is used as a named argument in its body. +names-defaults-neg.scala:168: error: variable definition needs type because 'x' is used as a named argument in its body. def u3 { var x = u.f(x = 1) } ^ -names-defaults-neg.scala:169: error: variable definition needs type because 'x' is used as a named argument in its body. +names-defaults-neg.scala:171: error: variable definition needs type because 'x' is used as a named argument in its body. def u6 { var x = u.f(x = "32") } ^ -names-defaults-neg.scala:172: error: reference to x is ambiguous; it is both a method parameter and a variable in scope. +names-defaults-neg.scala:174: error: reference to x is ambiguous; it is both a method parameter and a variable in scope. def u9 { var x: Int = u.f(x = 1) } ^ -names-defaults-neg.scala:179: error: variable definition needs type because 'x' is used as a named argument in its body. +names-defaults-neg.scala:181: error: variable definition needs type because 'x' is used as a named argument in its body. class u15 { var x = u.f(x = 1) } ^ -names-defaults-neg.scala:179: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment +names-defaults-neg.scala:181: warning: type-checking the invocation of method f checks if the named argument expression 'x = ...' is a valid assignment in the current scope. The resulting type inference error (see above) can be fixed by providing an explicit type in the local definition for x. class u15 { var x = u.f(x = 1) } ^ -names-defaults-neg.scala:182: error: reference to x is ambiguous; it is both a method parameter and a variable in scope. +names-defaults-neg.scala:184: error: reference to x is ambiguous; it is both a method parameter and a variable in scope. class u18 { var x: Int = u.f(x = 1) } ^ -5 warnings found +6 warnings found 46 errors found diff --git a/test/files/neg/names-defaults-neg.scala b/test/files/neg/names-defaults-neg.scala index d11c9910a1..c809b9a7a2 100644 --- a/test/files/neg/names-defaults-neg.scala +++ b/test/files/neg/names-defaults-neg.scala @@ -94,6 +94,8 @@ object Test extends App { def deprNam4(@deprecatedName('deprNam4Arg) deprNam4Arg: String) = 0 deprNam4(deprNam4Arg = null) + def deprNam5(@deprecatedName deprNam5Arg: String) = 0 + deprNam5(deprNam5Arg = null) // t3818 def f3818(x: Int = 1, y: Int, z: Int = 1) = 0 |