| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It’s almost 1am, so I’m only scratching the surface, mechanistically
applying the renames that I’ve written down in my notebook:
* typeSignature => info
* declarations => decls
* nme/tpnme => termNames/typeNames
* paramss => paramLists
* allOverriddenSymbols => overrides
Some explanation is in order so that I don’t get crucified :)
1) No information loss happens when abbreviating `typeSignature` and `declarations`.
We already have contractions in a number of our public APIs (e.g. `typeParams`),
and I think it’s fine to shorten words as long as people can understand
the shortened versions without a background in scalac.
2) I agree with Simon that `nme` and `tpnme` are cryptic. I think it would
be thoughtful of us to provide newcomers with better names. To offset
the increase in mouthfulness, I’ve moved `MethodSymbol.isConstructor`
to `Symbol.isConstructor`, which covers the most popular use case for nme’s.
3) I also agree that putting `paramss` is a lot to ask of our users.
The double-“s” convention is very neat, but let’s admit that it’s just
weird for the newcomers. I think `paramLists` is a good compromise here.
4) `allOverriddenSymbols` is my personal complaint. I think it’s a mouthful
and a shorter name would be a much better fit for the public API.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Reflection API exhibits a tension inherent to experimental things:
on the one hand we want it to grow into a beautiful and robust API,
but on the other hand we have to deal with immaturity of underlying mechanisms
by providing not very pretty solutions to enable important use cases.
In Scala 2.10, which was our first stab at reflection API, we didn't
have a systematic approach to dealing with this tension, sometimes exposing
too much of internals (e.g. Symbol.deSkolemize) and sometimes exposing
too little (e.g. there's still no facility to change owners, to do typing
transformations, etc). This resulted in certain confusion with some internal
APIs living among public ones, scaring the newcomers, and some internal APIs
only available via casting, which requires intimate knowledge of the
compiler and breaks compatibility guarantees.
This led to creation of the `internal` API module for the reflection API,
which provides advanced APIs necessary for macros that push boundaries
of the state of the art, clearly demarcating them from the more or less
straightforward rest and providing compatibility guarantees on par with
the rest of the reflection API.
This commit does break source compatibility with reflection API in 2.10,
but the next commit is going to introduce a strategy of dealing with that.
|
|
|
|
|
|
|
|
|
|
| |
Performs the following renamings:
* scala.reflect.macros.BlackboxContext to scala.reflect.macros.blackbox.Context
* scala.reflect.macros.BlackboxMacro to scala.reflect.macros.blackbox.Macro
* scala.reflect.macros.WhiteboxContext to scala.reflect.macros.whitebox.Context
* scala.reflect.macros.WhiteboxMacro to scala.reflect.macros.whitebox.Macro
https://groups.google.com/forum/#!topic/scala-internals/MX40-dM28rk
|
|
|
|
|
| |
This method has always been slightly bothering me, so I was really glad
when Denys asked me to rename it. Let’s see how it pans out.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is the first commit in the series. This commit only:
1) Splits Context into BlackboxContext and WhiteboxContext
2) Splits Macro into BlackboxMacro and WhiteboxMacro
3) Introduces the isBundle property in the macro impl binding
Here we just teach the compiler that macros can now be blackbox and whitebox,
without actually imposing any restrictions on blackbox macros. These
restrictions will come in subsequent commits.
For description and documentation of the blackbox/whitebox separation
see the official macro guide at the scaladoc website:
http://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html
Some infrastructure work to make evolving macros easier:
compile partest-extras with quick so they can use latest library/reflect/...
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
1) Free symbols no longer carry signatures in their constructors.
Previously to reify a free symbol (i.e. to generate a ValDef that creates it)
one had to reify sym.info first. However reification of sym.info might lead to
unexpected side effects, including stack overflows, if reification of sym.info
recursively required reifying sym itself.
Now it's not a problem. First we reify a "header" of a free symbol
by emitting something like:
val free$Foo1 = build.newFreeTerm("Foo", Foo.this, NoFlags)`
Afterwards, when doing code generation for the reification symbol table, we
populate free symbols by inserting calls to `build.setTypeSignature($sym.info)`
This techniques transforms recursion into memoized iteration, because even if
reifying sym.info indirectly requires reification of sym itself, we remember
that we already reified sym and simply return things like Ident(free$Foo1).
2) Unfortunately I haven't been able to get rid of recursion completely.
Since some symbols (e.g. local classes) aren't pickled, we need to recreate
them during reification (this is necessary e.g. to reify RefinedTypes).
Reifier uses a special function, named `reifySymDef`, for that purpose.
Here's an example of how it works:
val symdef$_1 = build.newNestedSymbol(free$U1, newTypeName("_"),
NoPosition, DEFERRED | PARAM, false);
`reifySymDef` expands into a call to `newNestedSymbol`, which requires an owner
This essentially turns `reifySymDef` into a recursion of `reifySymDef` calls,
so that the entire owner chain get reified.
This is an implementation strategy that was employed in the first revision
of the reifier written by Martin, and personally I have no clue whether it's
really necessary to reify the parents. I leave this as a future work.
3) When working with free symbols, it's necessary to attach free symbols
to their reification. This is required in obscure nested reification scenarios,
when a symbol that was free for an inner reifee is no longer free for an outer
reifee. In that case we need to remove that free symbol from the symbol table
of the inner reification.
Back then we didn't have tree attachments, so I had to introduce a phantom
"value" parameter for `newFreeType` to keep track of the original symbols for
free types. Now when we have attachments, this is no longer necessary and
allowed me to clean up the code.
|
|
|
|
| |
Removes the stubs left out to appease the old starr, fixes macro tests.
|
| |
|
|
|
|
|
| |
* introduces ArrayTag and ErasureTag
* all type tags now feature erasure
|
| |
|
|
Implements SIP 16: Self-cleaning macros: http://bit.ly/wjjXTZ
Features:
* Macro defs
* Reification
* Type tags
* Manifests aliased to type tags
* Extended reflection API
* Several hundred tests
* 1111 changed files
Not yet implemented:
* Reification of refined types
* Expr.value splicing
* Named and default macro expansions
* Intricacies of interaction between macros and implicits
* Emission of debug information for macros (compliant with JSR-45)
Dedicated to Yuri Alekseyevich Gagarin
|