Skip to content

Commit 53a2614

Browse files
author
dmitry.naydanov
committed
Trailing commas support, see scala/scala#5245 ; also getting rid of yellow code #SCL-10597 fixed
1 parent 6049f48 commit 53a2614

28 files changed

+1577
-101
lines changed

src/org/jetbrains/plugins/scala/lang/parser/parsing/base/ImportSelectors.scala

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,61 +25,65 @@ object ImportSelectors extends ParserNode {
2525
builder.getTokenType match {
2626
case ScalaTokenTypes.tLBRACE =>
2727
builder.advanceLexer() //Ate {
28-
builder.enableNewlines
28+
builder.enableNewlines()
2929
case _ =>
3030
builder error ErrMsg("lbrace.expected")
3131
importSelectorMarker.drop()
3232
return false
3333
}
34+
35+
def doneImportSelectors() {
36+
builder.advanceLexer()
37+
builder.restoreNewlinesState()
38+
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
39+
}
40+
3441
//Let's parse Import selectors while we will not see Import selector or will see '}'
3542
while (true) {
3643
builder.getTokenType match {
3744
case ScalaTokenTypes.tRBRACE =>
3845
builder error ErrMsg("import.selector.expected")
3946
builder.advanceLexer() //Ate }
40-
builder.restoreNewlinesState
47+
builder.restoreNewlinesState()
4148
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
4249
return true
4350
case ScalaTokenTypes.tUNDER =>
4451
builder.advanceLexer() //Ate _
4552
builder.getTokenType match {
46-
case ScalaTokenTypes.tRBRACE => {
53+
case ScalaTokenTypes.tRBRACE =>
4754
builder.advanceLexer() //Ate }
48-
builder.restoreNewlinesState
55+
builder.restoreNewlinesState()
4956
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
5057
return true
51-
}
52-
case _ => {
58+
case _ =>
5359
ParserUtils.parseLoopUntilRBrace(builder, () => {}) //we need to find closing brace, otherwise we can miss important things
54-
builder.restoreNewlinesState
60+
builder.restoreNewlinesState()
5561
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
5662
return true
57-
}
5863
}
5964
case ScalaTokenTypes.tIDENTIFIER =>
6065
ImportSelector parse builder
66+
67+
if (ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRBRACE)) {
68+
doneImportSelectors()
69+
return true
70+
}
71+
6172
builder.getTokenType match {
62-
case ScalaTokenTypes.tCOMMA => {
63-
builder.advanceLexer() //Ate ,
64-
}
65-
case ScalaTokenTypes.tRBRACE => {
66-
builder.advanceLexer() //Ate}
67-
builder.restoreNewlinesState
68-
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
73+
case ScalaTokenTypes.tCOMMA => builder.advanceLexer() //Ate ,
74+
case ScalaTokenTypes.tRBRACE =>
75+
doneImportSelectors()
6976
return true
70-
}
71-
case null => {
72-
builder.restoreNewlinesState
77+
case null =>
78+
builder.restoreNewlinesState()
7379
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
7480
return true
75-
}
76-
case _ => {
81+
case _ =>
7782
builder error ErrMsg("rbrace.expected")
7883
builder.advanceLexer()
79-
}
8084
}
8185
case null =>
82-
builder.restoreNewlinesState
86+
builder.restoreNewlinesState()
8387
importSelectorMarker.done(ScalaElementTypes.IMPORT_SELECTORS)
8488
return true
8589
case _ =>

src/org/jetbrains/plugins/scala/lang/parser/parsing/builder/ScalaPsiBuilderImpl.scala

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package org.jetbrains.plugins.scala.lang.parser.parsing.builder
22

33
import com.intellij.lang.PsiBuilder
44
import com.intellij.lang.impl.PsiBuilderAdapter
5-
import com.intellij.openapi.util.text.StringUtil
6-
import org.jetbrains.plugins.scala.lang.TokenSets
75
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
86

97
import scala.collection.mutable
@@ -34,26 +32,20 @@ class ScalaPsiBuilderImpl(builder: PsiBuilder)
3432
if (eof) return 0
3533
if (!ParserUtils.elementCanStartStatement(getTokenType, this)) return 0
3634

37-
var i = 1
38-
while (i < getCurrentOffset && TokenSets.WHITESPACE_OR_COMMENT_SET.contains(rawLookup(-i))) i += 1
39-
val textBefore = getOriginalText.subSequence(rawTokenTypeStart(-i + 1), rawTokenTypeStart(0)).toString
40-
if (!textBefore.contains('\n')) return 0
41-
val lines = s"start $textBefore end".split('\n')
42-
if (lines.exists(_.forall(StringUtil.isWhiteSpace))) 2
43-
else 1
35+
ParserUtils.countNewLinesBeforeCurrentTokenRaw(this)
4436
}
4537

4638
def isNewlinesEnabled: Boolean = newlinesEnabled.isEmpty || newlinesEnabled.top
4739

48-
def disableNewlines {
40+
def disableNewlines() {
4941
newlinesEnabled.push(false)
5042
}
5143

52-
def enableNewlines {
44+
def enableNewlines() {
5345
newlinesEnabled.push(true)
5446
}
5547

56-
def restoreNewlinesState {
48+
def restoreNewlinesState() {
5749
assert(newlinesEnabled.nonEmpty)
5850
newlinesEnabled.pop()
5951
}

src/org/jetbrains/plugins/scala/lang/parser/parsing/expressions/ArgumentExprs.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package expressions
66

77
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
88
import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
9+
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
910

1011
/**
1112
* @author Alexander Podkhalyuzin
@@ -30,21 +31,20 @@ trait ArgumentExprs {
3031
builder.getTokenType match {
3132
case ScalaTokenTypes.tLPARENTHESIS =>
3233
builder.advanceLexer() //Ate (
33-
builder.disableNewlines
34+
builder.disableNewlines()
3435
expr parse builder
35-
while (builder.getTokenType == ScalaTokenTypes.tCOMMA) {
36+
while (builder.getTokenType == ScalaTokenTypes.tCOMMA && !ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRPARENTHESIS)) {
3637
builder.advanceLexer()
37-
if (!expr.parse(builder)) {
38-
builder error ErrMsg("wrong.expression")
39-
}
38+
if (!expr.parse(builder)) builder error ErrMsg("wrong.expression")
4039
}
40+
4141
builder.getTokenType match {
4242
case ScalaTokenTypes.tRPARENTHESIS =>
4343
builder.advanceLexer() //Ate )
4444
case _ =>
4545
builder error ScalaBundle.message("rparenthesis.expected")
4646
}
47-
builder.restoreNewlinesState
47+
builder.restoreNewlinesState()
4848
argMarker.done(ScalaElementTypes.ARG_EXPRS)
4949
true
5050
case ScalaTokenTypes.tLBRACE =>

src/org/jetbrains/plugins/scala/lang/parser/parsing/expressions/Bindings.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package expressions
66

77
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
88
import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
9+
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
910

1011
/**
1112
* @author Alexander Podkhalyuzin
@@ -34,7 +35,7 @@ trait Bindings {
3435
return false
3536
}
3637
binding parse builder
37-
while (builder.getTokenType == ScalaTokenTypes.tCOMMA) {
38+
while (builder.getTokenType == ScalaTokenTypes.tCOMMA && !ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRPARENTHESIS)) {
3839
builder.advanceLexer() //Ate ,
3940
if (!binding.parse(builder)) {
4041
builder error ErrMsg("wrong.binding")

src/org/jetbrains/plugins/scala/lang/parser/parsing/expressions/SimpleExpr.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,17 @@ trait SimpleExpr extends ParserNode with ScalaTokenTypes {
7777
case ScalaTokenTypes.tLPARENTHESIS =>
7878
state = true
7979
builder.advanceLexer()
80-
builder.disableNewlines
80+
builder.disableNewlines()
8181
builder.getTokenType match {
8282
case ScalaTokenTypes.tRPARENTHESIS =>
8383
builder.advanceLexer()
84-
builder.restoreNewlinesState
84+
builder.restoreNewlinesState()
8585
newMarker = simpleMarker.precede
8686
simpleMarker.done(ScalaElementTypes.UNIT_EXPR)
8787
case _ =>
8888
if (!expr.parse(builder)) {
8989
builder error ErrMsg("rparenthesis.expected")
90-
builder.restoreNewlinesState
90+
builder.restoreNewlinesState()
9191
newMarker = simpleMarker.precede
9292
simpleMarker.done(ScalaElementTypes.UNIT_EXPR)
9393
} else {
@@ -109,7 +109,7 @@ trait SimpleExpr extends ParserNode with ScalaTokenTypes {
109109
} else {
110110
builder.advanceLexer()
111111
}
112-
builder.restoreNewlinesState
112+
builder.restoreNewlinesState()
113113
newMarker = simpleMarker.precede
114114
simpleMarker.done(if (isTuple) ScalaElementTypes.TUPLE else ScalaElementTypes.PARENT_EXPR)
115115
}
@@ -174,6 +174,7 @@ trait SimpleExpr extends ParserNode with ScalaTokenTypes {
174174
}
175175
}
176176
subparse(newMarker)
177-
return true
177+
178+
true
178179
}
179180
}

src/org/jetbrains/plugins/scala/lang/parser/parsing/params/FunTypeParamClause.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package params
66

77
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
88
import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
9+
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
910

1011
/**
1112
* @author Alexander Podkhalyuzin
@@ -22,27 +23,27 @@ object FunTypeParamClause {
2223
builder.getTokenType match {
2324
case ScalaTokenTypes.tLSQBRACKET =>
2425
builder.advanceLexer() //Ate [
25-
builder.disableNewlines
26+
builder.disableNewlines()
2627
case _ =>
27-
funMarker.drop
28+
funMarker.drop()
2829
return false
2930
}
3031
if (!TypeParam.parse(builder, mayHaveVariance = false)) {
3132
builder error ErrMsg("wrong.parameter")
3233
}
33-
while (builder.getTokenType == ScalaTokenTypes.tCOMMA) {
34+
while (builder.getTokenType == ScalaTokenTypes.tCOMMA && !ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRSQBRACKET)) {
3435
builder.advanceLexer() //Ate
3536
if (!TypeParam.parse(builder, mayHaveVariance = false)) {
3637
builder error ErrMsg("wrong.parameter")
3738
}
3839
}
3940
builder.getTokenType match {
4041
case ScalaTokenTypes.tRSQBRACKET =>
41-
builder.advanceLexer //Ate ]
42+
builder.advanceLexer() //Ate ]
4243
case _ => builder error ErrMsg("wrong.parameter")
4344
}
44-
builder.restoreNewlinesState
45+
builder.restoreNewlinesState()
4546
funMarker.done(ScalaElementTypes.TYPE_PARAM_CLAUSE)
46-
return true
47+
true
4748
}
4849
}

src/org/jetbrains/plugins/scala/lang/parser/parsing/params/Params.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package params
66

77
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
88
import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
9+
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
910

1011
/**
1112
* @author Alexander Podkhalyuzin
@@ -26,7 +27,7 @@ trait Params {
2627
if (!param.parse(builder)) {
2728
return false
2829
}
29-
while (builder.getTokenType == ScalaTokenTypes.tCOMMA) {
30+
while (builder.getTokenType == ScalaTokenTypes.tCOMMA && !ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRPARENTHESIS)) {
3031
builder.advanceLexer() //Ate ,
3132
if (!param.parse(builder)) {
3233
builder error ScalaBundle.message("wrong.parameter")

src/org/jetbrains/plugins/scala/lang/parser/parsing/params/TypeParamClause.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package params
66

77
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
88
import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
9+
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
910

1011
/**
1112
* @author Alexander Podkhalyuzin
@@ -26,29 +27,29 @@ trait TypeParamClause {
2627
val typeMarker = builder.mark
2728
builder.getTokenType match {
2829
case ScalaTokenTypes.tLSQBRACKET =>
29-
builder.advanceLexer //Ate [
30-
builder.disableNewlines
30+
builder.advanceLexer() //Ate [
31+
builder.disableNewlines()
3132
case _ =>
32-
typeMarker.drop
33+
typeMarker.drop()
3334
return false
3435
}
3536
if (!typeParam.parse(builder, mayHaveVariance = true)) {
3637
builder error ScalaBundle.message("wrong.parameter")
3738
}
38-
while (builder.getTokenType == ScalaTokenTypes.tCOMMA) {
39+
while (builder.getTokenType == ScalaTokenTypes.tCOMMA && !ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRSQBRACKET)) {
3940
builder.advanceLexer() //Ate
4041
if (!typeParam.parse(builder, mayHaveVariance = true)) {
4142
builder error ScalaBundle.message("wrong.parameter")
4243
}
4344
}
4445
builder.getTokenType match {
4546
case ScalaTokenTypes.tRSQBRACKET =>
46-
builder.advanceLexer //Ate ]
47+
builder.advanceLexer() //Ate ]
4748
case _ =>
4849
builder error ScalaBundle.message("rsqbracket.expected")
4950
}
50-
builder.restoreNewlinesState
51+
builder.restoreNewlinesState()
5152
typeMarker.done(ScalaElementTypes.TYPE_PARAM_CLAUSE)
52-
return true
53+
true
5354
}
5455
}

src/org/jetbrains/plugins/scala/lang/parser/parsing/top/params/ClassParamClause.scala

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package top.params
66

77
import org.jetbrains.plugins.scala.lang.lexer.ScalaTokenTypes
88
import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
9+
import org.jetbrains.plugins.scala.lang.parser.util.ParserUtils
910

1011
/**
1112
* @author Alexander Podkhalyuzin
@@ -31,41 +32,40 @@ trait ClassParamClause {
3132
//Look for '('
3233
builder.getTokenType match {
3334
case ScalaTokenTypes.tLPARENTHESIS =>
34-
builder.advanceLexer //Ate '('
35-
builder.disableNewlines
35+
builder.advanceLexer() //Ate '('
36+
builder.disableNewlines()
3637
builder.getTokenType match {
37-
case ScalaTokenTypes.kIMPLICIT => {
38-
classParamMarker.rollbackTo
39-
builder.restoreNewlinesState
38+
case ScalaTokenTypes.kIMPLICIT =>
39+
classParamMarker.rollbackTo()
40+
builder.restoreNewlinesState()
4041
return false
41-
}
42-
case _ => {}
42+
case _ =>
4343
}
4444
//ok, let's parse parameters
4545
if (classParam parse builder) {
46-
while (builder.getTokenType == ScalaTokenTypes.tCOMMA) {
47-
builder.advanceLexer //Ate ,
46+
while (builder.getTokenType == ScalaTokenTypes.tCOMMA && !ParserUtils.eatTrailingComma(builder, ScalaTokenTypes.tRPARENTHESIS)) {
47+
builder.advanceLexer() //Ate ,
4848
if (!(classParam parse builder)) {
4949
builder error ErrMsg("wrong.parameter")
5050
}
5151
}
5252
}
5353
case _ =>
54-
classParamMarker.rollbackTo
54+
classParamMarker.rollbackTo()
5555
return false
5656
}
5757
//Look for ')'
5858
builder.getTokenType match {
5959
case ScalaTokenTypes.tRPARENTHESIS =>
60-
builder.advanceLexer //Ate )
61-
builder.restoreNewlinesState
60+
builder.advanceLexer() //Ate )
61+
builder.restoreNewlinesState()
6262
classParamMarker.done(ScalaElementTypes.PARAM_CLAUSE)
63-
return true
63+
true
6464
case _ =>
6565
classParamMarker.done(ScalaElementTypes.PARAM_CLAUSE)
6666
builder error ErrMsg("rparenthesis.expected")
67-
builder.restoreNewlinesState
68-
return true
67+
builder.restoreNewlinesState()
68+
true
6969
}
7070
}
7171
}

0 commit comments

Comments
 (0)