Skip to content

Commit

Permalink
Fix scala#1396: Modify parser to allow wildcard types everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
cswinter committed Aug 1, 2016
1 parent a0ad3f1 commit 6c38603
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 27 deletions.
12 changes: 6 additions & 6 deletions docs/SyntaxSummary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,17 @@ grammar.
| StableId
| Path `.' `type' SingletonTypeTree(p)
| `(' ArgTypes ')' Tuple(ts)
| `_' TypeBounds
| Refinement RefinedTypeTree(EmptyTree, refinement)
| SimpleLiteral SingletonTypeTree(l)
ArgType ::= Type
| `_' TypeBounds
ArgTypes ::= ArgType {`,' ArgType}
FunArgType ::= ArgType
| `=>' ArgType PrefixOp(=>, t)
ArgTypes ::= Type {`,' Type}
| NamedTypeArg {`,' NamedTypeArg }
FunArgType ::= Type
| `=>' Type PrefixOp(=>, t)
ParamType ::= [`=>'] ParamValueType
ParamValueType ::= Type [`*'] PostfixOp(t, "*")
TypeArgs ::= `[' ArgTypes `]' ts
NamedTypeArg ::= id `=' ArgType NamedArg(id, t)
NamedTypeArg ::= id `=' Type NamedArg(id, t)
NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]' nts
Refinement ::= `{' [Dcl] {semi [Dcl]} `}' ds
TypeBounds ::= [`>:' Type] [`<: Type] | INT TypeBoundsTree(lo, hi)
Expand Down
38 changes: 17 additions & 21 deletions src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ object Parsers {
* | StableId
* | Path `.' type
* | `(' ArgTypes `)'
* | `_' TypeBounds
* | Refinement
* | Literal
*/
Expand All @@ -746,6 +747,10 @@ object Parsers {
else if (in.token == LBRACE)
atPos(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
else if (isSimpleLiteral) { SingletonTypeTree(literal()) }
else if (in.token == USCORE) {
val start = in.skipToken()
typeBounds().withPos(Position(start, in.offset, start))
}
else path(thisOK = false, handleSingletonType) match {
case r @ SingletonTypeTree(_) => r
case r => convertToTypeId(r)
Expand All @@ -770,25 +775,16 @@ object Parsers {
atPos(t.pos.start, id.pos.start) { SelectFromTypeTree(t, id.name) }
}

/** ArgType ::= Type | `_' TypeBounds
*/
val argType = () =>
if (in.token == USCORE) {
val start = in.skipToken()
typeBounds().withPos(Position(start, in.offset, start))
}
else typ()

/** NamedTypeArg ::= id `=' ArgType
/** NamedTypeArg ::= id `=' Type
*/
val namedTypeArg = () => {
val name = ident()
accept(EQUALS)
NamedArg(name.toTypeName, argType())
NamedArg(name.toTypeName, typ())
}

/** ArgTypes ::= ArgType {`,' ArgType}
* NamedTypeArg {`,' NamedTypeArg}
/** ArgTypes ::= Type {`,' Type}
* | NamedTypeArg {`,' NamedTypeArg}
*/
def argTypes(namedOK: Boolean = false) = {
def otherArgs(first: Tree, arg: () => Tree): List[Tree] = {
Expand All @@ -801,22 +797,22 @@ object Parsers {
first :: rest
}
if (namedOK && in.token == IDENTIFIER)
argType() match {
typ() match {
case Ident(name) if in.token == EQUALS =>
in.nextToken()
otherArgs(NamedArg(name, argType()), namedTypeArg)
otherArgs(NamedArg(name, typ()), namedTypeArg)
case firstArg =>
if (in.token == EQUALS) println(s"??? $firstArg")
otherArgs(firstArg, argType)
otherArgs(firstArg, typ)
}
else commaSeparated(argType)
else commaSeparated(typ)
}

/** FunArgType ::= ArgType | `=>' ArgType
/** FunArgType ::= Type | `=>' Type
*/
val funArgType = () =>
if (in.token == ARROW) atPos(in.skipToken()) { ByNameTypeTree(argType()) }
else argType()
if (in.token == ARROW) atPos(in.skipToken()) { ByNameTypeTree(typ()) }
else typ()

/** ParamType ::= [`=>'] ParamValueType
*/
Expand All @@ -834,7 +830,7 @@ object Parsers {
} else t
}

/** TypeArgs ::= `[' ArgType {`,' ArgType} `]'
/** TypeArgs ::= `[' Type {`,' Type} `]'
* NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]'
*/
def typeArgs(namedOK: Boolean = false): List[Tree] = inBrackets(argTypes(namedOK))
Expand Down

0 comments on commit 6c38603

Please sign in to comment.