Changed ScopingRule to deal with scala scopes

After discussion with @Lewix, we realized we had no mechanism to deal with scala-style symbol scoping, so the ScopingRule base-type now provides symbol scoping functionalities.

I also extended the optimizer macro with ClassDef and ModuleDef since some rules were throwing warnings about this.
For example, if users are only interested in ValDef definitions, they could have the following case in their step function:
```scala
case v: ValDef =>
   // ... do something with v
  enterScope()
```
which will provide scoping only inside blocks on the right-hand side of value definitions. I don't really see when this would be useful, but you never know. This way we maintain flexibility for now, just in case.