Scalameta Semester Project
Documentation/Website: https://scalameta.org/
Repository: https://github.com/scalameta/scalameta
Getting Started with Scalameta
$ git clone https://github.com/scalameta/scalameta.git
The project is built using sbt
.
$ sbt
> scalametaJVM/compile
> testsJVM/test
Writting and running your first test
Create a new .scala
file in tests/shared/src/test/scala/scala/meta/tests/
. Here is a template
you can copy-paste:
package org.scalameta.tests
import org.scalatest._
import scala.meta._
class MyTest extends FunSuite {
test("my first test") {
val program = "class Foo"
println(program.parse[Source].get)
}
}
You can then run your test with sbt
:
> testsJVM/testOnly org.scalameta.tests.MyTest
console
Experimenting with the > scalametaJVM/console
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_172).
Type in expressions for evaluation. Or try :help.
scala> import scala.meta._
import scala.meta._
Parsing, AST, Tokens...
scala> val program = "class Foo"
program: String = class Foo
scala> val tree = program.parse[Source].get
tree: scala.meta.Source = class Foo
scala> val tokens = tree.tokens
tokens: scala.meta.tokens.Tokens = Tokens(, class, , Foo, )
Sources:
Getting Started with Dotty
Documentation/Website: http://dotty.epfl.ch/
Repository: https://github.com/lampepfl/dotty
Getting started with sbt
:
$ sbt new lampepfl/dotty.g8
$ sbt
sbt:dotty-example-project> console
scala> enum Foo { case Bar }
// defined class Foo
Dotty Enums
Useful links:
- Documentation:
- Pull Requests:
Support for Dotty Enums in Scalameta
Open issue: scalameta/scalameta#901
TODO list:
Week 1:
- Be familiar with Scalameta and its concepts (e.g. Trees, Tokens, Parser). Read the Tree Guide.
- Be familiar with the Scalameta codebase (e.g.
sbt
, compile, test). - Be familiar with Dotty Enums. In particular their syntax.
- Think about a tree representation for enums. Some thoughts are already in the Scalameta issue. However, this was before the simplification.
Week 2:
- Implement and test the parser for the "Case".
Week 3:
- Implement and test the parser for the "Enum"
- Find why the LF token is consumed after a case
- Modify to permit case parsing only in an enum
Week 4:
- Make changes to match the structure decided with @olafurpg
DONE:
Week 1:
- Read scalameta files that are interesting for the project
- Using AST explorer and code, understand how the AST is built
- Read the TreeGuide
- Study the Dotty syntax for Enum to compare with Class syntax
- Have a first idea of what need to be changed :
- In the method that begins at the line 2872 of scalametaParser:
def tmplDef(mods: List[Mod]): Member with Stat
adding a case for the token *KwEnum*, with a structure like the *KwClass* case
- In Trees.scala
@ast class Enum(mods: List[Mod],
name: scala.meta.Type.Name,
tparams: List[scala.meta.Type.Param],
ctor: Ctor.Primary,
templ: Template) extends Defn with Member.Type
for the Enum Case :
@ast class Case(mods : List[Mod],
name : scala.meta.Type.Name,
tparams : List[scala.meta.Type.Param],
ctor : Option[Ctor.Primary) extends Defn with Member.Type]
Week 2:
- add trait EnumCase extends Defn with Member.Type
- add the Defn.Case and Defn.SimpleCases classes in Defn object
- Defn.Case parses the case with constructor or only one case
- Defn.SimpleCases parses case of this form : case Foo, Bar
- add a case KwCase if ahead token is not object or class in funDefOrDclOrSecondaryCtor method
- add and implement the method that parses the case :
def caseDef(mods : List[Mod]) : Stat with Member.Type
- add a condition in the trait DefIntro (line 520 of ScalametaParser) as this the KwCase is recognize as a Definition intro
Week 3:
- add the Defn.Enum class
@ast class Enum(mods : List[Mod], name: scala.meta.Type.Name, tparams: List[scala.meta.Type.Param], ctor: Ctor.Primary, templ: Template) extends Defn with Member.Type
- add the case KwEnum() to the method tmplDef
case KwEnum() => enumDef(mods)
- add the KwEnum as a template intro in TemplateIntro
- Add the enumDef method that parses enum
def enumDef(mods: List[Mod]) : Defn.Enum = atPos(mods, auto){...}
- Try to implement a similar solution as the Dotty parser to avoid case being parsed outside an enum's body (using a var)
- But after the meeting with @olafurpg, some changes will be done in the code written until now
Week 4:
- Transform everything done before to match the structure that we discussed with @olafurpg.
- Found the problem with \n during parsing case
Week 5:
- Start to transform the tokenIterator to be a real iterator to let the parser give information to the iterator for fetching the next token. That will solve the problem of the removed end of line when parsing a case. To achieve this, I will change the SimpleTokenIterator class to fetch the next token only when next is called.
Week 6:
- Finish the SimpleTokenIterator class and open the pull request.
- Add the adjustSepRegions in TokenIterator trait (to see if it is the right solution).
- Put everything together.
- Begin to write some tests.