8000 SI-4700 Types with symbolic names print in infix by default · Pull Request #5589 · scala/scala · GitHub
[go: up one dir, main page]

Skip to content

SI-4700 Types with symbolic names print in infix by default #5589

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 8000 terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 < 8000 /h5>
Diff view
Prev Previous commit
SI-4700 Make infix notation default for symbolic types.
Add ability to disable this via the @showAsInfix annotation.
  • Loading branch information
allisonhb committed Dec 14, 2016
commit fab1db5a3854ae737e1d749eb08be9baf41199f5
42 changes: 24 additions & 18 deletions src/library/scala/annotation/showAsInfix.scala
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
package scala.annotation

/**
* This annotation, used for two-parameter generic types makes Scala print
* the type using infix notation:
*
* ```
* scala> class &&[T, U]
* defined class $amp$amp
*
* scala> def foo: Int && Int = ???
* foo: &&[Int,Int]
*
* scala> @showAsInfix class &&[T, U]
* defined class $amp$amp
*
* scala> def foo: Int && Int = ???
* foo: Int && Int
* ```
*/
class showAsInfix extends annotation.StaticAnnotation
* This annotation configures how Scala prints two-parameter generic types.
*
* By default, types with symbolic names are printed infix; while types without
* them are printed using the regular generic type syntax.
*
* Example of usage:
{{{
scala> class Map[T, U]
defined class Map

scala> def foo: Int Map Int = ???
foo: Map[Int,Int]

scala> @showAsInfix class Map[T, U]
defined class Map

scala> def foo: Int Map Int = ???
foo: Int Map Int
}}}
*
* @param enabled whether to show this type as an infix type operator.
* @since 2.12.2
*/
class showAsInfix(enabled: Boolean = true) extends annotation.StaticAnnotation
5 changes: 3 additions & 2 deletions src/reflect/scala/reflect/internal/AnnotationInfos.scala
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
/** Check whether any of the arguments mention a symbol */
def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym)

def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
def booleanArg(index: Int) = constantAtIndex(index) map (_ 8000 .booleanValue)
def symbolArg(index: Int) = argAtIndex(index) collect {
case Apply(fun, Literal(str) :: Nil) if fun.symbol == definitions.Symbol_apply =>
newTermName(str.stringValue)
Expand Down
8 changes: 6 additions & 2 deletions src/reflect/scala/reflect/internal/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2101,9 +2101,13 @@ trait Types
toBoolean(trivial)
}

/* It only makes sense to show 2-ary type constructors infix. */
/* It only makes sense to show 2-ary type constructors infix.
* By default we do only if it's a symbolic name. */
override def isShowAsInfixType: Boolean =
sym.hasAnnotation(ShowAsInfixAnnotationClass) && hasLength(args, 2)
hasLength(args, 2) &&
sym.getAnnotation(ShowAsInfixAnnotationClass)
.map(_ booleanArg 0 getOrElse true)
.getOrElse(!Character.isUnicodeIdentifierStart(sym.decodedName.head))

private[Types] def invalidateTypeRefCaches(): Unit = {
parentsCache = null
Expand Down
27 changes: 12 additions & 15 deletions test/files/run/t4700.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@ scala> class &&[T,U]
defined class $amp$amp

scala> def foo: Int && Boolean = ???
foo: &&[Int,Boolean]

scala> @showAsInfix class ||[T,U]
defined class $bar$bar

scala> def foo: Int || Boolean = ???
foo: Int || Boolean

scala> @showAsInfix class &&[T, U]
defined class $amp$amp
foo: Int && Boolean

scala> def foo: Int && Boolean && String = ???
foo: Int && Boolean && String
Expand All @@ -29,7 +20,13 @@ defined type alias Mappy
scala> def foo: Int Mappy (Boolean && String) = ???
foo: Int Mappy (Boolean && String)

scala> @showAsInfix class &:[L, R]
scala> @showAsInfix(false) class ||[T,U]
defined class $bar$bar

scala> def foo: Int || Boolean = ???
foo: ||[Int,Boolean]

scala> class &:[L, R]
defined class $amp$colon

scala> def foo: Int &: String = ???
Expand All @@ -38,10 +35,10 @@ foo: Int &: String
scala> def foo: Int &: Boolean &: String = ???
foo: Int &: Boolean &: String

scala> def foo: (Int || String) &: Boolean = ???
foo: (Int || String) &: Boolean
scala> def foo: (Int && String) &: Boolean = ???
foo: (Int && String) &: Boolean

scala> def foo: Int || (Boolean &: String) = ???
foo: Int || (Boolean &: String)
scala> def foo: Int && (Boolean &: String) = ???
foo: Int && (Boolean &: String)

scala> :quit
11 changes: 5 additions & 6 deletions test/files/run/t4700.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ object Test extends ReplTest {
|import scala.annotation.showAsInfix
|class &&[T,U]
|def foo: Int && Boolean = ???
|@showAsInfix class ||[T,U]
|def foo: Int || Boolean = ???
|@showAsInfix class &&[T, U]
|def foo: Int && Boolean && String = ???
|def foo: Int && (Boolean && String) = ???
|@showAsInfix type Mappy[T, U] = Map[T, U]
|def foo: Int Mappy (Boolean && String) = ???
|@showAsInfix class &:[L, R]
|@showAsInfix(false) class ||[T,U]
|def foo: Int || Boolean = ???
|class &:[L, R]
|def foo: Int &: String = ???
|def foo: Int &: Boolean &: String = ???
|def foo: (Int || String) &: Boolean = ???
|def foo: Int || (Boolean &: String) = ???
|def foo: (Int && String) &: Boolean = ???
|def foo: Int && (Boolean &: String) = ???
|""".stripMargin
}

0