Skip to content

Commit

Permalink
Merge pull request scala#2718 from dotty-staging/infix-prettyprint
Browse files Browse the repository at this point in the history
SI-4700 Types with symbolic names print in infix by default
  • Loading branch information
smarter authored Jun 9, 2017
2 parents b7632b9 + a9032b0 commit 1d24a1b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
23 changes: 23 additions & 0 deletions compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,28 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
toTextTuple(args.init)
("implicit " provided isImplicit) ~ argStr ~ " => " ~ argText(args.last)
}

def isInfixType(tp: Type): Boolean = tp match {
case AppliedType(tycon, args) =>
args.length == 2 &&
!Character.isUnicodeIdentifierStart(tycon.typeSymbol.name.toString.head)
// TODO: Once we use the 2.12 stdlib, also check the @showAsInfix annotation
case _ =>
false
}
def toTextInfixType(op: Type, args: List[Type]): Text = {
/* SLS 3.2.8: all infix types have the same precedence.
* In A op B op' C, op and op' need the same associativity.
* Therefore, if op is left associative, anything on its right
* needs to be parenthesized if it's an infix type, and vice versa. */
val l :: r :: Nil = args
val isRightAssoc = op.typeSymbol.name.endsWith(":")
val leftArg = if (isRightAssoc && isInfixType(l)) "(" ~ toText(l) ~ ")" else toText(l)
val rightArg = if (!isRightAssoc && isInfixType(r)) "(" ~ toText(r) ~ ")" else toText(r)

leftArg ~ " " ~ toTextLocal(op) ~ " " ~ rightArg
}

homogenize(tp) match {
case x: ConstantType if homogenizedView =>
return toText(x.widen)
Expand All @@ -132,6 +154,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
if (tycon.isRepeatedParam) return toTextLocal(args.head) ~ "*"
if (defn.isFunctionClass(cls)) return toTextFunction(args, cls.name.isImplicitFunction)
if (defn.isTupleClass(cls)) return toTextTuple(args)
if (isInfixType(tp)) return toTextInfixType(tycon, args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
case tp: TypeRef =>
val hideType = !ctx.settings.debugAlias.value && (tp.symbol.isAliasPreferred)
Expand Down
19 changes: 19 additions & 0 deletions tests/repl/infix-types.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
scala> class &&[T,U]
defined class &&
scala> def foo: Int && Boolean = ???
def foo: Int && Boolean
scala> def foo: Int && Boolean && String = ???
def foo: Int && Boolean && String
scala> def foo: Int && (Boolean && String) = ???
def foo: Int && (Boolean && String)
scala> class &:[L, R]
defined class &:
scala> def foo: Int &: String = ???
def foo: Int &: String
scala> def foo: Int &: Boolean &: String = ???
def foo: Int &: Boolean &: String
scala> def foo: (Int && String) &: Boolean = ???
def foo: (Int && String) &: Boolean
scala> def foo: Int && (Boolean &: String) = ???
def foo: Int && (Boolean &: String)
scala> :quit

0 comments on commit 1d24a1b

Please sign in to comment.