| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
As suggested in review:
- Use `abort` rather than `{error; EmptyTree} when we hit an
error in reification or tag materialization.
- Explicitly avoid adding the `MacroExpansionAttachment` to the
macro expansion if it an `EmptyTree`
- Emit a `-Xdev` warning if any other code paths find a way to
mutate attachments in places they shouldn't.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit a02e053a5dec134f7c7dc53a2c1091039218237d.
That commit lead to an error compiling Specs2:
[info] [warn] /localhome/jenkinsdbuild/workspace/Community-2.11.x-retronym/dbuild-0.7.1-M1/target-0.7.1-M1/project-builds/specs2-aaa8091b47a34817ca90134ace8b09a9e0f854e9/core/src/test/scala/org/specs2/text/EditDistanceSpec.scala:6: Unused import
[info] [warn] import DiffShortener._
[info] [warn] ^
[info] [error] /localhome/jenkinsdbuild/workspace/Community-2.11.x-retronym/dbuild-0.7.1-M1/target-0.7.1-M1/project-builds/specs2-aaa8091b47a34817ca90134ace8b09a9e0f854e9/core/src/test/scala/org/specs2/text/LinesContentDifferenceSpec.scala:7: exception during macro expansion:
[info] [error] java.lang.UnsupportedOperationException: Position.point on NoPosition
[info] [error] at scala.reflect.internal.util.Position.fail(Position.scala:53)
[info] [error] at scala.reflect.internal.util.UndefinedPosition.point(Position.scala:131)
[info] [error] at scala.reflect.internal.util.UndefinedPosition.point(Position.scala:126)
[info] [error] at org.specs2.reflect.Macros$.sourceOf(Macros.scala:25)
[info] [error] at org.specs2.reflect.Macros$.stringExpr(Macros.scala:19)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When producing an initial spec for macros two years ago, we sort of glossed
over named/default arguments in macro applications, leaving them for future work.
Once the aforementioned future has come, I’ve made several attempts at
making things operational (e.g. last summer), but it’s always been unclear
how to marry the quite complex desugaring that tryNamesDefaults performs
with the expectations of macro programmers to see unsugared trees
in macro impl parameters.
Here’s the list of problems that arise when trying to encode named/default
arguments of macro applications:
1) When inside macro impls we don’t really care about synthetic vals
that are typically introduced to preserve evaluation order in non-positional
method applications. When we inline those synthetics, we lose information
about evaluation order, which is something that we wouldn’t like to lose
in the general case.
2) More importantly, it’s also not very exciting to see invocations of
default getters that stand for unspecified default arguments. Ideally,
we would like to provide macro programmers with right-hand sides of those
default getters, but that is: a) impossible in the current implementation
of default parameters, b) would anyway bring scoping problems that we’re
not ready to deal with just yet.
Being constantly unhappy with potential solutions to the aforementioned
problems, I’ve been unable to nail this down until the last weekend,
when I realized that: 1) even though we can’t express potential twists in
evaluation order within linearly ordered macro impl params, we can use
c.macroApplication to store all the named arguments we want, 2) even though
we can’t get exactly what we want for default arguments, we can represent
them with EmptyTree’s, which is not ideal, but pretty workable. That’s
what has been put into life in this commit.
As a pleasant side-effect, now the macro engine doesn’t have to reinvent
the wheel wrt reporting errors about insufficient arg or arglist count.
Since this logic is intertwined with the tryNamesDefaults desugaring,
we previously couldn’t make use of it and had to roll our own logic
that checked that the number of arguments and parameters of macro applications
correspond to each other. Now it’s all deduplicated and consistent.
|
|
|
|
| |
Use `hasAttachment` rather than `getAttachment.exists`
|
|
|
|
|
|
|
|
|
|
| |
In Jan 2013, I submitted a number of pull requests that built up a foundation
for the upcoming type macros pull request. Unfortunately, type macros
ended up being rejected, but the extra generality introduced in advance
still persisted in the compiler until now.
This commit takes care of unused generality in the macro engine,
keeping the internal implementation as well as the public API clean.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The presentation compiler is primarily interested in trees that
represent the code that one sees in the IDE, not the expansion of
macros.
This commit continues to expand macros, but adds a hook in which
the presentation compiler discards the expansion, retaining instead
the expandee. The expandee is attributed with the type of the
expansion, which allows white box macros to work. In addition,
any domain specific errors and warnings issued by the macro will
still be reported, as a side-effect of the expansion.
The failing test from the last commit now correctly resolves
hyperlinks in macro arguments.
Related IDE ticket:
https://www.assembla.com/spaces/scala-ide/tickets/1001449#
This facility is configured as follows:
// expand macros as per normal
-Ymacro-expand:normal
// don't expand the macro, takes the place of -Ymacro-no-expand
-Ymacro-expand:none
// expand macros to compute type and emit warnings,
// but retain expandee. Set automatically be the presentation
// compiler
-Ymacro-expand:discard
This leaves to door ajar for a new option:
// Don't expand blackbox macros; expand whitebox
// but retain expandee
-Ymacro-expand:discard-whitebox-only
The existing test for SI-6812 has been duplicated. One copy exercises
the now-deprecated -Ymacro-no-expand, and the other uses the new
option.
|
|
|
|
|
|
|
|
|
|
|
| |
Since mkInvoke, the applyDynamic/selectDynamic/etc desugarer, is disconnected
from typedNamedApply, the applyDynamicNamed argument rewriter, the latter
doesn’t know whether it needs to apply the rewriting because the application
has just been desugared or it needs to hold on because it’s already performed
a desugaring on this tree.
This commit introduces the attachment that links these translation facilities,
preventing infinite applyDynamicNamed desugarings.
|
|
|
|
|
|
|
|
|
| |
Interplay between the insertApply desugaring and the invokeDynamic desugarings
is already quite brittle, but the real fun begins when macros crash the party.
The proposed patch enriches the `isDesugaredApply` check performed in
`mkInvoke`, the invokeDynamic desugarer, and makes sure that everything
is safe and sound in the macroland.
|
|
|
|
|
|
|
| |
Most of this was revealed via -Xlint with a flag which assumes
closed world. I can't see how to check the assumes-closed-world
code in without it being an ordeal. I'll leave it in a branch in
case anyone wants to finish the long slog to the merge.
|
|
|
|
| |
This reverts commit 71fb0b83a, which itself reverted the fix for SI-6812.
|
|
|
|
|
| |
Following typedMacroBody, macroRuntime along with its friends has also
been moved out into a separate component.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Upgrades the way that macro defs are compiled by factoring out most of
the logic in typedMacroBody and related errors in ContextErrors into an
standalone cake. This leads to tighter cohesion and better code reuse
as the cake is isolated from the rest of the compiler and is much easier
to evolve than just a method body.
Increased convenience of coding macro compilation allowed me to further
clarify the implementation of the macro engine (e.g. take a look at
Validators.scala) and to easily implement additional features, namely:
1) Parameters and return type of macro implementations can now be plain
c.Tree's instead of previously mandatory c.Expr's. This makes macros more
lightweight as there are a lot of situations when one doesn't need to
splice macro params (the only motivation to use exprs over trees). Also
as we're on the verge of having quasiquotes in trunk, there soon will be
no reason to use exprs at all, since quasiquotes can splice everything.
2) Macro implementations can now be defined in bundles, standalone cakes
built around a macro context: http://docs.scala-lang.org/overviews/macros/bundles.html.
This further reduces boilerplate by simplifying implementations complex
macros due to the fact that macro programmers no longer need to play
path-dependent games to use helpers.
|
|
|
|
|
|
|
|
|
| |
Changes macroExpand to accommodate expansion schemes different from the
currently supported one.
As a bonus, which follows clarification of the macro expansion logic,
this refactoring fixes suppression of macro expansions, which
previously didn't work with delayed expansion.
|
|
|
|
|
| |
Applies a minor renaming that I failed to thoroughly perform
in the last pull request which refactored parent types.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Similarly to global.emptyValDef, which is a dummy that stands for an
empty self-type, this commit introduces global.pendingSuperCall, which
stands for a yet-to-be-filled-in call to a superclass constructor.
pendingSuperCall is emitted by Parsers.template, treated specially by
Typers.typedParentType and replaced with a real superclass ctor call
by Typers.typedTemplate.
To avoid copy/paste, this commit also factors out and unifies dumminess
of EmptyTree, emptyValDef and pendingSuperCall - they all don't have a
position and actively refuse to gain one, same story for tpe.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
At the moment parser does too much w.r.t handling of parent types.
It checks whether a parent can have value arguments or not and
more importantly, it synthesizes constructors and super calls.
This approach is fundamentally incompatible with upcoming type macros.
Take for example the following two snippets of code:
`class C extends A(2)`
`class D extends A(2) with B(3)`
In the first snippet, `A` might be a type macro, therefore the super call
`A.super(2)` eagerly emitted by the parser might be meaningless. In the
second snippet parser will report an error despite that `B` might be
a type macro which expands into a trait.
Unfortunately we cannot simply augment the parser with the `isTypeMacro`
check. This is because to find out whether an identifier refers to a type
macro, one needs to perform a typecheck, which the parser cannot do.
Therefore we need a deep change in how parent types and constructors
are processed by the compiler, which is implemented in this commit.
|
|
|
|
|
|
|
|
|
| |
Builds a starr that uses stuff from scala.reflect.macros for macro activities.
Crucial makro thingies (such as makro.Context or makro.internal.macroImpl)
are temporarily left in place, because they are necessary for previous starr.
Macro tests will be fixed in a dedicated commit, so that they don't pollute
meaningful commits, making the life easy for reviewers and spelunkers.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before reflection refactoring, macro contexts only exposed a mirror.
Now it's time to expose both a universe (the compiler instance) and
a mirror (a macro-specific symbol resolver).
By the way, speaking of mirrors. Macro contexts have their own mirror,
which is different from compiler's rootMirror. This is done because
macros need to be able to resolve stuff from empty package.
Reflection refactoring brought major changes to runtime evaluation,
which got dropped from universes and now requires scala-compiler.jar.
However there are macro users, who would like to do eval inside macros.
To help them we expose `libraryClassLoader` to manually build toolboxes,
and also a simple-to-use `c.eval` method.
I've also sneakily introduced `c.parse`, because it's something that
has also been frequently requested. Moreover, it might help Scaladoc.
So I decided that it might be worth it to add this new functionality.
|
|
|
|
|
|
|
|
|
| |
As a result, hardwired macros don't need implementation stubs.
This is very important, because in a few commits scala.reflect.makro.Context
will move out from scala-library.jar.
Also adding fast track entries doesn't require jumping through hoops
with PDTs. It's as simple as defining PartialFunction[Tree, Any].
|
|
|