summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Merge pull request #4429 from ruippeixotog/issue/8552Adriaan Moors2015-04-221-2/+37
|\ | | | | SI-8627 Two-argument indexOf does not work for Iterator
| * SI-8627 Two-argument indexOf does not work for IteratorRui Gonçalves2015-04-041-2/+37
| | | | | | | | Adds two new methods to `Iterator`, overloading `indexOf` and `indexWhere` with a two-arg version whose second argument indicates the index where to start the search. These methods were already present in instances of `GenSeqLike` but not on iterators, leading to strange behavior when two arguments were passed to `indexOf`.
* | Merge commit '555f8f0' into merge/2.11-to-2.12-apr-21Lukas Rytz2015-04-2116-220/+397
|\ \
| * | Make lambda body public rather than using static accessorJason Zaugg2015-04-172-101/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Under -Ydelambdafy:method (the basis of the upcoming "indylambda" translation for -target:jvm-1.8), an anonymous function is currently encoded as: 1. a private method containing the lambda's code 2. a public, static accessor method that allows access to 1 from other classes, namely: 3. an anonymous class capturing free variables and implementing the suitable FunctionN interface. In our prototypes of indylambda, we do away with 3, instead deferring creating of this class to JDK8's LambdaMetafactory by way of an invokedynamic instruction at the point of lambda capture. This facility can use a private method as the lambda target; access is mediated by the runtime-provided instance of `java.lang.invoke.MethodHandles.Lookup` that confers the privelages of the lambda capture call site to the generated implementation class. Indeed, The java compiler uses this to emit private lambda body methods. However, there are two Scala specific factors that make this a little troublesome. First, Scala's optimizer may want to inline the lambda capture call site into a new enclosing class. In general, this isn't a safe optimization, as `invokedynamic` instructions have call-site specific semantics. But we will rely the ability to inline like this in order to eliminate closures altogether where possible. Second, to support lambda deserialization, the Java compiler creates a synthetic method `$dersializeLamda$` in each class that captures them, just to be able to get the suitable access to spin up an anoymous class with access to the private method. It only needs to do this for functional interfaces that extends Serializable, which is the exception rather than the rule. But in Scala, *every* function must support serialization, so blindly copying the Java approach will lead to some code bloat. I have prototyped a hybrid approach to these challenges: use the private method directly where it is allowed, but fall back to using the accessor method in a generic lambda deserializer or in call sites that have been inlined into a new enclosing class. However, the most straight forward approach is to simply emit the lambda bodies as public (with an mangled name and with the SYHTNETIC flag) and use them in all cases. That is what is done in this commit. This does moves us one step backwards from the goals of SI-7085, but it doesn't seem sensible to incur the inconvenience from locking down one small part of our house when we don't have a plan or the budget to complete that job. The REPL has some fancy logic to decompile the bodys of lambdas (`:javap -fun C#m`) which needed tweaking to accomodate this change. I haven't tried to make this backwards compatible with the old encoding as `-Ydelambdafy:method` is still experimental.
| * | Merge pull request #4451 from som-snytt/issue/3368-remediateAdriaan Moors2015-04-162-5/+4
| |\ \ | | | | | | | | SI-3368 Default to coalescing for 2.11
| | * | SI-3368 Default to coalescing for 2.11Som Snytt2015-04-162-5/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Preserve current behavior (no PCData nodes, only Text) for 2.11. The coalescing flag is on if enabled or if source level is not 2.12 and no flag was supplied. The subtle change is that adjacent Text nodes are thereby coalesced. This happens in the presence of CData sections, but this is at the discretion of the parser anyway. Also, no PCData nodes are emitted under coalescing, even if there were no sibling text nodes. That is the correct behavior: the general idea is that coalescing mode says, I only want to deal with text.
| * | | SI-9273 Avoid unpositioned error for bare classOfJason Zaugg2015-04-151-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A bare identifier `classOf` in a position wth an expected type of `Class[_]` was leading to an unpositioned error. This is due to special treatment of bare `classOf` in `typedIdent` creating an ephemeral, but unpositioned, `TypeTree`. This commit positions that tree and tests that the error is issued at a sensible position. There is still an irregularity between `classOf` and `Predef.classOf`, but that seems esoteric enough to leave alone for now.
| * | | Merge pull request #4367 from retronym/topic/indylambda-specializationAdriaan Moors2015-04-131-1/+17
| |\ \ \ | | |/ / | |/| | Disable -Ydelambdafy:method for specialized FunctionN
| | * | Disable -Ydelambdafy:method for specialized FunctionNJason Zaugg2015-04-101-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Delambdafy phase generates its `FunctionN` subclasses after the specialization phase. As such, `((x: Int) => x).apply(42)` incurs boxing. This commit falls back to the `-Ydelambdafy:inline` in this case. This is done by running the specialization type map over the type of the function, and seeing if anything changes. To make this work robustly, we first need to ensure that the specialization info transformer has processed all the function types. This is not a fundamental limitation; we could in principle generate the specialized code. A followup change will use `-Ydelambdafy:method` as the basis for invokedymnamic lambdas. As part of that stream of work, we will synthesize specialization-aware lambdas, and remove the fallback to `-Ydelambdafy:inline`. I have updated some tests that intend to test the delambdafy transform to avoid use of specialized function types.
| * | | Merge pull request #4431 from adriaanm/rebase-4379Adriaan Moors2015-04-133-41/+165
| |\ \ \ | | | | | | | | | | Patmat: efficient reasoning about mutual exclusion
| | * | | Patmat: efficient reasoning about mutual exclusionGerard Basler2015-04-063-41/+165
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Faster analysis of wide (but relatively flat) class hierarchies by using a more efficient encoding of mutual exclusion. The old CNF encoding for mutually exclusive symbols of a domain added a quadratic number of clauses to the formula to satisfy. E.g. if a domain has the symbols `a`, `b` and `c` then the clauses ``` !a \/ !b /\ !a \/ !c /\ !b \/ !c ``` were added. The first line prevents that `a` and `b` are both true at the same time, etc. There's a simple, more efficient encoding that can be used instead: consider a comparator circuit in hardware, that checks that out of `n` signals, at most 1 is true. Such a circuit can be built in the form of a sequential counter and thus requires only 3n-4 additional clauses [1]. A comprehensible comparison of different encodings can be found in [2]. [1]: http://www.carstensinz.de/papers/CP-2005.pdf [2]: http://www.wv.inf.tu-dresden.de/Publications/2013/report-13-04.pdf
| * | | | Merge pull request #4373 from retronym/topic/indylambda-permutations-2Lukas Rytz2015-04-102-3/+12
| |\ \ \ \ | | | | | | | | | | | | SI-8359 Adjust parameter order of accessor method in Delambdafy
| | * | | | SI-8359 Adjust parameter order of accessor method in DelambdafyJason Zaugg2015-03-242-3/+12
| | | |/ / | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Under `-Ydelambdafy:method`, a public, static accessor method is created to expose the private method containing the body of the lambda. Currently this accessor method has its parameters in the same order structure as those of the lambda body method. What is this order? There are three categories of parameters: 1. lambda parameters 2. captured parameters (added by lambdalift) 3. self parameters (added to lambda bodies that end up in trait impl classes by mixin, and added unconditionally to the static accessor method.) These are currently emitted in order #3, #1, #2. Here are examples of the current behaviour: BEFORE (trait): ``` % cat sandbox/test.scala && scalac-hash v2.11.5 -Ydelambdafy:method sandbox/test.scala && javap -private -classpath . 'Test$class' trait Member; class Capture; trait LambdaParam trait Test { def member: Member def foo { val local = new Capture (arg: LambdaParam) => "" + arg + member + local } } Compiled from "test.scala" public abstract class Test$class { public static void foo(Test); private static final java.lang.String $anonfun$1(Test, LambdaParam, Capture); public static void $init$(Test); public static final java.lang.String accessor$1(Test, LambdaParam, Capture); } ``` BEFORE (class): ``` % cat sandbox/test.scala && scalac-hash v2.11.5 -Ydelambdafy:method sandbox/test.scala && javap -private -classpath . Test trait Member; class Capture; trait LambdaParam abstract class Test { def member: Member def foo { val local = new Capture (arg: LambdaParam) => "" + arg + member + local } } Compiled from "test.scala" public abstract class Test { public abstract Member member(); public void foo(); private final java.lang.String $anonfun$1(LambdaParam, Capture); public Test(); public static final java.lang.String accessor$1(Test, LambdaParam, Capture); } ``` Contrasting the class case with Java: ``` % cat sandbox/Test.java && javac -d . sandbox/Test.java && javap -private -classpath . Test public abstract class Test { public static class Member {}; public static class Capture {}; public static class LambaParam {}; public static interface I { public abstract Object c(LambaParam arg); } public abstract Member member(); public void test() { Capture local = new Capture(); I i1 = (LambaParam arg) -> "" + member() + local; } } Compiled from "Test.java" public abstract class Test { public Test(); public abstract Test$Member member(); public void test(); private java.lang.Object lambda$test$0(Test$Capture, Test$LambaParam); } ``` We can see that in Java 8 lambda parameters come after captures. If we want to use Java's LambdaMetafactory to spin up our anoymous FunctionN subclasses on the fly, our ordering must change. I can see three options for change: 1. Adjust `LambdaLift` to always prepend captured parameters, rather than appending them. I think we could leave `Mixin` as it is, it already prepends the self parameter. This would result a parameter ordering, in terms of the list above: #3, #2, #1. 2. More conservatively, do this just for methods known to hold lambda bodies. This might avoid needlessly breaking code that has come to depend on our binary encoding. 3. Adjust the parameters of the accessor method only. The body of this method can permute params before calling the lambda body method. This commit implements option #2. In also prototyped #1, and found it worked so long as I limited it to non-constructors, to sidestep the need to make corresponding changes elsewhere in the compiler to avoid the crasher shown in the enclosed test case, which was minimized from a bootstrap failure from an earlier a version of this patch. We would need to defer option #1 to 2.12 in any case, as some of these lifted methods are publicied by the optimizer, and we must leave the signatures alone to comply with MiMa. I've included a test that shows this in all in action. However, that is currently disabled, as we don't have a partest category for tests that require Java 8.
| * | | | Merge pull request #4306 from som-snytt/issue/3368-bAdriaan Moors2015-04-094-57/+130
| |\ \ \ \ | | | | | | | | | | | | SI-3368 CDATA gets a Node
| | * | | | SI-3368 ReviewSom Snytt2015-04-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | Verbose option help and test tweak.
| | * | | | SI-3368 Promote xml option to -XxmlSom Snytt2015-04-083-14/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As long as Scala does XML literals, there is probably parsing behavior worth configuring. Therefore, the umbrella option is promoted to `-Xxml`. It was tempting to make it `-XML`, but we resisted.
| | * | | | SI-3368 CDATA gets a NodeSom Snytt2015-04-084-57/+130
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | XML Parser uses `scala.xml.PCData`. A compiler flag `-Yxml:coalescing`, analogous to `DocumentBuilderFactory.setCoalescing`, turns `PCData` nodes into `Text` nodes and coalesces sibling text nodes. This change also fixes parse errors such as rejecting a sequence of CDATA sections. A sequence of "top level" nodes are not coalesced. ``` scala> <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a> res0: scala.xml.Elem = <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a> scala> :replay -Yxml:coalescing Replaying: <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a> res0: scala.xml.Elem = <a><b/>starthi &amp; bye<c/>world<d/>stuffred &amp; black</a> ```
| * | | | | Merge pull request #4403 from gourlaysama/wip/t9239-generic-signatureAdriaan Moors2015-04-091-4/+6
| |\ \ \ \ \ | | | | | | | | | | | | | | SI-9239 fix java generic signature when traits extend classes
| | * | | | | SI-9239 fix java generic signature when traits extend classesAntoine Gourlay2015-03-251-4/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Given the following code: class C1[T] trait T1[T] extends C1[T] class C2[T] extends T1[T] The generic signature of C2 changed after ced3ca8 from "C1[T], T1[T]" to "Object, T1[T]", even though C1 was still marked as a superclass in the bytecode... C1 was removed because a subclass (T1) appeared later on, and it was possible for a trait to cause a class to be evicted. It turns out that if a class A appears in "parents", it *always* has to stay in the signature: if a trait later in the list inherits from some class, that class has to be a superclass of A (per SLS §5.1), or A itself, so in any case, the most specific superclass is A, so A should stay in the signature. Thus minimizeParents now only allows traits/interfaces to be removed from the list (the refactoring in 7552739, moving from mixinClasses to parents, makes this much easier to fix). This didn't happen for non-generic signatures because there are two separate fields in the classfile for this (one for the superclass, one for interfaces), so interfaces were processed on their own. Thus non-parametrized classes were not affected. Anything that used erased types at runtime was also fine (like isInstanceOf checks), and anything that used ScalaSignature was also unaffected. Maybethat's why so few things broke... See the test for how this affects Java (hint: badly). This changes very few things when building scala itself, and the changes seem sensible: --- sandbox/lib/scala-library.jar#!scala/runtime/NonLocalReturnControl.class +++ build/pack/lib/scala-library.jar#!scala/runtime/NonLocalReturnControl.class - Generic Signature: <T:Ljava/lang/Object;>Ljava/lang/Object;Lscala/util/control/ControlThrowable; + Generic Signature: <T:Ljava/lang/Object;>Ljava/lang/Throwable;Lscala/util/control/ControlThrowable; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/QueueProxy$$anon$1.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/QueueProxy$$anon$1.class - Generic Signature: Ljava/lang/Object;Lscala/collection/mutable/QueueProxy<TA;>; + Generic Signature: Lscala/collection/mutable/Queue<TA;>;Lscala/collection/mutable/QueueProxy<TA;>; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/Iterable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/Iterable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory<Lscala/collection/mutable/Iterable;>; + Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/mutable/Iterable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/mutable/Iterable;>; --- sandbox/lib/scala-library.jar#!scala/collection/immutable/Traversable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/immutable/Traversable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory<Lscala/collection/immutable/Traversable;>; + Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/immutable/Traversable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/immutable/Traversable;>; --- sandbox/lib/scala-library.jar#!scala/collection/immutable/Iterable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/immutable/Iterable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory<Lscala/collection/immutable/Iterable;>; + Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/immutable/Iterable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/immutable/Iterable;>; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/Traversable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/Traversable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory<Lscala/collection/mutable/Traversable;>; + Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/mutable/Traversable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/mutable/Traversable;>; --- sandbox/lib/scala-library.jar#!scala/throws.class +++ build/pack/lib/scala-library.jar#!scala/throws.class - Generic Signature: <T:Ljava/lang/Throwable;>Ljava/lang/Object;Lscala/annotation/StaticAnnotation; + Generic Signature: <T:Ljava/lang/Throwable;>Lscala/annotation/Annotation;Lscala/annotation/StaticAnnotation; --- sandbox/lib/scala-library.jar#!scala/collection/mutable/StackProxy$$anon$1.class +++ build/pack/lib/scala-library.jar#!scala/collection/mutable/StackProxy$$anon$1.class - Generic Signature: Ljava/lang/Object;Lscala/collection/mutable/StackProxy<TA;>; + Generic Signature: Lscala/collection/mutable/Stack<TA;>;Lscala/collection/mutable/StackProxy<TA;>; --- sandbox/lib/scala-library.jar#!scala/collection/convert/Wrappers$IterableWrapper.class +++ build/pack/lib/scala-library.jar#!scala/collection/convert/Wrappers$IterableWrapper.class - Generic Signature: <A:Ljava/lang/Object;>Ljava/lang/Object;Lscala/collection/convert/Wrappers$IterableWrapperTrait<TA;>;Lscala/Product;Lscala/Serializable; + Generic Signature: <A:Ljava/lang/Object;>Ljava/util/AbstractCollection<TA;>;Lscala/collection/convert/Wrappers$IterableWrapperTrait<TA;>;Lscala/Product;Lscala/Serializable; --- sandbox/lib/scala-library.jar#!scala/collection/Iterable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/Iterable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory<Lscala/collection/Iterable;>; + Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/Iterable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/Iterable;>; --- sandbox/lib/scala-library.jar#!scala/collection/Traversable$.class +++ build/pack/lib/scala-library.jar#!scala/collection/Traversable$.class - Generic Signature: Ljava/lang/Object;Lscala/collection/generic/TraversableFactory<Lscala/collection/Traversable;>; + Generic Signature: Lscala/collection/generic/GenTraversableFactory<Lscala/collection/Traversable;>;Lscala/collection/generic/TraversableFactory<Lscala/collection/Traversable;>; --- sandbox/lib/scala-library.jar#!scala/collection/parallel/AdaptiveWorkStealingForkJoinTasks$WrappedTask.class +++ build/pack/lib/scala-library.jar#!scala/collection/parallel/AdaptiveWorkStealingForkJoinTasks$WrappedTask.class - Generic Signature: <R:Ljava/lang/Object;Tp:Ljava/lang/Object;>Ljava/lang/Object;Lscala/collection/parallel/ForkJoinTasks$WrappedTask<TR;TTp;>;Lscala/collection/parallel/AdaptiveWorkStealingTasks$WrappedTask<TR;TTp;>; + Generic Signature: <R:Ljava/lang/Object;Tp:Ljava/lang/Object;>Lscala/concurrent/forkjoin/RecursiveAction;Lscala/collection/parallel/ForkJoinTasks$WrappedTask<TR;TTp;>;Lscala/collection/parallel/AdaptiveWorkStealingTasks$WrappedTask<TR;TTp;>;
| * | | | | | Merge pull request #4386 from retronym/ticket/7741Lukas Rytz2015-04-092-9/+15
| |\ \ \ \ \ \ | | | | | | | | | | | | | | | | SI-7741: Be more tolerant of absent inner classfiles and non-Scala interface members
| | * | | | | | SI-7741 Tread more lightly during classfile parsingJason Zaugg2015-03-252-9/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1. Avoid forcing info of non-Scala interface members This avoids parsing the ostensibly malformed class definitions that correspond to a Groovy lambda defined in an interface. 2. Be more tolerant of absent inner classfiles Taking a leaf out of javac's book (see transcript below), we can use stub symbols for InnerClass entries that don't have corresponding class files on the compilation classpath. This will limit failures to code that directly refers to the inner class, rather than any code that simply refers to the enclosing class. It seems that groovyc has a habit of emitting incongrous bytecode in this regard. But this change seems generally useful. ``` % cat sandbox/{Test,Client}.java public class Test { public class Inner {} } public class Client { public Test.Inner x() { return null; } } % javac -d . sandbox/Test.java && javac -classpath . sandbox/Client.java % javac -d . sandbox/Test.java && rm 'Test$Inner.class' && javac -classpath . sandbox/Client.java sandbox/Client.java:2: error: cannot access Inner public Test.Inner x() { return null; } ^ class file for Test$Inner not found 1 error % cat sandbox/{Test,Client}.java public class Test { public class Inner {} } public class Client { public Test.NeverExisted x() { return null; } } % javac -classpath . sandbox/Client.java sandbox/Client.java:2: error: cannot find symbol public Test.NeverExisted x() { return null; } ^ symbol: class NeverExisted location: class Test 1 error % cat sandbox/{Test,Client}.java public class Test { public class Inner {} } public class Client { public Test x() { return null; } } topic/groovy-interop ~/code/scala2 javac -d . sandbox/Test.java && rm 'Test$Inner.class' && javac -classpath . sandbox/Client.java # allowed ```
| * | | | | | | Merge pull request #4428 from kzys/7601-img-alt-211Lukas Rytz2015-04-092-17/+36
| |\ \ \ \ \ \ \ | | | | | | | | | | | | | | | | | | [nomerge] SI-7601 Scaladoc: img elements must have an "alt" attribute
| | * | | | | | | [nomerge] SI-7601 Scaladoc: img elements must have an "alt" attributeKato Kazuyoshi2015-04-022-17/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change makes Scaladoc's HTML valid a bit. Backport of #4407 to 2.11.x
* | | | | | | | | Merge commit 'fedbfd7' into merge/2.11-to-2.12-apr-21Lukas Rytz2015-04-2121-208/+393
|\| | | | | | | |
| * | | | | | | | Merge pull request #4427 from gourlaysama/wip/t5795-scaladoc-empty-paramsLukas Rytz2015-04-092-15/+20
| |\ \ \ \ \ \ \ \ | | | | | | | | | | | | | | | | | | | | SI-5795 empty scaladoc tags should be omitted from output
| | * | | | | | | | SI-5795 empty scaladoc tags should be omitted from outputAntoine Gourlay2015-04-021-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Empty scaladoc tags, like `@param`, `@return`, `@version`, etc. should be omitted from the output when they have no meaning by themselves. They are still parsed, for validation (warning that a tag doesn't exist and so on), but are removed, if empty, when building the Comment. The only ones that stay even when empty are `@deprecated`, so that the class name can be striked-through ("Deprecated" also appears in the header, even if there is no message with it), and `@throws`.
| | * | | | | | | | fix scaladoc issue with parsing of empty tagsAntoine Gourlay2015-04-021-7/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Consider the following code: /** * @see * @deprecated */ object Foo The comment parser properly parsed the body of the 'see' tag as empty, but not the one of 'deprecated': it supposedly contains a single character, a newline '\n', which is wrong. This always happened to the last tag in the list; it is always appended a new line (whether empty or not), which breaks formatting (and things later on that test if a body is empty of not).
| | * | | | | | | | fix Scaladoc html display when there are empty tagsAntoine Gourlay2015-04-021-0/+2
| | |/ / / / / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Empty scaladoc tags used to completely break the HTML layout of classes and methods. See the difference between before [1] and after [2]. [1]: http://static.gourlaysama.net/img/scaladoc_t5795_before.png [2]: http://static.gourlaysama.net/img/scaladoc_t5795_after.png
| * | | | | | | | Merge pull request #4411 from xeno-by/ticket/9252Lukas Rytz2015-04-091-5/+1
| |\ \ \ \ \ \ \ \ | | | | | | | | | | | | | | | | | | | | SI-9252 gets rid of custom logic for jArrayClass in runtime reflection
| | * | | | | | | | SI-9252 gets rid of custom logic for jArrayClass in runtime reflectionEugene Burmako2015-03-271-5/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Apparently, I've already fixed a very similar issue two years ago. That was a fun surprise! (https://issues.scala-lang.org/browse/SI-5680)
| * | | | | | | | | Merge pull request #4439 from esfand-r/error-message-improvementJason Zaugg2015-04-091-1/+1
| |\ \ \ \ \ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | Error message improvement
| | * | | | | | | | | Error message improvementesfandiar amirrahimi2015-04-081-1/+1
| | | |_|_|_|/ / / / | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | 'may be not be' -> 'may not be'
| * | | | | | | | | Merge pull request #4438 from retronym/topic/plugin-api-regressionAdriaan Moors2015-04-081-2/+4
| |\ \ \ \ \ \ \ \ \ | | |/ / / / / / / / | |/| | | | | | | | Fix regression in plugin API
| | * | | | | | | | Fix regression in plugin APIJason Zaugg2015-04-081-2/+4
| | | |_|_|_|_|/ / | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Removing a call to a deprecated method had the effect of rendering plugins that override that method inoperable. This manifest as a failure to build scala-js in the community build: https://github.com/scala/community-builds/issues/95 Partially reverts d4546fd.
| * | | | | | | | grammar it's -> itsGeoffrey Knauth2015-04-071-1/+1
| | | | | | | | |
| * | | | | | | | Merge pull request #4332 from Ichoran/opt-TravOnce-2.11.xGrzegorz Kossakowski2015-04-071-2/+15
| |\ \ \ \ \ \ \ \ | | | | | | | | | | | | | | | | | | | | Performance improvement: collectFirst in TraversableOnce
| | * | | | | | | | Performance improvement: collectFirst in TraversableOnceRex Kerr2015-03-301-2/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | collectFirst was implemented in TraversableOnce by calling toIterator and then using a non-local return to pull out a Some when the partial function succeeded. This had two problems: 1. If the TraversableOnce was Iterator or Iterable, stepping through until pf is happy is much (15x!) faster. 2. If the TraversableOnce was not, creating an Iterator is a waste of time and memory This fixes both of these issues by inspecting the self-type and choosing the appropriate implementation. Further (modest) improvements likely possible in 2.12 by moving specialized implementations to child classes and using `applyOrElse` on the partial function with a package-private object instead of a locally created one.
| * | | | | | | | | Merge pull request #4413 from lrytz/opt/inliningEverythingLukas Rytz2015-04-0710-115/+204
| |\ \ \ \ \ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | Fixes and Improvements for the new inliner
| | * | | | | | | | | SI-9139 don't inline across @strictfp modesLukas Rytz2015-04-013-1/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Cannot inline if one of the methods is @strictfp, but not the other.
| | * | | | | | | | | Don't inlinie if the resulting method becomes too large for the JVMLukas Rytz2015-04-013-3/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This threshold is really the last resort and should never be reached. An inlining heuristic that blows up methods to the maximum size allowed by the JVM is broken. In the future we need to include some heuristic about code size when making an inlining decision, see github.com/scala-opt/scala/issues/2
| | * | | | | | | | | Don't force the GenASM backend when passing -optimizeLukas Rytz2015-04-012-7/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This behavior is confusing and also problematic for writing partest tests: CI passes -optimize, which negates the -Ybackend:GenBCode entry in a flags file.
| | * | | | | | | | | Apply local variable index shift when inlining iinc instructionLukas Rytz2015-04-011-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | That was an oversight. Scalac never emits iinc, but it can appear when inlining from the classpath.
| | * | | | | | | | | Clean up the way compiler settings are accessed in the backend.Lukas Rytz2015-04-018-68/+58
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Many backend components don't have access to the compiler instance holding the settings. Before this change, individual settings required in these parts of the backend were made available as members of trait BTypes, implemented in the subclass BTypesFromSymbols (which has access to global). This change exposes a single value of type ScalaSettings in the super trait BTypes, which gives access to all compiler settings.
| | * | | | | | | | | Don't try to inline native methodsLukas Rytz2015-04-012-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Because you can't, really.
| | * | | | | | | | | Eliminate unreachable code before inlining a methodLukas Rytz2015-04-016-44/+81
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Running an ASM analyzer returns null frames for unreachable instructions in the analyzed method. The inliner (and other components of the optimizer) require unreachable code to be eliminated to avoid null frames. Before this change, unreachable code was eliminated before building the call graph, but not again before inlining: the inliner assumed that methods in the call graph have no unreachable code. This invariant can break when inlining a method. Example: def f = throw e def g = f; println() When building the call graph, both f and g contain no unreachable code. After inlining f, the println() call becomes unreachable. This breaks the inliner's assumption if it tries to inline a call to g. This change intruduces a cache to remember methods that have no unreachable code. This allows invoking DCE every time no dead code is required, and bail out fast. This also simplifies following the control flow in the optimizer (call DCE whenever no dead code is required).
| | * | | | | | | | | Command-line flag to control inlining heuristicsLukas Rytz2015-03-314-2/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduces a stress-test mode "everything" in which the inliner tries to inline every calliste that can be statically resolved.
| | * | | | | | | | | Make class Invalid a ControlThrowableLukas Rytz2015-03-311-1/+2
| | |/ / / / / / / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Invalid is used for control flow in RightBiasedEither.orThrow.
| * | / / / / / / / SI-9264 An even-better diagnostic for an unexplained crashJason Zaugg2015-04-071-1/+6
| | |/ / / / / / / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We have seen an intermittent crasher in the backend for the last month or so. In https://github.com/scala/scala/pull/4397, I added a diagnostic to show the actual locals in scope in the method. This commit further expands the diagnistic to show the method's tree.
| * | | | | | | | Merge pull request #4370 from gbasler/ticket/SI-9181Adriaan Moors2015-04-063-66/+141
| |\ \ \ \ \ \ \ \ | | |_|_|/ / / / / | |/| | | | | | | SI-9181 Exhaustivity checking does not scale (regression)
| | * | | | | | | Bring back improvements from `SI-6942` that were lost during the switch toGerard Basler2015-03-021-8/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Tseitin's transformation, e.g., use `CNF(P1 /\ ... /\ PN) == CNF(P1) ++ CNF(...) ++ CNF(PN)` in order to simplify the resultung formula.