| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
| |
Macros don't correspond to bytecode-level methods, therefore
there's no need to undergo any transformations past typer.
|
|
|
|
|
|
|
|
| |
This matter was discussed at scala-internals:
http://groups.google.com/group/scala-internals/browse_thread/thread/6414d200cf31c357
And I am convinced with Paul's argument: consistency of the convention
is very important.
|
|
|
|
|
|
|
|
|
|
|
| |
Entries in SynchronizedTypes.uniques could previously be garbage collected
in-between a successful call to contains and an actual cache lookup.
The patch could be a one-liner, but I don't want to use HOFs
in this function, whose prototype is a hotspot in the compiler.
Also the fix doesn't touch scalac in any way. It only applies to
reflective universes that provide runtime reflection functionality.
|
|\
| |
| | |
a fork of isValueType and isNonValueType
|
| |
| |
| |
| |
| |
| | |
only affects runtime reflection, because Symbol.typeSignature
is only defined in the reflection API. the rest of the compiler
uses Symbol.info instead.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Restrictions regarding how non-value types can be used have
generally not been enforced explicitly, depending instead on
the fact that the compiler wouldn't attempt to use them in
strange ways like offering a method type as a type argument.
Since users can now create most types from scratch, it has
become important to enforce the restrictions in a more
direct fashion.
This was a lot harder than it probably should have been
because there are so many types which go unmentioned by the
specification. Hopefully a useful exercise in any case.
|
| | |
|
|\ \
| | |
| | | |
Removes discrepancy between SIP 15 and compiler
|
| | |
| | |
| | |
| | | |
There was a discrepancy in that the compiler alternatively accepts a val parameter or an unbox method for a value class but SIP 15 does not mention the unbox method. I commented out the line in the compiler that does it.
|
|\ \ \
| |_|/
|/| | |
SI-6380 Add @throws[Exception]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This change allows an additional notation of the @throws annotation:
Old-style: @throws(classOf[Exception])
New-style: @throws[Exception]
The optional String argument moves @throws in line with @deprecated,
@migration, etc. and prevents confusion caused by the default inheritance
of ScalaDoc comments and the non-inheritance of annotations.
Before: /** This method does ...
* @throws IllegalArgumentException if `a` is less than 0. */
@throws(classOf[IllegalArgumentException])
def foo(a: Int) = ...
Now: /** This method does ... */
@throws[IllegalArgumentException]("if `a` is less than 0")
def foo(a: Int) = ...
ScalaDoc @throws tags remain supported for cases where documentation of
thrown exceptions is needed, but are not supposed to be added to the
exception attribute of the class file.
In this commit the necessary compiler support is added.
The code to extract exceptions from annotations is now shared instead
of being duplicated all over the place.
The change is completely source and binary compatible, except that the code
is now enforcing that the type thrown is a subtype of Throwable as mandated
by the JVM spec instead of allowing something like @throws(classOf[String]).
Not in this commit:
- ScalaDoc support to add the String argument to ScalaDoc's exception list
- Adaption of the library
|
|\ \ \
| | | |
| | | | |
Much better unchecked warnings.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
It's not Typer's personal method. All should be able to
drink of its wisdom.
|
| | | | |
|
| | |/
| |/| |
|
|\ \ \
| | | |
| | | | |
SI-5314 - CPS transform of return statement fails (resubmission of #987)
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Add `adaptTypeOfReturn` hook to `AnnotationCheckers`.
Move adaptation of types of return expressions from `addAnnotations`
to `typedReturn` via `adaptTypeOfReturn` hook.
This resolves an inconsistency where previously types could have
a plus marker without additional CPS annotations. This also adds
additional test cases.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
I did this for ReificationError a long time ago. Must've probably forgot
to do the same for ParseError.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
Takes macros.Settings, throws away its mutable parts, moves classPath from Run
back to the top level - and unites all that in the Infrastructure trait.
|
| | | |
| | | |
| | | |
| | | | |
Scaladoc-driven cleanup for the win
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
scala.reflect.api.Mirror is the most basic contract for mirrors.
Currently scala.reflect.api.Universe.Mirror is simply an abstract type
type Mirror >: Null <: scala.reflect.api.Mirror[self.type], and
scala.reflect.macros.Universe doesn't override that type, so from the user
standpoint at the moment scala.reflect.api.Mirror == c.mirror, however,
in the future this might be a source of errors.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
currentRun goes to Enclosures and becomes enclosingRun
currentClassPath gets integrated into Run
|
| | | |
| | | |
| | | |
| | | |
| | | | |
By turning them from abstract types into full-fledged traits
implemented by our internal Run and CompilationUnit.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
It was useful to pretend that SourceFile isn't a part of the API,
when it's physical location was in scala-compiler.jar.
Afterwards Position and SourceFile have been moved to scala-reflect.jar,
and (what's more important) scala-reflect.jar gained experimental status,
meaning that we're not bound by backward compatibility in 2.10.0.
Therefore I'd say we should expose a full-fledged SourceFile in Position.source
(just as we do for Symbol.associatedFile) and later find out how to strip down
its interface to something suitable for public consumption.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
libraryClassLoader can be derived from currentClassPath
currentMacro can be trivially derived from macroApplication
Backend-detection methods forXXX (as in forJVM or forScaladoc)
might be useful, but current design of this API is not future-proof.
I'm not able to come up with a better design on the spot, so
let's remove this functionality for the moment.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Back then we didn't have a notion of a macro-specific universe,
so I had to expose these methods in Context.
Now we have our very own macros.Universe, so capturing methods
have landed there.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
The former is a one-method trait, the latter is a two-method trait.
In a scaladoc these guys don't look like the pull their weight.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
It was an interesting idea to give macro developers control over front ends,
but it hasn't given any visible results.
To the contrast, front ends have proven useful for toolboxes to easily control
what errors get printed where.
Therefore I'm moving front ends to scala-compiler.jar to clean up the API.
Yay for scaladoc-driven development!
|
| | | |
| | | |
| | | |
| | | | |
Continues the series of Scaladoc-driven optimizations to scala-reflect.jar.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This is an internal implementation class, only necessary for reification
(exposes some really internal stuff required to recreate the trees,
the stuff for which the public API is insufficient or too verbose).
Therefore we don't need it in Scaladoc.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
The name looks weird in the scaladoc overview panel,
so I decided to do a last-minute rename.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The only place we use something from scala.reflect.io in the public API
is Symbol.associatedFile, so I've excluded scala.reflect.io from scaladoc
and added a "warning: experimental" comment to associatedFile instead.
I'd argue that this greatly simplifies the surface of reflection API
(typing scala.reflect in the search bar now yields 3 packages instead of 4).
|
|\ \ \ \
| | | | |
| | | | | |
SI-6412 alleviates leaks in toolboxes, attempt #2
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Turns importer caches into fully weak hash maps, and also applies
manual cleanup to toolboxes every time they are used.
It's not enough, because reflection-mem-typecheck test is still leaking
at a rate of ~100kb per typecheck, but it's much better than it was before.
We'll fix the rest later, after 2.10.0-final.
For more information, see https://issues.scala-lang.org/browse/SI-6412 and
http://groups.google.com/group/scala-internals/browse_thread/thread/eabcf3d406dab8b2
In comparison with https://github.com/scala/scala/commit/b403c1d,
the original commit that implemented the fix, this one doesn't crash tests.
The problem with the original commit was that it called tryFixup() before
updating the cache, leading to stack overflows.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Don't call `updateInfo` during typing.
|
| | |_|/ /
| |/| | |
| | | | |
| | | | | |
We resort to `setInfo`, basically removing the previous info. This "fixes" a possible race condition
in typing ModuleDefs by making the typer always 'win'. See the assertion stack trace in SI-6429.
|
| |/ / /
|/| | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
If the parameter types of a method have lower visibility than
the method itself, then the method cannot be overridden because
the parameter types cannot be expressed. This is a confusing
and frustrating situation to expose via public API. Such
methods should either have access as strong as their parameter
types, or be made final.
|
|\ \ \ \
| |/ / /
|/| | | |
SI-6277 fix for isXXX methods in reflection
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
`Symbol.getFlag`, 'Symbol.hasFlag`, `Symbol.hasAllFlags`, `Symbol.annotations`
and `Symbol.privateWithin` now trigger automatic initialization of symbols
if they are used in a runtime reflection universe and some other conditions
are met (see `Symbol.needsInitialize` for details).
As the performance testing in https://github.com/scala/scala/pull/1380 shows,
this commit introduces a ~2% performance regression of compilation speed.
Unfortunately all known solutions to the bug at hand (A, B & C - all of those)
introduce perf regressions (see the pull request linked above for details).
However we're under severe time pressure, so there's no more time to explore.
Therefore I suggest this is reasonable to accept this performance hit,
because we've just gained 6% from removing scala.reflect.base,
and even before that we were well within our performance goal for 2.10.0-final.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
At times it's useful to know whether a lazy type can change
the flags of the underlying symbol or not.
If the completer is flag-agnostic, this means that we can safely
use flag-inspection facilities such as hasFlag and isXXX tests
without fear of looking into not yet initialized data.
|
| | | | |
|
| | | |
| | | |
| | | |
| | | | |
This reverts commit b403c1d7524ccdfc3455b5bc5d5363fdd9c82bec.
|
|\ \ \ \
| | | | |
| | | | | |
SI-6412 some fixes for reflection leaks
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
`mirrorThatLoaded(sym: Symbol): Mirror` in JavaMirrors used to iterate over
`lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]()`
to find out what mirror has loaded a certain symbol.
It worked okay until yesterday when I noticed failing tests, which crashed
when weak references in mirrors were dereferenced with get.get. Apparently
some mirrors were collected, and the logic in JavaMirror didn't account for
that possibility.
When fixing this bug, I noticed that mirrors can become unreachable even
if there are still reachable symbols created by those mirrors. That doesn't
make sense, therefore I fixed this bug as well by introducing a strong ref
from root symbols to the enclosing mirror. Therefore, any active symbol
will have a strong reference to the enclosing mirror by the virtue of the
owner chain.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Turns importer caches into fully weak hash maps, and also applies
manual cleanup to toolboxes every time they are used.
It's not enough, because reflection-mem-typecheck test is still leaking
at a rate of ~100kb per typecheck, but it's much better than it was before.
We'll fix the rest later, after 2.10.0-final.
For more information, see https://issues.scala-lang.org/browse/SI-6412 and
http://groups.google.com/group/scala-internals/browse_thread/thread/eabcf3d406dab8b2
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This is the most blatant leak in reflection. There are others, but their impact
is much smaller, therefore we'll fix them later, after 2.10.0-final.
For more information, see https://issues.scala-lang.org/browse/SI-6412 and
http://groups.google.com/group/scala-internals/browse_thread/thread/eabcf3d406dab8b2
|
|\ \ \ \ \
| |/ / / /
|/| | | | |
Changed implementation comments from /** */ to /* */ for ScalaDoc
|
| | | | |
| | | | |
| | | | |
| | | | | |
reasonable
|
| |/ / /
|/| | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Java enum values are represented with constants wrapping corresponding Symbols.
To find out the underlying type of such a constant one needs to calculate
sym.owner.linkedClassOfClass.tpe (where sym represents the wrapped symbol).
To quote the source code, given (in java): class A { enum E { VAL1 } }
- sym: the symbol of the actual enumeration value (VAL1)
- .owner: the ModuleClassSymbol of the enumeration (object E)
- .linkedClassOfClass: the ClassSymbol of the enumeration (class E)
Back then, as far as I can guess, linkedClassOfClass was flaky and didn't
work well late in the compilation pipeline.
Therefore a fix to SI-1329 introduced a caching facility. Once a ConstantType
representing the type of Constant(sym) was created (I guess, during typer, when
linkedClassOfClass was still working), it cached the underlying type and used
it in subsequent phases.
***
Unfortunately this solution, being fine for enum values, broke another flavor
of constants - type wrapping constants that represent classOf (for example,
Constant(IntTpe) represents the classOf[Int] constant).
Type-wrapping constants are special, because their type (e.g. Class[Int] in the
example from the previous paragraph) changes as the compilation progresses.
Before erasure it's Class[something], and after erasure it's just Class.
Therefore caching types of such constants might lead to incorrect types
flying around after erasure, as described in this scala-internals thread:
http://groups.google.com/group/scala-internals/browse_thread/thread/45185b341aeb6a30.
***
Now when the problem is clear, the question is why didn't it happen before?
That's all because of another peculiarity of the compiler.
Before erasure package references (e.g. in TypeRef prefixes) are represented
as ThisType(sym), where sym stands for a package class symbol. After erasure
such references are represented differently, e.g. java.lang package looks like
TypeRef(TypeRef(TypeRef(NoPrefix, root, Nil), java, Nil), java.lang, Nil).
As described in the aforementioned thread, the incorrect caching strategy
employed in UniqueConstantType mixed with other caching mechanisms in compiler
effectively established a non-clearable cache that goes from Type instances to
types that represent their classOfs, e.g. from String to Class[String].
So if anyone tried to typecheck a classOf after erasure, he/she would get
Class[String] instead of the correct Class, and compiler would crash. Right?
Nope. Before erasure String is TypeRef(ThisType(java.lang), StringSymbol, Nil),
and after erasure it's TypeRef(TypeRef(...), StringSymbol, Nil), as explained
above. Therefore the foul cache would contain two String types: one pre-erasure
going to a pre-erasure Class[String], and another one post-erasure going to
a post-erasure Class.
***
This shaky balance was broken when I tried to implement class tag generation
with shiny Type.erasure method that Martin just exposed in the reflection API.
The erasure method partially invoked the Erasure phase, and for a String
it returned its post-erasure representation (with java.lang prefix represented
as TypeRef, not as ThisType). And after that I used the result of erasure
to build a classOf for a class tag. Since I did it in a macro, it was
typer, a pre-erasure phase.
Now you understand why things broke. That classOf created a Constant
wrapping a post-erasure representation of String, which cached the incorrect
non-erased Class[String] type for a post-erasure type, and things exploded.
You can imagine my panic! The ScalaDays deadline was near, I still had to do
finishing touches to implicit macros (which I actually never had time to do),
and such a fundamental thing exploded.
Actually I figured out the hashing problem, but in the limited time I had
I failed to understand why exactly it's happening, so I introduced the dirty
workaround praised in SI-5918 and moved on.
***
The story doesn't end here.
Some time has passed, and I learned a lot about the compiler. I independently
discovered the ThisType -> TypeRef transform that erasure applies to package
references and patched Type.erasure to undo it. After all, Type.erasure is a
user-facing API, and users don't need to know about post-typer implementation
details. You can read more about this here:
http://groups.google.com/group/scala-internals/browse_thread/thread/6d3277ae21b6d581
From what we've learned above, we can see that this Type.erasure fix made
the UniqueConstantType workaround unnecessary. But I didn't know that.
So imagine my surprise when I tried to remove that workaround and ran the tests
only to see that nothing fails. I went back in time to April when the problem
first manifested, extracted a minimized crasher and tried to use it on trunk.
Again, nothing crashed.
And only with the help of showRaw, I finally understood that types printed as
"String" can be wildly different. The rest was a piece of cake.
***
The irony is that the original reason for ConstantType caching is no longer
valid. linkedClassOfClass now works fine (and files/jvm/outerEnum.scala
agrees with me), so we can remove the cache altogether.
So why all this story about erasure and package references? Well, I don't know.
I enjoyed uncovering this mystery, so I wanted to share it with you :)
|
|\ \ \ \
| | | | |
| | | | | |
Fixes SI-5822 & SI-6305 - OSGi tests + fixes
|