allanrenucci / scalameta-semester-project

Scalameta Semester Project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

Experimenting with the console

> 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:

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:

  1. Read scalameta files that are interesting for the project
  2. Using AST explorer and code, understand how the AST is built
  3. Read the TreeGuide
  4. Study the Dotty syntax for Enum to compare with Class syntax
  5. 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:

  1. add trait EnumCase extends Defn with Member.Type
  2. add the Defn.Case and Defn.SimpleCases classes in Defn object
    1. Defn.Case parses the case with constructor or only one case
    2. Defn.SimpleCases parses case of this form : case Foo, Bar
  3. add a case KwCase if ahead token is not object or class in funDefOrDclOrSecondaryCtor method
  4. add and implement the method that parses the case :
    def caseDef(mods : List[Mod]) : Stat with Member.Type
  5. add a condition in the trait DefIntro (line 520 of ScalametaParser) as this the KwCase is recognize as a Definition intro

Week 3:

  1. 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
  2. add the case KwEnum() to the method tmplDef
    case KwEnum() =>
        enumDef(mods)
  3. add the KwEnum as a template intro in TemplateIntro
  4. Add the enumDef method that parses enum
    def enumDef(mods: List[Mod]) : Defn.Enum = atPos(mods, auto){...}
  5. Try to implement a similar solution as the Dotty parser to avoid case being parsed outside an enum's body (using a var)
  6. But after the meeting with @olafurpg, some changes will be done in the code written until now

Week 4:

  1. Transform everything done before to match the structure that we discussed with @olafurpg.
  2. Found the problem with \n during parsing case

Week 5:

  1. 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:

  1. Finish the SimpleTokenIterator class and open the pull request.
  2. Add the adjustSepRegions in TokenIterator trait (to see if it is the right solution).
  3. Put everything together.
  4. Begin to write some tests.

About

Scalameta Semester Project