Skip to content

Commit

Permalink
Merged branch idea243.release into idea243.x
Browse files Browse the repository at this point in the history
  • Loading branch information
builduser committed Jan 21, 2025
2 parents 12d7b09 + 9b224b3 commit 5aaf057
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ object GivenType extends InfixType {
AnnotType(isPattern = false)

override protected def errorMessage: String = ScalaBundle.message("type.expected")

override protected def `allow 'as' operator`: Boolean = true
}

object OldGivenDef {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import org.jetbrains.plugins.scala.lang.parser.parsing.builder.ScalaPsiBuilder
*/

object CompoundType extends Type {
override protected def infixType: InfixType = InfixType

override def apply(star: Boolean, isPattern: Boolean, typeVariables: Boolean)(implicit builder: ScalaPsiBuilder): Boolean = {
override def apply(star: Boolean, isPattern: Boolean, typeVariables: Boolean, inContextBound: Boolean)(implicit builder: ScalaPsiBuilder): Boolean = {
val compoundMarker = builder.mark()
builder.getTokenType match {
case ScalaTokenTypes.tLBRACE if !builder.isScala3 =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object ContextBounds {
object ContextBound {
def apply()(implicit builder: ScalaPsiBuilder): Boolean = {
val contextBoundMarker = builder.mark()
if (!Type()) {
if (!Type(inContextBound = true)) {
contextBoundMarker.rollbackTo()
false
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ object InfixType extends InfixType {
(implicit builder: ScalaPsiBuilder): Boolean =
CompoundType(star, isPattern)
override protected def errorMessage: String = ScalaBundle.message("compound.type.expected")

override protected def `allow 'as' operator`: Boolean = true
}

trait InfixType {
Expand All @@ -26,15 +28,21 @@ trait InfixType {
@Nls
protected def errorMessage: String

protected def `allow 'as' operator`: Boolean

private val varargStarFollowSet = TokenSet.create(
ScalaTokenTypes.tRPARENTHESIS, // def test(x: Int*) -- standard case
ScalaTokenTypes.tASSIGN, // def test(x: Int* = 3) -- this is allowed by syntax, but not by semantics
ScalaTokenTypes.tCOMMA, // def test(x: Int*,) -- especially with trailing comma
)

final def apply(star: Boolean = false, isPattern: Boolean = false, typeVariables: Boolean = false)(implicit builder: ScalaPsiBuilder): Boolean = {
final def apply(star: Boolean = false,
isPattern: Boolean = false,
typeVariables: Boolean = false,
inContextBound: Boolean = false)
(implicit builder: ScalaPsiBuilder): Boolean = {
if (builder.isScala3) {
return parseInScala3(star, isPattern, typeVariables)(builder)
return parseInScala3(star, isPattern, typeVariables, inContextBound)(builder)
}

var markerList = List.empty[PsiBuilder.Marker] //This list consist of markers for right-associated op
Expand Down Expand Up @@ -141,7 +149,10 @@ trait InfixType {
}
}

private def parseInScala3(star: Boolean, isPattern: Boolean, typeVariables: Boolean)(implicit builder: ScalaPsiBuilder): Boolean = {
private def parseInScala3(star: Boolean,
isPattern: Boolean,
typeVariables: Boolean,
inContextBound: Boolean)(implicit builder: ScalaPsiBuilder): Boolean = {
val infixParsingRule = new PrecedenceClimbingInfixParsingRule {
override protected def referenceElementType: IElementType = ScalaElementType.REFERENCE
override protected def infixElementType: IElementType = ScalaElementType.INFIX_TYPE
Expand All @@ -164,7 +175,7 @@ trait InfixType {
(!isPattern ||
typeVariables ||
builder.getTokenText != "|") &&
!(builder.features.`new context bounds and givens` && builder.getTokenText == "as") &&
!(inContextBound && builder.features.`new context bounds and givens` && builder.getTokenText == "as") &&
super.shouldContinue

private def parseTypeVariable(): Boolean = if (isPattern && typeVariables && builder.getTokenType == ScalaTokenTypes.tIDENTIFIER) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.jetbrains.plugins.scala.lang.parser.util.InScala3
* | [[DepFunParams]] '=>' [[Type]]
*/
object InfixTypePrefix {
def apply(star: Boolean, isPattern: Boolean, typeVariables: Boolean)(implicit builder: ScalaPsiBuilder): Boolean = {
def apply(star: Boolean, isPattern: Boolean, typeVariables: Boolean, inContextBound: Boolean)(implicit builder: ScalaPsiBuilder): Boolean = {
val marker = builder.mark()

val rollbackMarker = builder.mark()
Expand Down Expand Up @@ -42,7 +42,7 @@ object InfixTypePrefix {
builder.advanceLexer() // 'given'
} else givenMarker.drop()

if (InfixType(star, isPattern, typeVariables)) {
if (InfixType(star, isPattern, typeVariables, inContextBound)) {
if (isImplicitFunctionType) {
if (builder.getTokenType == ScalaTokenTypes.tRPARENTHESIS)
builder.advanceLexer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import org.jetbrains.plugins.scala.lang.parser.parsing.types.Type.parseWildcardS
* }}}
*/
object Type extends Type {
override protected def infixType: InfixType = InfixType

// TODO: handle changes for later Dotty versions https://dotty.epfl.ch/docs/reference/changed-features/wildcards.html
// In Scala 3.0, both _ and ? are legal names for wildcards.
// In Scala 3.1, _ is deprecated in favor of ? as a name for a wildcard. A -rewrite option is available to rewrite one to the other.
Expand All @@ -37,12 +35,14 @@ object Type extends Type {
}

trait Type {
protected def infixType: InfixType

def apply(star: Boolean = false, isPattern: Boolean = false, typeVariables: Boolean = false)(implicit builder: ScalaPsiBuilder): Boolean = {
def apply(star: Boolean = false,
isPattern: Boolean = false,
typeVariables: Boolean = false,
inContextBound: Boolean = false)
(implicit builder: ScalaPsiBuilder): Boolean = {
val typeMarker = builder.mark()

if (InfixTypePrefix(star, isPattern, typeVariables)) {
if (InfixTypePrefix(star, isPattern, typeVariables, inContextBound)) {
typeMarker.drop()
true
} else if (PolyFunOrTypeLambda(star, isPattern)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2859,4 +2859,122 @@ class GivenNewSyntaxParserTest extends SimpleScala3ParserTestBase {
| PsiWhiteSpace('\n')
|""".stripMargin
)

// SCL-23314
def testInfixAs(): Unit = checkTree(
"""
|val conv: (String as Int) = ???
|given instance: (String as Int) = ???
|def test(ev: (String as Int)) = ???
|""".stripMargin,
"""
|ScalaFile
| PsiWhiteSpace('\n')
| ScPatternDefinition: conv
| AnnotationsList
| <empty list>
| Modifiers
| <empty list>
| PsiElement(val)('val')
| PsiWhiteSpace(' ')
| ListOfPatterns
| ReferencePattern: conv
| PsiElement(identifier)('conv')
| PsiElement(:)(':')
| PsiWhiteSpace(' ')
| TypeInParenthesis: (String as Int)
| PsiElement(()('(')
| InfixType: String as Int
| SimpleType: String
| CodeReferenceElement: String
| PsiElement(identifier)('String')
| PsiWhiteSpace(' ')
| CodeReferenceElement: as
| PsiElement(identifier)('as')
| PsiWhiteSpace(' ')
| SimpleType: Int
| CodeReferenceElement: Int
| PsiElement(identifier)('Int')
| PsiElement())(')')
| PsiWhiteSpace(' ')
| PsiElement(=)('=')
| PsiWhiteSpace(' ')
| ReferenceExpression: ???
| PsiElement(identifier)('???')
| PsiWhiteSpace('\n')
| ScGivenAliasDefinition: instance
| AnnotationsList
| <empty list>
| Modifiers
| <empty list>
| PsiElement(given)('given')
| PsiWhiteSpace(' ')
| PsiElement(identifier)('instance')
| PsiElement(:)(':')
| Parameters
| <empty list>
| PsiWhiteSpace(' ')
| TypeInParenthesis: (String as Int)
| PsiElement(()('(')
| InfixType: String as Int
| SimpleType: String
| CodeReferenceElement: String
| PsiElement(identifier)('String')
| PsiWhiteSpace(' ')
| CodeReferenceElement: as
| PsiElement(identifier)('as')
| PsiWhiteSpace(' ')
| SimpleType: Int
| CodeReferenceElement: Int
| PsiElement(identifier)('Int')
| PsiElement())(')')
| PsiWhiteSpace(' ')
| PsiElement(=)('=')
| PsiWhiteSpace(' ')
| ReferenceExpression: ???
| PsiElement(identifier)('???')
| PsiWhiteSpace('\n')
| ScFunctionDefinition: test
| AnnotationsList
| <empty list>
| Modifiers
| <empty list>
| PsiElement(def)('def')
| PsiWhiteSpace(' ')
| PsiElement(identifier)('test')
| Parameters
| ParametersClause
| PsiElement(()('(')
| Parameter: ev
| AnnotationsList
| <empty list>
| Modifiers
| <empty list>
| PsiElement(identifier)('ev')
| PsiElement(:)(':')
| PsiWhiteSpace(' ')
| ParameterType
| TypeInParenthesis: (String as Int)
| PsiElement(()('(')
| InfixType: String as Int
| SimpleType: String
| CodeReferenceElement: String
| PsiElement(identifier)('String')
| PsiWhiteSpace(' ')
| CodeReferenceElement: as
| PsiElement(identifier)('as')
| PsiWhiteSpace(' ')
| SimpleType: Int
| CodeReferenceElement: Int
| PsiElement(identifier)('Int')
| PsiElement())(')')
| PsiElement())(')')
| PsiWhiteSpace(' ')
| PsiElement(=)('=')
| PsiWhiteSpace(' ')
| ReferenceExpression: ???
| PsiElement(identifier)('???')
| PsiWhiteSpace('\n')
|""".stripMargin
)
}

0 comments on commit 5aaf057

Please sign in to comment.