Skip to content

Commit 0d460cb

Browse files
committed
Implement case class and case object
1 parent 4a68508 commit 0d460cb

File tree

4 files changed

+112
-66
lines changed

4 files changed

+112
-66
lines changed

semanticdb/input/src/main/scala/example/Case.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ class CaseTest {
66
case y @ Some(x) => x
77
case None => 0
88
}
9-
}
9+
}
10+
11+
case class CaseClass(x: Int)
12+
case object CaseObject

semanticdb/input/src/main/scala/example/Classes.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package example
2-
/*
2+
33
class C1(val x1: Int) extends AnyVal
44

5-
class C2(val x2: Int) extends AnyVal
6-
object C2
5+
//class C2(val x2: Int) extends AnyVal
6+
/*object C2
77
88
case class C3(x: Int)
99
@@ -13,9 +13,9 @@ object C4
1313
object M {
1414
implicit class C5(x: Int)
1515
}
16-
*/
16+
1717
case class C6(private val x: Int)
18-
/*
18+
1919
class C7(x: Int)
2020
2121
class C8(private[this] val x: Int)

semanticdb/src/dotty/semanticdb/SemanticdbConsumer.scala

Lines changed: 100 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
9595
case _ => false
9696
}
9797

98-
def isDefaultGetter: Boolean = symbol.name.contains(tpnme.DEFAULT_GETTER.toString)
98+
def isDefaultGetter: Boolean =
99+
symbol.name.contains(tpnme.DEFAULT_GETTER.toString)
99100

100101
def isParameter: Boolean = symbol.flags.is(Flags.Param)
101102

@@ -388,12 +389,12 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
388389
)
389390
}
390391

391-
val reserverdFunctions: List[String] = "apply" :: "unapply" :: Nil
392+
val reservedFunctions: List[String] = "apply" :: "unapply" :: Nil
392393
def addOccurenceTree(tree: Tree,
393394
type_symbol: s.SymbolOccurrence.Role,
394395
range: s.Range,
395396
force_add: Boolean = false): Unit = {
396-
if (type_symbol != s.SymbolOccurrence.Role.DEFINITION && reserverdFunctions
397+
if (type_symbol != s.SymbolOccurrence.Role.DEFINITION && reservedFunctions
397398
.contains(tree.symbol.name))
398399
return
399400
if (tree.isUserCreated || (force_add && !(!tree.isUserCreated && iterateParent(
@@ -566,68 +567,109 @@ class SemanticdbConsumer(sourceFile: java.nio.file.Path) extends TastyConsumer {
566567
super.traverseTree(tree)
567568
}
568569
case ClassDef(classname, constr, parents, selfopt, statements) => {
569-
// we first add the class to the symbol list
570-
addOccurenceTree(tree,
571-
s.SymbolOccurrence.Role.DEFINITION,
572-
range(tree, tree.symbol.pos, tree.symbol.name))
573-
//println("constr symbol pos: ", constr.symbol.pos.startColumn, constr.symbol.pos.endColumn)
574-
//println("constr pos: ", constr.pos.startColumn, constr.pos.endColumn)
575-
// then the constructor
576-
if (!constr.isUserCreated) {
577-
fittedInitClassRange = Some(
578-
s.Range(tree.symbol.pos.startLine,
579-
tree.symbol.pos.startColumn + classname.length + 1,
580-
tree.symbol.pos.startLine,
581-
tree.symbol.pos.startColumn + classname.length + 1))
570+
println("\n")
571+
val resolvedClassSymbol = tree.symbol.asClass.companionClass
572+
val resolvedObjectSymbol = tree.symbol.asClass.companionModule
573+
println(tree.symbol.flags)
574+
if (resolvedClassSymbol != None && resolvedClassSymbol.get.flags.isCase) {
575+
// case class
576+
if (resolvedClassSymbol.get == tree.symbol) {
577+
println("YES")
578+
// we first add the class to the symbol list
579+
addOccurenceTree(tree,
580+
s.SymbolOccurrence.Role.DEFINITION,
581+
range(tree, tree.symbol.pos, tree.symbol.name))
582+
583+
fittedInitClassRange = Some(
584+
s.Range(constr.symbol.pos.startLine,
585+
constr.symbol.pos.startColumn,
586+
constr.symbol.pos.endLine,
587+
constr.symbol.pos.endColumn))
588+
589+
traverseTree(constr)
590+
fittedInitClassRange = None
591+
} else {
592+
println("NO")
593+
}
594+
} else if (tree.symbol.flags.isObject && tree.symbol.flags.isCase) {
595+
println("YES object")
596+
// we first add the class to the symbol list
597+
addOccurenceTree(tree,
598+
s.SymbolOccurrence.Role.DEFINITION,
599+
range(tree, tree.symbol.pos, tree.symbol.name))
600+
601+
fittedInitClassRange = Some(
602+
s.Range(constr.symbol.pos.startLine,
603+
constr.symbol.pos.startColumn,
604+
constr.symbol.pos.endLine,
605+
constr.symbol.pos.endColumn))
606+
607+
traverseTree(constr)
608+
fittedInitClassRange = None
609+
println("NO object")
582610
} else {
583-
fittedInitClassRange = Some(
584-
s.Range(constr.symbol.pos.startLine,
585-
constr.symbol.pos.startColumn,
586-
constr.symbol.pos.endLine,
587-
constr.symbol.pos.endColumn))
588-
}
589-
traverseTree(constr)
590-
fittedInitClassRange = None
591-
592-
// we add the parents to the symbol list
593-
forceAddBecauseParents = true
594-
parents.foreach(_ match {
595-
case IsTypeTree(t) => traverseTypeTree(t)
596-
case IsTerm(t) => {
597-
traverseTree(t)
611+
// we first add the class to the symbol list
612+
addOccurenceTree(tree,
613+
s.SymbolOccurrence.Role.DEFINITION,
614+
range(tree, tree.symbol.pos, tree.symbol.name))
615+
//println("constr symbol pos: ", constr.symbol.pos.startColumn, constr.symbol.pos.endColumn)
616+
//println("constr pos: ", constr.pos.startColumn, constr.pos.endColumn)
617+
// then the constructor
618+
if (!constr.isUserCreated) {
619+
fittedInitClassRange = Some(
620+
s.Range(tree.symbol.pos.startLine,
621+
tree.symbol.pos.startColumn + classname.length + 1,
622+
tree.symbol.pos.startLine,
623+
tree.symbol.pos.startColumn + classname.length + 1))
624+
} else {
625+
fittedInitClassRange = Some(
626+
s.Range(constr.symbol.pos.startLine,
627+
constr.symbol.pos.startColumn,
628+
constr.symbol.pos.endLine,
629+
constr.symbol.pos.endColumn))
598630
}
599-
})
600-
forceAddBecauseParents = false
601-
602-
selfopt match {
603-
case Some(vdef @ ValDef(name, _, _)) if name != "_" => {
604-
// To find the current position, we will heuristically
605-
// reparse the source code.
606-
// The process is done in three steps:
607-
// 1) Find a position before the '{' of the self but after any
608-
// non related '{'. Here, it will be the largest end pos of a parent
609-
// 2) Find the first '{'
610-
// 3) Iterate until the character we are seeing is a letter
611-
val startPosSearch: Int = parents.foldLeft(tree.pos.endColumn)(
612-
(old: Int, ct: TermOrTypeTree) =>
631+
traverseTree(constr)
632+
fittedInitClassRange = None
633+
634+
// we add the parents to the symbol list
635+
forceAddBecauseParents = true
636+
parents.foreach(_ match {
637+
case IsTypeTree(t) => traverseTypeTree(t)
638+
case IsTerm(t) => {
639+
traverseTree(t)
640+
}
641+
})
642+
forceAddBecauseParents = false
643+
644+
selfopt match {
645+
case Some(vdef @ ValDef(name, _, _)) if name != "_" => {
646+
// To find the current position, we will heuristically
647+
// reparse the source code.
648+
// The process is done in three steps:
649+
// 1) Find a position before the '{' of the self but after any
650+
// non related '{'. Here, it will be the largest end pos of a parent
651+
// 2) Find the first '{'
652+
// 3) Iterate until the character we are seeing is a letter
653+
val startPosSearch: Int = parents.foldLeft(
654+
tree.pos.endColumn)((old: Int, ct: TermOrTypeTree) =>
613655
ct match {
614656
case IsTerm(t) if t.pos.endColumn < old => t.pos.endColumn
615-
case _ => old
657+
case _ => old
616658
})
617-
var posColumn = sourceCode.indexOf("{", startPosSearch)
618-
while (!sourceCode(posColumn).isLetter && posColumn < sourceCode.length) posColumn += 1
619-
620-
addSelfDefinition(name,
621-
s.Range(vdef.pos.startLine,
622-
posColumn,
623-
vdef.pos.endLine,
624-
posColumn + name.length))
659+
var posColumn = sourceCode.indexOf("{", startPosSearch)
660+
while (!sourceCode(posColumn).isLetter && posColumn < sourceCode.length) posColumn += 1
661+
662+
addSelfDefinition(name,
663+
s.Range(vdef.pos.startLine,
664+
posColumn,
665+
vdef.pos.endLine,
666+
posColumn + name.length))
667+
}
668+
case _ =>
625669
}
626-
case _ =>
627-
}
628-
selfopt.foreach(traverseTree)
629670

630-
statements.foreach(traverseTree)
671+
statements.foreach(traverseTree)
672+
}
631673
}
632674
case IsDefinition(cdef) => {
633675

semanticdb/test/dotty/semanticdb/Tests.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class Tests {
196196
//def testObjects(): Unit = checkFile("example/Objects.scala")
197197
//@Test def testOverrides(): Unit = checkFile("example/Overrides.scala")
198198
//WIP @Test def testPrefixes(): Unit = checkFile("example/Prefixes.scala")
199-
@Test def testSelfs(): Unit = checkFile("example/Selfs.scala")
199+
//@Test def testSelfs(): Unit = checkFile("example/Selfs.scala")
200200
//@Test def testSelfUse(): Unit = checkFile("example/SelfUse.scala")
201201
//WIP @Test def testSynthetic(): Unit = checkFile("example/Synthetic.scala")
202202
//WIP @Test def testTraits(): Unit = checkFile("example/Traits.scala")
@@ -205,5 +205,6 @@ class Tests {
205205
//@Test def testDependantModule(): Unit = checkFile("example/DependantModule.scala")
206206
//@Test def testNew(): Unit = checkFile("example/New.scala")
207207
//@Test def testIgnoredSymbol(): Unit = checkFile("example/IgnoredSymbol.scala")
208-
//@Test def testCase(): Unit = checkFile("example/Case.scala")
208+
@Test def testCase(): Unit = checkFile("example/Case.scala")
209+
//@Test def testApply(): Unit = checkFile("example/Apply.scala")
209210
}

0 commit comments

Comments
 (0)