@@ -46,7 +46,7 @@ object Parsers {
4646 }
4747
4848 @ sharable object ParamOwner extends Enumeration {
49- val Class, Type, TypeParam, Def = Value
49+ val Class, Type, TypeParam, Def, Constructor = Value
5050 }
5151
5252 private implicit class AddDeco (val buf : ListBuffer [Tree ]) extends AnyVal {
@@ -714,6 +714,7 @@ object Parsers {
714714 }
715715
716716/* ------------- TYPES ------------------------------------------------------ */
717+
717718 /** Same as [[typ ]], but if this results in a wildcard it emits a syntax error and
718719 * returns a tree for type `Any` instead.
719720 */
@@ -1055,6 +1056,21 @@ object Parsers {
10551056 case None => t
10561057 }
10571058
1059+ /** TypeRHS ::= ‘if’ Expr ‘then’ TypeRHS ‘else’ TypeRHS
1060+ * | Type
1061+ */
1062+ def typeRHS (): Tree =
1063+ if (in.token == IF )
1064+ atPos(in.skipToken()) {
1065+ val cond = typeRHS()
1066+ accept(THEN )
1067+ val thenp = typeRHS()
1068+ accept(ELSE )
1069+ val elsep = expr()
1070+ If (cond, thenp, elsep)
1071+ }
1072+ else toplevelTyp()
1073+
10581074/* ----------- EXPRESSIONS ------------------------------------------------ */
10591075
10601076 /** EqualsExpr ::= `=' Expr
@@ -1831,14 +1847,15 @@ object Parsers {
18311847 */
18321848 def typeParamClause (ownerKind : ParamOwner .Value ): List [TypeDef ] = inBrackets {
18331849 def typeParam (): TypeDef = {
1834- val isConcreteOwner = ownerKind == ParamOwner .Class || ownerKind == ParamOwner .Def
1850+ val isDefOwner = ownerKind == ParamOwner .Def || ownerKind == ParamOwner .Constructor
1851+ val isConcreteOwner = isDefOwner || ownerKind == ParamOwner .Class
18351852 val start = in.offset
18361853 val mods = atPos(start) {
18371854 annotsAsMods() | {
18381855 if (ownerKind == ParamOwner .Class ) Param | PrivateLocal
18391856 else Param
18401857 } | {
1841- if (ownerKind != ParamOwner . Def )
1858+ if (! isDefOwner )
18421859 if (isIdent(nme.raw.PLUS )) { in.nextToken(); Covariant }
18431860 else if (isIdent(nme.raw.MINUS )) { in.nextToken(); Contravariant }
18441861 else EmptyFlags
@@ -1875,14 +1892,14 @@ object Parsers {
18751892 * DefParam ::= {Annotation} [`inline'] Param
18761893 * Param ::= id `:' ParamType [`=' Expr]
18771894 */
1878- def paramClauses (owner : Name , ofCaseClass : Boolean = false ): List [List [ValDef ]] = {
1895+ def paramClauses (ownerKind : ParamOwner . Value , ofCaseClass : Boolean = false ): List [List [ValDef ]] = {
18791896 var imods : Modifiers = EmptyModifiers
18801897 var implicitOffset = - 1 // use once
18811898 var firstClauseOfCaseClass = ofCaseClass
18821899 def param (): ValDef = {
18831900 val start = in.offset
18841901 var mods = annotsAsMods()
1885- if (owner.isTypeName ) {
1902+ if (ownerKind == ParamOwner . Class ) {
18861903 mods = addFlag(modifiers(start = mods), ParamAccessor )
18871904 mods =
18881905 atPos(start, in.offset) {
@@ -1909,7 +1926,7 @@ object Parsers {
19091926 atPos(start, nameStart) {
19101927 val name = ident()
19111928 accept(COLON )
1912- if (in.token == ARROW && owner.isTypeName && ! (mods is Local ))
1929+ if (in.token == ARROW && ownerKind == ParamOwner . Class && ! (mods is Local ))
19131930 syntaxError(VarValParametersMayNotBeCallByName (name, mods is Mutable ))
19141931 val tpt = paramType()
19151932 val default =
@@ -1936,7 +1953,7 @@ object Parsers {
19361953 funArgMods()
19371954 }
19381955 }
1939- funArgMods()
1956+ if (ownerKind != ParamOwner . Type ) funArgMods()
19401957
19411958 commaSeparated(() => param())
19421959 }
@@ -1953,7 +1970,7 @@ object Parsers {
19531970 }
19541971 val start = in.offset
19551972 val result = clauses()
1956- if (owner == nme. CONSTRUCTOR && (result.isEmpty || (result.head take 1 exists (_.mods is Implicit )))) {
1973+ if (ownerKind == ParamOwner . Constructor && (result.isEmpty || (result.head take 1 exists (_.mods is Implicit )))) {
19571974 in.token match {
19581975 case LBRACKET => syntaxError(" no type parameters allowed here" )
19591976 case EOF => incompleteInputError(AuxConstructorNeedsNonImplicitParameter ())
@@ -2121,7 +2138,7 @@ object Parsers {
21212138 }
21222139 if (in.token == THIS ) {
21232140 in.nextToken()
2124- val vparamss = paramClauses(nme. CONSTRUCTOR )
2141+ val vparamss = paramClauses(ParamOwner . Constructor )
21252142 if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE )
21262143 val rhs = {
21272144 if (! (in.token == LBRACE && scala2ProcedureSyntax(" " ))) accept(EQUALS )
@@ -2132,7 +2149,7 @@ object Parsers {
21322149 val mods1 = addFlag(mods, Method )
21332150 val name = ident()
21342151 val tparams = typeParamClauseOpt(ParamOwner .Def )
2135- val vparamss = paramClauses(name )
2152+ val vparamss = paramClauses(ParamOwner . Def )
21362153 var tpt = fromWithinReturnType(typedOpt())
21372154 if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE )
21382155 val rhs =
@@ -2183,19 +2200,27 @@ object Parsers {
21832200 Block (stats, Literal (Constant (())))
21842201 }
21852202
2186- /** TypeDef ::= type id [TypeParamClause] `=' Type
2187- * TypeDcl ::= type id [TypeParamClause ] TypeBounds
2203+ /** TypeDcl ::= id [TypTypeParamClause] {DefParamClause} [‘:’ Type] ‘=’ TypeRHS
2204+ * | id [HkTypeParamClause ] TypeBounds
21882205 */
21892206 def typeDefOrDcl (start : Offset , mods : Modifiers ): Tree = {
21902207 newLinesOpt()
21912208 atPos(start, nameStart) {
21922209 val name = ident().toTypeName
21932210 val tparams = typeParamClauseOpt(ParamOwner .Type )
2211+ val vparamss = paramClauses(ParamOwner .Type )
2212+ val tpt = typedOpt()
2213+ val isDef = ! vparamss.isEmpty || ! tpt.isEmpty
21942214 in.token match {
21952215 case EQUALS =>
21962216 in.nextToken()
2197- TypeDef (name, lambdaAbstract(tparams, toplevelTyp())).withMods(mods).setComment(in.getDocComment(start))
2217+ val rhs = typeRHS()
2218+ val res =
2219+ if (isTypeDefRHS(rhs) || isDef) DefDef (name, tparams, vparamss, tpt, rhs)
2220+ else TypeDef (name, lambdaAbstract(tparams, rhs))
2221+ res.withMods(mods).setComment(in.getDocComment(start))
21982222 case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
2223+ if (isDef) syntaxError(" `=' expected" )
21992224 TypeDef (name, lambdaAbstract(tparams, typeBounds())).withMods(mods).setComment(in.getDocComment(start))
22002225 case _ =>
22012226 syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals (in.token))
@@ -2245,7 +2270,7 @@ object Parsers {
22452270 def classConstr (owner : Name , isCaseClass : Boolean = false ): DefDef = atPos(in.lastOffset) {
22462271 val tparams = typeParamClauseOpt(ParamOwner .Class )
22472272 val cmods = fromWithinClassConstr(constrModsOpt(owner))
2248- val vparamss = paramClauses(owner , isCaseClass)
2273+ val vparamss = paramClauses(ParamOwner . Class , isCaseClass)
22492274 makeConstructor(tparams, vparamss).withMods(cmods)
22502275 }
22512276
0 commit comments