summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/internal/Trees.scala
Commit message (Collapse)AuthorAgeFilesLines
* Avoid tree sharing with substituteThisJason Zaugg2016-05-311-1/+1
| | | | | | | | | | The underlying transformer has a by-name parameter for the to provide the `to` tree, but this was strict in the layers of API above. Tree sharing is frowned upon in general as it leads to cross talk when, e.g., the erasure typechecker mutates the `tpe` field of the shared tree in different context.
* Lower-case spelling of @deprecated messagesSimon Ochsenreither2016-05-281-3/+3
|
* New trait encoding: use default methods, jettison impl classesJason Zaugg2016-03-181-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, concrete methods in traits were encoded with "trait implementation classes". - Such a trait would compile to two class files - the trait interface, a Java interface, and - the implementation class, containing "trait implementation methods" - trait implementation methods are static methods has an explicit self parameter. - some methods don't require addition of an interface method, such as private methods. Calls to these directly call the implementation method - classes that mixin a trait install "trait forwarders", which implement the abstract method in the interface by forwarding to the trait implementation method. The new encoding: - no longer emits trait implementation classes or trait implementation methods. - instead, concrete methods are simply retained in the interface, as JVM 8 default interface methods (the JVM spec changes in [JSR-335](http://download.oracle.com/otndocs/jcp/lambda-0_9_3-fr-eval-spec/index.html) pave the way) - use `invokespecial` to call private or particular super implementations of a method (rather `invokestatic`) - in cases when we `invokespecial` to a method in an indirect ancestor, we add that ancestor redundantly as a direct parent. We are investigating alternatives approaches here. - we still emit trait fowrarders, although we are [investigating](https://github.com/scala/scala-dev/issues/98) ways to only do this when the JVM would be unable to resolve the correct method using its rules for default method resolution. Here's an example: ``` trait T { println("T") def m1 = m2 private def m2 = "m2" } trait U extends T { println("T") override def m1 = super[T].m1 } class C extends U { println("C") def test = m1 } ``` The old and new encodings are displayed and diffed here: https://gist.github.com/retronym/f174d23f859f0e053580 Some notes in the implementation: - No need to filter members from class decls at all in AddInterfaces (although we do have to trigger side effecting info transformers) - We can now emit an EnclosingMethod attribute for classes nested in private trait methods - Created a factory method for an AST shape that is used in a number of places to symbolically bind to a particular super method without needed to specify the qualifier of the `Super` tree (which is too limiting, as it only allows you to refer to direct parents.) - I also found a similar tree shape created in Delambdafy, that is better expressed with an existing tree creation factory method, mkSuperInit.
* Remove unused imports and other minor cleanupsSimon Ochsenreither2015-12-181-1/+1
| | | | | | | | | | - Language imports are preceding other imports - Deleted empty file: InlineErasure - Removed some unused private[parallel] methods in scala/collection/parallel/package.scala This removes hundreds of warnings when compiling with "-Xlint -Ywarn-dead-code -Ywarn-unused -Ywarn-unused-import".
* Also mutate module *class*'s owner in ChangeOwnerTraverserAdriaan Moors2015-11-121-1/+3
| | | | | Keep owner for module (symbol of the tree) and module class (holds the members) in synch while moving trees between owners (e.g., while duplicating them in specialization)
* SI-9498 Avoid caching bug with pattern type variablesJason Zaugg2015-09-301-13/+1
| | | | | | | | | | | | | | | | | | | | | | | | Typechecking a pattern that defines a pattern type variable initially assigns abstract type symbol with open type bounds. Later on, pattern type inference kicks in to sharpen the type of the variable based on constraints imposed by the expected type (ie, the type of scrutinee of the pattern.) However, before inference does this, a `TypeRef` to the abstract type symbol can be queried for its base type with respect to some class, which leads to it populating an internal cache. This cache becomes stale when the underlying symbol has its type mutated. The repercussions of this meant that a subsequent call to `baseType` gave the wrong result (`NoType`), which lead to an `asSeenFrom` operation to miss out of substitution of a type variable. Note the appearance of `A` in the old type errors in the enclosed test case. This commit takes an approach similar to 286dafbd to invalidate caches after the mutation. I've routed both bandaids through the same first aid kit: I'm sure over time we'll add additional calls to this method, and additional cache invalidations within it.
* Merge remote-tracking branch 'origin/2.11.x' into 2.12.xSeth Tisue2015-09-081-2/+2
| | | | | | | | only trivial merge conflicts here. not dealing with PR #4333 in this merge because there is a substantial conflict there -- so that's why I stopped at 63daba33ae99471175e9d7b20792324615f5999b for now
* Removed warningsEECOLOR2015-03-261-1/+1
| | | | | | | | | | | | | | | | | | | | | - Added `since` to deprecation statement - Added unit to parameter list - Removed usage of deprecated method polyType - Replaced deprecated `debugwarn` with `devWarning` - Changed switch statement to if else in order to remove a warning - Switched implementation of `init` and `processOptions` to prevent warning - Replaced deprecated `Console.readLine` with `scala.io.StdIn.readLine` - Replaced deprecated `startOrPoint` with `start` - Replaced deprecated `tpe_=` with `setType` - Replaced deprecated `typeCheck` with `typecheck` - Replaced deprecated `CompilationUnit.warning` with `typer.context.warning` - Replaced deprecated `scala.tools.nsc.util.ScalaClassLoader` with `scala.reflect.internal.util.ScalaClassLoader` - Replaced deprecated `scala.tools.ListOfNil` with `scala.reflect.internal.util.ListOfNil` - Replaced deprecated `scala.tools.utils.ScalaClassLoader` with `scala.reflect.internal.util.ScalaClassLoader` - Replaced deprecated `emptyValDef` with `noSelfType` - In `BoxesRunTime` removed unused method and commented out unused values. Did not delete to keep a reference to the values. If they are deleted people might wonder why `1` and `2` are not used. - Replaced deprecated `scala.tools.nsc.util.AbstractFileClassLoader` with `scala.reflect.internal.util.AbstractFileClassLoader`
* SI-9135 Fix NPE, a regression in the pattern matcherJason Zaugg2015-02-051-1/+1
| | | | | | | | The community build discovered that #4252 introduced the possibility for a NullPointerException. The tree with a null type was a synthetic `Apply(<<matchEnd>>)` created by the pattern matcher. This commit adds a null check.
* SI-9050 Fix crasher with value classes, recursionJason Zaugg2015-01-161-1/+19
| | | | | | | | | | | | | | | | | | | | | | From the "Substitution is hard to do" department. In 7babdab9a, TreeSymSubstitutor was modified to mutate the info of symbols defined in the tree, if that symbol's info referred to one of the `from` symbols in the substitution. It would have been more principled to create a cloned symbol with the updated info, and add that to the substitution. But I wasn't able implement that correctly (let alone efficiently.) The in-place mutation of the info of a symbol led to the crasher in this bug: a singleton type over that symbol ends up with a stale cached value of 'underlying'. In the enclosed test case, this leads to a type error in the `SubstituteRecursion` of the extension methods phase. This commit performs a cleanup job at the end of `substituteSymbols` by invalidating the cache of any `SingleType`-s in the tree that refer to one of the mutated symbols.
* Merge pull request #4083 from retronym/ticket/8947Jason Zaugg2014-11-071-0/+8
|\ | | | | SI-8947 Avoid cross talk between tag materializers and reify
| * SI-8947 Additional layers of defence against EmptyTree mutationJason Zaugg2014-11-061-3/+4
| | | | | | | | | | | | | | | | | | | | | | 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.
| * SI-8947 Avoid cross talk between tag materializers and reifyJason Zaugg2014-10-301-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After a macro has been expanded, the expandee are expansion are bidirectionally linked with tree attachments. Reify uses the back reference to replace the expansion with the expandee in the reified tree. It also has some special cases to replace calls to macros defined in scala-compiler.jar with `Predef.implicitly[XxxTag[T]]`. This logic lives in `Reshape`. However, the expansion of a macro may be `EmptyTree`. This is the case when a tag materializer macro fails. User defined macros could do the also expand to `EmptyTree`. In the enclosed test case, the error message that the tag materializer issued ("cannot materialize class tag for unsplicable type") is not displayed as the typechecker finds another means of making the surrounding expression typecheck. However, the macro engine attaches a backreference to the materializer macro on `EmpytyTree`! Later, when `reify` reshapes a tree, every occurance of `EmptyTree` will be replaced by a call to `implicitly`. This commit expands the domain of `CannotHaveAttrs`, which is mixed in to `EmptyTree`. It silently ignores all attempts to mutate attachments. Unlike similar code that discards mutations of its type and position, I have refrained from issuing a developer warning in this case, as to silence this I would need to go and add a special case at any places adding attachments.
* | SI-8916 Fix -Ywarn-unused-import warningsSimon Ochsenreither2014-10-241-1/+0
|/
* fixes for wrappingIntoTermVladimirNik2014-02-201-1/+0
|
* block wrapping for trees modifiedVladimirNik2014-02-201-5/+7
|
* block processing fixed for syntactics in typechecked treesVladimirNik2014-02-201-1/+2
|
* Merge remote-tracking branch 'origin/master' into topic/palladium0Eugene Burmako2014-02-161-0/+9
|\ | | | | | | | | | | | | | | Conflicts: src/compiler/scala/reflect/macros/compiler/Resolvers.scala src/compiler/scala/reflect/macros/contexts/Typers.scala src/compiler/scala/tools/reflect/ToolBoxFactory.scala src/reflect/scala/reflect/api/BuildUtils.scala
| * typecheck(q"class C") no longer crashesEugene Burmako2014-02-121-0/+9
| | | | | | | | | | | | | | | | | | MemberDefs alone can't be typechecked as is, because namer only names contents of PackageDefs, Templates and Blocks. And, if not named, a tree can't be typed. This commit solves this problem by wrapping typecheckees in a trivial block and then unwrapping the result when it returns back from the typechecker.
* | fixes compat for tree and type extractorsEugene Burmako2014-02-151-55/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When I removed XXXDef(...) and XXXType(...) methods from the public API, I put compatibility stubs in compat via implicit classes enriching XXXExtractor traits with apply methods. Unfortunately, this doesn't work, because if XXXDef or XXXType have any kind of an apply method left in the public API, then implicit classes won't even be considered when resolving calls to XXXDef(...) or XXXType(...). Therefore I had to put those removed methods back and adorn them with an implicit parameter that can only be resolved when "import compat._" is in place. Quite extravagant, yes, but goes along the lines with the design goals of the refactoring, which are: 1) Break source compatibility for users who are using methods that are now moved to internal in order to attract attention. 2) Provide an easy way to fix the breakage by importing compat._, which will pimp back all the missing APIs with deprecation warnings that are going to guide migration.
* | establishes scala.reflect.api#internalEugene Burmako2014-02-141-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* | cleans up Trees a little bitEugene Burmako2014-02-141-0/+7
| | | | | | | | | | Adds some clarifications to docs, introduces personally long-awaited treeCopy.RefTree that lets us deal with RefTrees in a fully uniform fashion.
* | ValOrDefDef.name is now TermNameEugene Burmako2014-02-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Back then when we planned to introduce type macros, we relaxed the type of DefDef.name from TermName to Name in order to potentially be able to accommodate type names for type macros. Since then, type macros have been cancelled (and, for the record, my implementation of type macros in paradise 1.0 didn’t involve DefDefs with TypeNames), and we’ve rolled back the change to DefDef.name. What we forgot to do, however, was to change the type of ValOrDefDef.name, which is taken care of in this commit.
* | SI-8190 erasure identities for types in reflection APIEugene Burmako2014-02-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | Makes sure that almost every abstract type declared in reflection API erases to a unique class, so that they can be adequately used for method overloading to the same extent that tags allow them to be used in pattern matching. The only two exceptions from this rule are the types whose implementations we do not control: FlagSet that is implemented as Long and RuntimeClass that is implemented as java.lang.Class[_].
* | disambiguates uses of “local” in internal symbol APIEugene Burmako2014-02-121-1/+1
|/ | | | | | | | | | | | | | | | | There’s been a conflation of two distinct meanings of the word “local” in the internal symbol API: the first meaning being “local to this” (as in has the LOCAL flag set), the second meaning being “local to block” (as in declared in a block, i.e. having owner being a term symbol). Especially confusing is the fact that sym.isLocal isn’t the same as sym.hasFlag(LOCAL), which has led to now fixed SI-6733. This commit fixes the semantic mess by deprecating both Symbol.isLocal and Symbol.hasLocalFlag (that we were forced to use, because Symbol.isLocal had already been taken), and replacing them with Symbol.isLocalToThis and Symbol.isLocalToBlock. Unfortunately, we can’t remove the deprecated methods right away, because they are used in SBT, so I had to take small steps.
* ExistentialTypeTree.whereClauses are now MemberDefsEugene Burmako2014-01-071-4/+4
| | | | | | | | | | | Today’s flight back to Lausanne wasn’t as productive as the recent flight to Minsk (https://github.com/scala/scala/pull/3305), but I noticed one minor thingie: ExistentialTypeTree had an imprecise type specified for its whereClauses. This is now fixed. I didn’t increment PickleFormat.*Version numbers, because this change introduces only a miniscule incompatibility with what would have been a meaningless and most likely crash-inducing pickle anyway.
* Special treatment for local symbols in TypeTreeMemberTypeJason Zaugg2013-11-231-1/+1
| | | | | | | | Avoids calling `thisType` on the owner if it is a term symbol, which doesn't make much sense. This method is used internally in tree factory methods that create, e.g, a `DefDef` based on the info of a `Symbol`.
* Tidy up the Uncurry component of delambdafyJason Zaugg2013-11-171-0/+6
| | | | | | | | | - Use tree factories that accept symbols and encapsulate ValDef creation - Use `gen.mkForwarder` to handle the conditional addition of `: _*` for varargs functions. We don't need to predicate this on `etaExpandKeepsStar`; the only place that need to do that is EtaExpansion.
* add hasAttachment utility method to the internal apiDen Shabalin2013-11-121-1/+1
|
* Flesh out the Delambdafy phase.James Iry2013-11-061-1/+21
| | | | | | | | | | | | | | | | | | | | | This commit puts a real body on the Delambdafy phase. From a lambda, Delambdafy will create 1) a static forwarder at the top level of the class that contained the lambda 2) a new top level class that a) has fields and a constructor taking the captured environment (including possbily the "this" reference) b) an apply method that calls the static forwarder c) if needed a bridge method for the apply method 3) an instantiation of the newly created class which replaces the lambda Trees.scala is modified to add two more convenient factories for templates and classdefs. A few basic tests are included to verify that it works as expected. Further commits will have additional tests.
* Merge pull request #3033 from paulp/pr/pickler-reduxGrzegorz Kossakowski2013-10-161-72/+101
|\ | | | | Traverser and Pickler improvements.
| * Tree traversal: more uniform and granular.Paul Phillips2013-10-121-72/+101
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There's a huge amount of tree traversal related duplication which is hard to eliminate only because trees aren't properly traversed. The not-quite-tree bits of key trees are ignored during traversals, making it impossible to write e.g. a pretty printer without duplicating almost the entire traversal logic (as indeed is done for printing purposes in more than one place.) And almost the entire pickler logic is redundant with Traverser, except since it's all duplicated of course it diverged. The pickler issue is remedied in the commit to follow. The not-quite-trees not quite being traversed were Modifiers, Name, ImportSelector, and Constant. Now every case field of every tree is traversed, with classes which aren't trees traversed via the following methods, default implementations as shown: def traverseName(name: Name): Unit = () def traverseConstant(c: Constant): Unit = () def traverseImportSelector(sel: ImportSelector): Unit = () def traverseModifiers(mods: Modifiers): Unit = traverseAnnotations(mods.annotations)
* | Aesthetics in Trees.Paul Phillips2013-10-131-52/+52
|/ | | | | | As long as it's a block of pure boilerplate we have to navigate around all the time, it may as well be the most beautiful boilerplate it knows how to be.
* Removing unused code.Paul Phillips2013-10-021-6/+0
| | | | | | | 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.
* Merge pull request #3003 from paulp/pr/position-catchupPaul Phillips2013-10-011-2/+2
|\ | | | | Updating Position call sites.
| * Updating Position call sites.Paul Phillips2013-09-271-2/+2
| | | | | | | | | | | | Calling position factories rather than instantiating these particular classes. Not calling deprecated methods. Added a few position combinator methods.
* | Merge pull request #2991 from xeno-by/topic/unapply-copierEugene Burmako2013-09-301-1/+1
|\ \ | |/ |/| transformers no longer ignore UnApply.fun
| * transformers no longer ignore UnApply.funEugene Burmako2013-09-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Second time's the charm. I remember trying to do exactly the same somewhen around 2.10.0-M4, but then some continuations tests were failing. Luckily, today everything went smoothly. Please note that this fix changes the way that SI-5465 manifests itself. Previously it produced type errors, now it simply crashes the compiler. Therefore I had to attach the try/catch FatalError clause to invocations of toolbox methods, so that compiler crashes get caught and translated to ToolBoxErrors. Also fixes SI-7871, and that clears the way for implementing quasiquotes with conventional macros rather than relying on a special case in typer.
* | SI-6762 rename emptyValDef to noSelfType.Paul Phillips2013-09-271-2/+4
|/ | | | | Looks like emptyValDef.isEmpty was already changed to return false, so now all that's left is a name which means something.
* SI-7853 A less ad-hoc place to call memberTypeJason Zaugg2013-09-181-3/+7
| | | | | | | | | | | | | | | Rather than localizing the fix to the outerAccessor, this commit pushed the call to `memberType` into *all* usages of `newValDef` and `newDefDef`. The TPT of `applyOrElse` in synthetized partial functions must be set explicitly to pass the pos/t7853-partial-function.scala. Otherwise, the as-seen-from ends up cloning the type parameter `B1` of `applyOrElse` as it transforms (questionably) its bound from `List[Int @unchecked]` to `List[Int]`. Partial Function synthesis was already a delicate area, and this makes things more explicit which could be counted as an improvement.
* Merge pull request #2884 from retronym/ticket/3832Jason Zaugg2013-09-151-0/+19
|\ | | | | SI-1909 SI-3832 SI-7007 SI-7223 Improved handling of larval objects
| * SI-3832 Extract tracking of under-construction classes to a mixinJason Zaugg2013-09-111-0/+19
| | | | | | | | In order to reduce the noise in OuterPathTransformer.
* | Reducing variation of tree creation methods.Paul Phillips2013-09-131-51/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | TreeDSL has no future - it was always a temporary measure waiting for something like quasiquotes to come along. In this commit I cull as much of it as I can, especially the delicate matter of creating new DefDefs and ValDefs, which I completely turn over to the old style creators. I unified all the symbol-based DefDef and ValDef creators under a single method, since it was yet another place where ctrl-C and ctrl-V were being punched with glee. Was beaten to the punch on adding copyTypeDef to fill out the *Def creators. Eliminated as many redundant positioning calls as I could find. If you are creating a DefTree tree based on a symbol, it will always have an atPos(sym.pos) { ... } wrapped around it. You don't need another one. All of this is motivated by positions work: positions are assigned in so many places and in such an ad hoc fashion that it is impossible to bring consistency to that without first bringing some consistency to tree creation.
* | Corrects behavior of finalResultType.Paul Phillips2013-09-131-1/+1
|/ | | | | | | | | | | | The implementation had come to depend on finalResultType accidentally doing things beyond its charter - in particular, widening types. After hunting down and fixing the call sites depending on the bugs, I was able to rewrite the method to do only what it's supposed to do. I threw in a different way of writing it entirely to suggest how some correctness might be obtained in the future. It's a lot harder for a method written like this to break.
* add missing copyTypeDef utility functionDen Shabalin2013-09-051-0/+16
|
* Merge branch 'master' into patmatPaul Phillips2013-08-201-2/+2
|\ | | | | | | | | | | Conflicts: src/compiler/scala/tools/nsc/Global.scala src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
| * No longer crash on NoSymbol.owner.Paul Phillips2013-08-191-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Historically calling NoSymbol.owner has crashed the compiler. With this commit, NoSymbol owns itself. This is consistent with the way ownership chains are handled elsewhere in the compiler (e.g. NoContext.owner is NoContext, NoSymbol.enclClass is NoSymbol, and so on) and frees every call site which handles symbols from having to perform precondition tests against NoSymbol. Since calling NoSymbol.owner sometimes (not always) indicates a bug which we'd like to catch sooner than later, I have introduced a couple more methods for selected call sites. def owner: Symbol // NoSymbol.owner is self, log if -Xdev def safeOwner: Symbol // NoSymbol.owner is self, ignore def assertOwner: Symbol // NoSymbol.owner is fatal The idea is that everyone can call sym.owner without undue anxiety or paranoid null-like tests. When compiling under -Xdev calls to `owner` are logged with a stack trace, so any call sites for which that is an expected occurrence should call safeOwner instead to communicate the intention and stay out of the log. Conversely, any call site where crashing on the owner call was a desirable behavior can opt into calling assertOwner. This commit also includes all the safeOwner calls necessary to give us a silent log when compiling scala.
* | Cleanups in Unapplies.Paul Phillips2013-08-171-0/+8
|/
* SI-7731 make CannotHaveAttrs more consistentDen Shabalin2013-08-141-4/+6
| | | | | | | | | | | Previously setPos, pos_=, setType, tpe_= all behaved inconsistently between each other even though they all represent similar attributes that cannot be changed on CannotHaveAttrs trees. In order to simplify handling of such trees in compiler code each of these fields now supports assignment to its current default value: NoType for tpe and NoPosition for pos. Such assignments don't mutate underlying trees.
* DefDef.name is now TermName againEugene Burmako2013-08-101-1/+1
| | | | | Now when there's no hope left for type macros, it's reasonable to provide a more specific type for DefDef.name.