scala-ide / scalariform

Scala source code formatter
http://scala-ide.github.com/scalariform/
MIT License
527 stars 148 forks source link

Trailing commas in class and function headers crash scalariform #284

Open fdietze opened 5 years ago

fdietze commented 5 years ago

While this works:

$ scalariform
class A(x:Int,
y:int
)

class A(
  x: Int,
  y: int
)

Adding a trailing comma crashes scalariform 2.10:

$ scalariform
class A(x:Int,
y:Int,
)

Exception in thread "main" java.lang.IllegalArgumentException: requirement failed: Parse tokens differ from expected.
  Actual = 
Token(CLASS,class,0,class)
Token(VARID,A,6,A)
Token(LPAREN,(,7,()
Token(VARID,x,8,x)
Token(COLON,:,9,:)
Token(VARID,Int,10,Int)
Token(COMMA,,,13,,)
Token(VARID,y,15,y)
Token(COLON,:,16,:)
Token(VARID,Int,17,Int)
Token(RPAREN,),22,))
Token(NEWLINES,

,23,

)
  expected = 
Token(CLASS,class,0,class)
Token(VARID,A,6,A)
Token(LPAREN,(,7,()
Token(VARID,x,8,x)
Token(COLON,:,9,:)
Token(VARID,Int,10,Int)
Token(COMMA,,,13,,)
Token(VARID,y,15,y)
Token(COLON,:,16,:)
Token(VARID,Int,17,Int)
Token(COMMA,,,20,,)
Token(RPAREN,),22,))
Token(NEWLINES,

,23,

)
  parseResult = 
CompilationUnit(StatSeq(None,Some(FullDefOrDcl(List(),List(),TmplDef(List(Token(CLASS,class,0,class)),Token(VARID,A,6,A),None,List(),None,Some(ParamClauses(None,List((ParamClause(Token(LPAREN,(,7,(),None,Some(Param(List(),List(),None,Token(VARID,x,8,x),Some((Token(COLON,:,9,:),Type(List(Type(List(GeneralTokens(List(Token(VARID,Int,10,Int))))))))),None)),List((Token(COMMA,,,13,,),Param(List(),List(),None,Token(VARID,y,15,y),Some((Token(COLON,:,16,:),Type(List(Type(List(GeneralTokens(List(Token(VARID,Int,17,Int))))))))),None))),Token(RPAREN,),22,)),Some(Token(COMMA,,,20,,))),None)))),None,None))),List((Token(NEWLINES,

,23,

),None))),Token(EOF,,25,))
    at scala.Predef$.require(Predef.scala:281)
    at scalariform.formatter.SpecificFormatter.fullFormat(SpecificFormatter.scala:54)
    at scalariform.formatter.SpecificFormatter.fullFormat$(SpecificFormatter.scala:27)
    at scalariform.formatter.ScalaFormatter$$anon$1.fullFormat(ScalaFormatter.scala:593)
    at scalariform.formatter.ScalaFormatter$.formatAsEdits(ScalaFormatter.scala:602)
    at scalariform.formatter.ScalaFormatter$.format(ScalaFormatter.scala:586)
    at scalariform.commandline.Main$.$anonfun$process$19(Main.scala:167)
    at scalariform.commandline.Main$.transformSysInToSysOut(Main.scala:209)
    at scalariform.commandline.Main$.process(Main.scala:179)
    at scalariform.commandline.Main$.main(Main.scala:16)
    at scalariform.commandline.Main.main(Main.scala)

The same happens with trailing commas in functions:

$ scalariform
def f(x:Int,
y:Int,
) = x + y

Exception in thread "main" java.lang.IllegalArgumentException: requirement failed: Parse tokens differ from expected.
  Actual = 
Token(DEF,def,0,def)
Token(VARID,f,4,f)
Token(LPAREN,(,5,()
Token(VARID,x,6,x)
Token(COLON,:,7,:)
Token(VARID,Int,8,Int)
Token(COMMA,,,11,,)
Token(VARID,y,13,y)
Token(COLON,:,14,:)
Token(VARID,Int,15,Int)
Token(RPAREN,),20,))
Token(EQUALS,=,22,=)
Token(VARID,x,24,x)
Token(PLUS,+,26,+)
Token(VARID,y,28,y)
Token(NEWLINE,
,29,
)
  expected = 
Token(DEF,def,0,def)
Token(VARID,f,4,f)
Token(LPAREN,(,5,()
Token(VARID,x,6,x)
Token(COLON,:,7,:)
Token(VARID,Int,8,Int)
Token(COMMA,,,11,,)
Token(VARID,y,13,y)
Token(COLON,:,14,:)
Token(VARID,Int,15,Int)
Token(COMMA,,,18,,)
Token(RPAREN,),20,))
Token(EQUALS,=,22,=)
Token(VARID,x,24,x)
Token(PLUS,+,26,+)
Token(VARID,y,28,y)
Token(NEWLINE,
,29,
)
  parseResult = 
CompilationUnit(StatSeq(None,Some(FullDefOrDcl(List(),List(),FunDefOrDcl(Token(DEF,def,0,def),Token(VARID,f,4,f),None,ParamClauses(None,List((ParamClause(Token(LPAREN,(,5,(),None,Some(Param(List(),List(),None,Token(VARID,x,6,x),Some((Token(COLON,:,7,:),Type(List(Type(List(GeneralTokens(List(Token(VARID,Int,8,Int))))))))),None)),List((Token(COMMA,,,11,,),Param(List(),List(),None,Token(VARID,y,13,y),Some((Token(COLON,:,14,:),Type(List(Type(List(GeneralTokens(List(Token(VARID,Int,15,Int))))))))),None))),Token(RPAREN,),20,)),Some(Token(COMMA,,,18,,))),None))),None,Some(ExprFunBody(Token(EQUALS,=,22,=),None,Expr(List(InfixExpr(List(CallExpr(None,Token(VARID,x,24,x),None,List(),None)),Token(PLUS,+,26,+),None,List(CallExpr(None,Token(VARID,y,28,y),None,List(),None))))))),false))),List((Token(NEWLINE,
,29,
),None))),Token(EOF,,30,))
    at scala.Predef$.require(Predef.scala:281)
    at scalariform.formatter.SpecificFormatter.fullFormat(SpecificFormatter.scala:54)
    at scalariform.formatter.SpecificFormatter.fullFormat$(SpecificFormatter.scala:27)
    at scalariform.formatter.ScalaFormatter$$anon$1.fullFormat(ScalaFormatter.scala:593)
    at scalariform.formatter.ScalaFormatter$.formatAsEdits(ScalaFormatter.scala:602)
    at scalariform.formatter.ScalaFormatter$.format(ScalaFormatter.scala:586)
    at scalariform.commandline.Main$.$anonfun$process$19(Main.scala:167)
    at scalariform.commandline.Main$.transformSysInToSysOut(Main.scala:209)
    at scalariform.commandline.Main$.process(Main.scala:179)
    at scalariform.commandline.Main$.main(Main.scala:16)
    at scalariform.commandline.Main.main(Main.scala)
udalrich commented 5 years ago

This also crashes scalariform in import statements:

package test

import scala.collection.{
    Map,
    Seq,
}

Compiling with sbt yields

[warn] Scalariform parser error for /projects//src/main/scala/com/example/Test.scala: Expected identifier, but got Token(RBRACE,},58,})
igorgatis commented 3 years ago

Any news on this?

hubertta commented 1 year ago

I made a pull request that should take care of this problem: https://github.com/scala-ide/scalariform/pull/296