@@ -3066,8 +3066,8 @@ object Parsers {
30663066
30673067 type ImportConstr = (Tree , List [ImportSelector ]) => Tree
30683068
3069- /** Import ::= `import' [`given'] [ ImportExpr {`,' ImportExpr}
3070- * Export ::= `export' [`given'] [ ImportExpr {`,' ImportExpr}
3069+ /** Import ::= `import' ImportExpr {‘,’ ImportExpr}
3070+ * Export ::= `export' ImportExpr {‘,’ ImportExpr}
30713071 */
30723072 def importClause (leading : Token , mkTree : ImportConstr ): List [Tree ] = {
30733073 val offset = accept(leading)
@@ -3097,48 +3097,62 @@ object Parsers {
30973097 ctx.compilationUnit.sourceVersion = Some (SourceVersion .valueOf(imported.toString))
30983098 Import (tree, selectors)
30993099
3100- /** ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec
3101- * ImportSpec ::= id
3102- * | ‘_’
3103- * | ‘given’
3104- * | ‘{’ ImportSelectors) ‘}’
3105- */
3106- def importExpr (mkTree : ImportConstr ): () => Tree = {
3107-
3108- /** '_' */
3109- def wildcardSelectorId () = atSpan(in.skipToken()) { Ident (nme.WILDCARD ) }
3110- def givenSelectorId (start : Offset ) = atSpan(start) { Ident (nme.EMPTY ) }
3100+ /** ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec
3101+ * | SimpleRef ‘as’ id
3102+ * ImportSpec ::= NamedSelector
3103+ * | WildcardSelector
3104+ * | ‘{’ ImportSelectors ‘}’
3105+ * ImportSelectors ::= NamedSelector [‘,’ ImportSelectors]
3106+ * | WildCardSelector {‘,’ WildCardSelector}
3107+ * NamedSelector ::= id [‘as’ (id | ‘_’)]
3108+ * WildCardSelector ::= ‘*' | ‘given’ [InfixType]
3109+ */
3110+ def importExpr (mkTree : ImportConstr ): () => Tree =
3111+
3112+ /** ‘*' | ‘_' */
3113+ def wildcardSelector () =
3114+ if in.token == USCORE && sourceVersion.isAtLeast(`3.1`) then
3115+ report.errorOrMigrationWarning(
3116+ em " `_` is no longer supported for a wildcard import; use `*` instead ${rewriteNotice(" 3.1" )}" ,
3117+ in.sourcePos())
3118+ patch(source, Span (in.offset, in.offset + 1 ), " *" )
3119+ ImportSelector (atSpan(in.skipToken()) { Ident (nme.WILDCARD ) })
3120+
3121+ /** 'given [InfixType]' */
3122+ def givenSelector () =
3123+ ImportSelector (
3124+ atSpan(in.skipToken()) { Ident (nme.EMPTY ) },
3125+ bound =
3126+ if canStartTypeTokens.contains(in.token) then rejectWildcardType(infixType())
3127+ else EmptyTree )
3128+
3129+ /** id [‘as’ (id | ‘_’) */
3130+ def namedSelector (from : Ident ) =
3131+ if in.token == ARROW || isIdent(nme.as) then
3132+ if in.token == ARROW && sourceVersion.isAtLeast(`3.1`) then
3133+ report.errorOrMigrationWarning(
3134+ em " The import renaming `a => b` is no longer supported ; use `a as b` instead ${rewriteNotice(" 3.1" )}" ,
3135+ in.sourcePos())
3136+ patch(source, Span (in.offset, in.offset + 2 ),
3137+ if testChar(in.offset - 1 , ' ' ) && testChar(in.offset + 2 , ' ' ) then " as"
3138+ else " as " )
3139+ atSpan(startOffset(from), in.skipToken()) {
3140+ val to = if in.token == USCORE then wildcardIdent() else termIdent()
3141+ ImportSelector (from, if to.name == nme.ERROR then EmptyTree else to)
3142+ }
3143+ else ImportSelector (from)
31113144
3112- /** ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors]
3113- * | WildCardSelector {‘,’ WildCardSelector}
3114- * WildCardSelector ::= ‘given’ [InfixType]
3115- * | ‘_'
3116- */
31173145 def importSelectors (idOK : Boolean ): List [ImportSelector ] =
3118- val isWildcard = in.token == USCORE || in.token == GIVEN
3146+ val isWildcard = in.token == USCORE || in.token == GIVEN || isIdent(nme.raw. STAR )
31193147 val selector = atSpan(in.offset) {
31203148 in.token match
3121- case USCORE =>
3122- ImportSelector (wildcardSelectorId())
3123- case GIVEN =>
3124- val start = in.skipToken()
3125- if in.token == USCORE then
3126- deprecationWarning(em " `given _` is deprecated in imports; replace with just `given` " , start)
3127- in.nextToken()
3128- ImportSelector (givenSelectorId(start)) // Let the selector span all of `given`; needed for -Ytest-pickler
3129- else if canStartTypeTokens.contains(in.token) then
3130- ImportSelector (givenSelectorId(start), bound = rejectWildcardType(infixType()))
3131- else
3132- ImportSelector (givenSelectorId(start))
3149+ case USCORE => wildcardSelector()
3150+ case GIVEN => givenSelector()
31333151 case _ =>
3134- val from = termIdent()
3135- if ! idOK then syntaxError(i " named imports cannot follow wildcard imports " )
3136- if in.token == ARROW then
3137- atSpan(startOffset(from), in.skipToken()) {
3138- val to = if in.token == USCORE then wildcardIdent() else termIdent()
3139- ImportSelector (from, if to.name == nme.ERROR then EmptyTree else to)
3140- }
3141- else ImportSelector (from)
3152+ if isIdent(nme.raw.STAR ) then wildcardSelector()
3153+ else
3154+ if ! idOK then syntaxError(i " named imports cannot follow wildcard imports " )
3155+ namedSelector(termIdent())
31423156 }
31433157 val rest =
31443158 if in.token == COMMA then
@@ -3149,26 +3163,36 @@ object Parsers {
31493163 selector :: rest
31503164
31513165 def importSelection (qual : Tree ): Tree =
3152- accept(DOT )
3153- in.token match
3154- case USCORE =>
3155- mkTree(qual, ImportSelector (wildcardSelectorId()) :: Nil )
3156- case GIVEN =>
3157- mkTree(qual, ImportSelector (givenSelectorId(in.skipToken())) :: Nil )
3158- case LBRACE =>
3159- mkTree(qual, inBraces(importSelectors(idOK = true )))
3160- case _ =>
3161- val start = in.offset
3162- val name = ident()
3163- if in.token == DOT then
3164- importSelection(atSpan(startOffset(qual), start) { Select (qual, name) })
3165- else
3166- atSpan(startOffset(qual)) {
3167- mkTree(qual, ImportSelector (atSpan(start) { Ident (name) }) :: Nil )
3168- }
3169-
3170- () => importSelection(simpleRef())
3171- }
3166+ if in.isIdent(nme.as) && qual.isInstanceOf [RefTree ] then
3167+ qual match
3168+ case Select (qual1, name) =>
3169+ val from = Ident (name).withSpan(Span (qual.span.point, qual.span.end, 0 ))
3170+ mkTree(qual1, namedSelector(from) :: Nil )
3171+ case qual : Ident =>
3172+ mkTree(EmptyTree , namedSelector(qual) :: Nil )
3173+ else
3174+ accept(DOT )
3175+ in.token match
3176+ case USCORE =>
3177+ mkTree(qual, wildcardSelector() :: Nil )
3178+ case GIVEN =>
3179+ mkTree(qual, givenSelector() :: Nil )
3180+ case LBRACE =>
3181+ mkTree(qual, inBraces(importSelectors(idOK = true )))
3182+ case _ =>
3183+ if isIdent(nme.raw.STAR ) then
3184+ mkTree(qual, wildcardSelector() :: Nil )
3185+ else
3186+ val start = in.offset
3187+ val name = ident()
3188+ if in.token == DOT then
3189+ importSelection(atSpan(startOffset(qual), start) { Select (qual, name) })
3190+ else
3191+ mkTree(qual, namedSelector(atSpan(start) { Ident (name) }) :: Nil )
3192+ end importSelection
3193+
3194+ () => atSpan(in.offset) { importSelection(simpleRef()) }
3195+ end importExpr
31723196
31733197 /** Def ::= val PatDef
31743198 * | var VarDef
0 commit comments