From 6c386039fa5df125492bfdcffdc06cf90fb134f1 Mon Sep 17 00:00:00 2001 From: Clemens Winter Date: Fri, 22 Jul 2016 13:43:02 +0200 Subject: Fix #1396: Modify parser to allow wildcard types everywhere --- docs/SyntaxSummary.txt | 12 +++++----- src/dotty/tools/dotc/parsing/Parsers.scala | 38 +++++++++++++----------------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/docs/SyntaxSummary.txt b/docs/SyntaxSummary.txt index 6751c90e2..f07335d1d 100644 --- a/docs/SyntaxSummary.txt +++ b/docs/SyntaxSummary.txt @@ -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) diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index 82add4c14..572db975c 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -737,6 +737,7 @@ object Parsers { * | StableId * | Path `.' type * | `(' ArgTypes `)' + * | `_' TypeBounds * | Refinement * | Literal */ @@ -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) @@ -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] = { @@ -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 */ @@ -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)) -- cgit v1.2.3