@@ -46,7 +46,7 @@ object Parsers {
46
46
}
47
47
48
48
@ sharable object ParamOwner extends Enumeration {
49
- val Class, Type, TypeParam, Def = Value
49
+ val Class, Type, TypeParam, Def, Constructor = Value
50
50
}
51
51
52
52
private implicit class AddDeco (val buf : ListBuffer [Tree ]) extends AnyVal {
@@ -714,6 +714,7 @@ object Parsers {
714
714
}
715
715
716
716
/* ------------- TYPES ------------------------------------------------------ */
717
+
717
718
/** Same as [[typ ]], but if this results in a wildcard it emits a syntax error and
718
719
* returns a tree for type `Any` instead.
719
720
*/
@@ -1055,6 +1056,21 @@ object Parsers {
1055
1056
case None => t
1056
1057
}
1057
1058
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
+
1058
1074
/* ----------- EXPRESSIONS ------------------------------------------------ */
1059
1075
1060
1076
/** EqualsExpr ::= `=' Expr
@@ -1831,14 +1847,15 @@ object Parsers {
1831
1847
*/
1832
1848
def typeParamClause (ownerKind : ParamOwner .Value ): List [TypeDef ] = inBrackets {
1833
1849
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
1835
1852
val start = in.offset
1836
1853
val mods = atPos(start) {
1837
1854
annotsAsMods() | {
1838
1855
if (ownerKind == ParamOwner .Class ) Param | PrivateLocal
1839
1856
else Param
1840
1857
} | {
1841
- if (ownerKind != ParamOwner . Def )
1858
+ if (! isDefOwner )
1842
1859
if (isIdent(nme.raw.PLUS )) { in.nextToken(); Covariant }
1843
1860
else if (isIdent(nme.raw.MINUS )) { in.nextToken(); Contravariant }
1844
1861
else EmptyFlags
@@ -1875,14 +1892,14 @@ object Parsers {
1875
1892
* DefParam ::= {Annotation} [`inline'] Param
1876
1893
* Param ::= id `:' ParamType [`=' Expr]
1877
1894
*/
1878
- def paramClauses (owner : Name , ofCaseClass : Boolean = false ): List [List [ValDef ]] = {
1895
+ def paramClauses (ownerKind : ParamOwner . Value , ofCaseClass : Boolean = false ): List [List [ValDef ]] = {
1879
1896
var imods : Modifiers = EmptyModifiers
1880
1897
var implicitOffset = - 1 // use once
1881
1898
var firstClauseOfCaseClass = ofCaseClass
1882
1899
def param (): ValDef = {
1883
1900
val start = in.offset
1884
1901
var mods = annotsAsMods()
1885
- if (owner.isTypeName ) {
1902
+ if (ownerKind == ParamOwner . Class ) {
1886
1903
mods = addFlag(modifiers(start = mods), ParamAccessor )
1887
1904
mods =
1888
1905
atPos(start, in.offset) {
@@ -1909,7 +1926,7 @@ object Parsers {
1909
1926
atPos(start, nameStart) {
1910
1927
val name = ident()
1911
1928
accept(COLON )
1912
- if (in.token == ARROW && owner.isTypeName && ! (mods is Local ))
1929
+ if (in.token == ARROW && ownerKind == ParamOwner . Class && ! (mods is Local ))
1913
1930
syntaxError(VarValParametersMayNotBeCallByName (name, mods is Mutable ))
1914
1931
val tpt = paramType()
1915
1932
val default =
@@ -1936,7 +1953,7 @@ object Parsers {
1936
1953
funArgMods()
1937
1954
}
1938
1955
}
1939
- funArgMods()
1956
+ if (ownerKind != ParamOwner . Type ) funArgMods()
1940
1957
1941
1958
commaSeparated(() => param())
1942
1959
}
@@ -1953,7 +1970,7 @@ object Parsers {
1953
1970
}
1954
1971
val start = in.offset
1955
1972
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 )))) {
1957
1974
in.token match {
1958
1975
case LBRACKET => syntaxError(" no type parameters allowed here" )
1959
1976
case EOF => incompleteInputError(AuxConstructorNeedsNonImplicitParameter ())
@@ -2121,7 +2138,7 @@ object Parsers {
2121
2138
}
2122
2139
if (in.token == THIS ) {
2123
2140
in.nextToken()
2124
- val vparamss = paramClauses(nme. CONSTRUCTOR )
2141
+ val vparamss = paramClauses(ParamOwner . Constructor )
2125
2142
if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE )
2126
2143
val rhs = {
2127
2144
if (! (in.token == LBRACE && scala2ProcedureSyntax(" " ))) accept(EQUALS )
@@ -2132,7 +2149,7 @@ object Parsers {
2132
2149
val mods1 = addFlag(mods, Method )
2133
2150
val name = ident()
2134
2151
val tparams = typeParamClauseOpt(ParamOwner .Def )
2135
- val vparamss = paramClauses(name )
2152
+ val vparamss = paramClauses(ParamOwner . Def )
2136
2153
var tpt = fromWithinReturnType(typedOpt())
2137
2154
if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE )
2138
2155
val rhs =
@@ -2183,19 +2200,27 @@ object Parsers {
2183
2200
Block (stats, Literal (Constant (())))
2184
2201
}
2185
2202
2186
- /** TypeDef ::= type id [TypeParamClause] `=' Type
2187
- * TypeDcl ::= type id [TypeParamClause ] TypeBounds
2203
+ /** TypeDcl ::= id [TypTypeParamClause] {DefParamClause} [‘:’ Type] ‘=’ TypeRHS
2204
+ * | id [HkTypeParamClause ] TypeBounds
2188
2205
*/
2189
2206
def typeDefOrDcl (start : Offset , mods : Modifiers ): Tree = {
2190
2207
newLinesOpt()
2191
2208
atPos(start, nameStart) {
2192
2209
val name = ident().toTypeName
2193
2210
val tparams = typeParamClauseOpt(ParamOwner .Type )
2211
+ val vparamss = paramClauses(ParamOwner .Type )
2212
+ val tpt = typedOpt()
2213
+ val isDef = ! vparamss.isEmpty || ! tpt.isEmpty
2194
2214
in.token match {
2195
2215
case EQUALS =>
2196
2216
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))
2198
2222
case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
2223
+ if (isDef) syntaxError(" `=' expected" )
2199
2224
TypeDef (name, lambdaAbstract(tparams, typeBounds())).withMods(mods).setComment(in.getDocComment(start))
2200
2225
case _ =>
2201
2226
syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals (in.token))
@@ -2245,7 +2270,7 @@ object Parsers {
2245
2270
def classConstr (owner : Name , isCaseClass : Boolean = false ): DefDef = atPos(in.lastOffset) {
2246
2271
val tparams = typeParamClauseOpt(ParamOwner .Class )
2247
2272
val cmods = fromWithinClassConstr(constrModsOpt(owner))
2248
- val vparamss = paramClauses(owner , isCaseClass)
2273
+ val vparamss = paramClauses(ParamOwner . Class , isCaseClass)
2249
2274
makeConstructor(tparams, vparamss).withMods(cmods)
2250
2275
}
2251
2276
0 commit comments