Commit Graph

206 Commits

Author SHA1 Message Date
Jason Zaugg 7d4890b68a Avoid CCE when scalac internally uses compileLate. Fixes #2452
For example, when the `--sourcepath` option is provided
and the refchecks phase compiles an annotation found
on a referenced symbol from the sourcepath.

`compileLate` assumes that all non-sentinel compiler
phases can be down cast to `GlobalPhase`.

This commit changes the two phases in SBT to extend
this instead of `Phase`. This has the knock on benefit
of simplifying the phases by letting the `GlobalPhase.run`
iterator over the list of compilation units and feed them
to us one by one.

I checked that the test case failed before making each
change.
2016-02-11 16:29:09 -05:00
Martin Duhem 6576844698 Hash of traits: include private fields, objects and super accessors 2016-02-10 18:15:44 +01:00
Guillaume Martres 726b5c8a30 ExtractAPI: avoid unnecessary duplication of defs with primitive types
If a method's type contains a non-primitive value class then it has two
signatures: one before erasure and one after erasure. Before this
commit, we checked if this was the case using `isAnyValSubtype`, but
this is too crude since primitive value classes are also subtypes of
`AnyVal` but do not change signature after erasure.

This commit replaces `isAnyValSubtype` by `isDerivedValueClass` which
excludes primitive value classes.

In practice, for an empty class, this reduces the size of the output of
`DefaultShowAPI` from 65 lines to 25 lines.
Before:
https://gist.github.com/smarter/cf1d6fe58efda88d6ee6#file-old-api
After:
https://gist.github.com/smarter/cf1d6fe58efda88d6ee6#file-new-api
2016-01-25 02:53:52 +01:00
Guillaume Martres 0993c1c7cc Always invalidate API when return type is a value class
Before this commit, we did not do the invalidation for methods with
multiple parameter list, the comment above `hasValueClassAsReturnType`
said:

  Note: We only inspect the "outermost type" (i.e. no recursion) because
  we don't need to inspect after erasure a function that would, for
  instance, return a function that returns a subtype of AnyVal.

But this is wrong: a method with signature:
  def foo(a: A)(b: B): C
is erased to:
  def foo(a: A, b: B): C
and not, as the comment in the code suggest, to:
  def foo(a: A): B => C
so we do need to inspect the final result type of methods, because they
can be value classes that will be erased to their underlying value.
2016-01-25 02:53:34 +01:00
Martin Duhem 1ebe86b704 Restore compiler bridge source for Scala < 2.10 2016-01-24 18:54:03 +01:00
Adriaan Moors 49431eb6f8 determine bytecode type with transformedType
... not exitingPostErasure, as this phase-travel crashes the compile
(it's only really meant for going back in time, right?)
2016-01-24 09:31:53 +01:00
Grzegorz Kossakowski dd0ed7de5e Fix DependencySpecification test.
This is a fixup of 0f616294c4.
That commit assumed that dealiasing is being done for types referred in
self type. It was changed to not do that but the test wasn't updated.
Unfortunately, that mistake slipped by during PR review because unit tests
of compileInterface were not ran (see #2358).
2016-01-09 00:00:14 +01:00
Adriaan Moors 698902ba44 API limited to static annotations to mimic pickling
Since pickled annotated types and symbols only mention
static annotations, whereas compilation from source
sees all annotations, we must explicitly filter annotations
in the API representation using the same criteria as the pickler,
so that we generate the same API when compiling from source
as when we're loading classfiles.
2016-01-06 13:56:54 -05:00
Krzysztof Romanowski d32a0eaaa0 Exclude all non static annotations from ExtractAPI 2016-01-06 13:56:54 -05:00
Adriaan Moors 0f616294c4 Extract dependencies in one pass.
Also a bit more complete: handle SelectFromTypeTree,
consider the self type an inheritance dependency,
and flatten any refinement types in inherited types,
to get to the symbols of their parents, instead of the
useless symbol of the refinement class.

Include inheritance dependencies in regular ones

Also, update test to reflect the self type is now seen as an inheritance dependency.

self types are local, so don't treat them like inherited types

note inheritanceSymbols dealiases, where allSymbols is constructed differently

fix NPE in source-dependencies/macro-annotation
2016-01-06 13:56:54 -05:00
Adriaan Moors 8c73b2f221 Refactor mkStructure
Specialize two implementations for each value of the `inherit` boolean argument.
Also use a more direct way of distinguishing declared and inherited members.

backwards compat for source-dependencies/inherited-dependencies
2016-01-06 13:56:54 -05:00
Adriaan Moors 9346e2bb4d Only include all base types for class definitions
For refinement types, the Structure was already restricted
to declarations (and not inherited members), but all base types
were still included for a refinement's parents, which would
create unwieldy, and even erroneous (cyclic) types by expanding
all constituents of an intersection type to add all base types.

Since the logic already disregarded inherited members, it seems
logical to only include direct parents, and not all ancestor types.

```
class Dep {
  def bla(c: Boolean) = if (c) new Value else "bla"
}

class Value extends java.lang.Comparable[Value] { def compareTo(that: Value): Int = 1 }
```
2016-01-06 13:56:54 -05:00
Adriaan Moors 3e03e0d1b5 Clean up ShowApi implicit overload
Motivated because we want to make it more robust & configurable.
Original motivation was to diagnose a cyclic type representation,
likely due to an f-bounded existential type, as illustrated by the following:

```
class Dep {
  // The API representation for `bla`'s result type contains a cycle
  // (an existential's type variable's bound is the existential type itself)
  // This results in a stack overflow while showing the API diff.
  // Note that the actual result type in the compiler is not cyclic
  // (the f-bounded existential for Comparable is truncated)
  def bla(c: Boolean) = if (c) new Value else "bla"
}

class Value extends java.lang.Comparable[Value] { def compareTo(that: Value): Int = 1 }
```

Limit nesting (`-Dsbt.inc.apidiff.depth=N`, where N defaults to `2`),
and number of declarations shown for a class/structural type
(via `sbt.inc.apidiff.decls`, which defaults to `0` -- no limit).

Limiting nesting is crucial in keeping the size of api diffs of large programs
within a reasonable amount of RAM...

For example, compiling the Scala library, the API diff with nesting at `4`
exhausts 4G of RAM...
2016-01-06 13:56:54 -05:00
Adriaan Moors 51524055f7 Reduce memory usage of ExtractDependenciesTraverser 2016-01-06 13:56:54 -05:00
Adriaan Moors 1ce1123054 API only tracks declared type of self variable
The only aspect of the self variable that's relevant for
incremental compilation is its explicitly declared type,
and only when it's different from the type of the class that declares it.

Technically, any self type that's a super type of the class could be ignored,
as it cannot affect external use (instantiation/subclassing) of the class.
2016-01-06 13:56:54 -05:00
Adriaan Moors 214451c51f API extraction ensures class symbol is initialized
Call `initialize` in case symbol's `info` hadn't been completed
during normal compilation.

Also, normalize to the class symbol immediately.

Add a TODO regarding only looking at class symbols,
and thus ignoring the term symbol for objects,
as the corresponding class symbol has all the relevant info.
2016-01-06 13:56:54 -05:00
Grzegorz Kossakowski 81c0d3daa9 Document ExtractAPI's handling of private members.
Mention that private members are being extracted and included in the api
structures but ignored in many other parts of incremental compiler. I've
made a mistake of assuming that private members are ignored at api
extraction time. This manifested itself as bug #2324.
2015-12-18 14:14:11 -08:00
Martin Duhem a244f4e141 Fix Codacy failure by specifying return type 2015-11-11 14:49:50 +01:00
Martin Duhem f5e7fdd62a Restore source compatibility with Scala 2.8 2015-11-09 16:30:11 +01:00
Martin Duhem bfc27f1179 Make sure AnyVal is involved before checking post erasure 2015-11-07 09:06:26 +01:00
Martin Duhem d41fda6584 Restore source compatibility with Scala 2.8 + cosmetic changes 2015-11-06 13:11:13 +01:00
Martin Duhem 499c5e7228 Correct fix against SO and macros problem 2015-11-06 11:27:40 +01:00
Martin Duhem f1c05cb5eb Fix source compatibility with Scala < 2.10 2015-11-05 09:26:38 +01:00
Martin Duhem 4299ff76aa Quick and dirty fix for SO 2015-11-05 07:39:50 +01:00
Martin Duhem 9764b7f6ef Don't inspect signatures post erasure if macros are involved 2015-11-04 17:45:08 +01:00
Martin Duhem 111511dc6d `afterPostErasure` didn't exist in 2.9 2015-11-04 15:04:59 +01:00
Martin Duhem efff171618 Restore source compatibility with Scala 2.11 2015-11-04 13:35:53 +01:00
Martin Duhem 46058029b5 Consider signatures of method before and after erasure in ExtractAPI
The signatures of methods that have value classes as arguments or return
type change during the erasure phase. Because we only registered
signatures before the erasure, we missed some API changes when a class
was changed to a value class (or a value class changed to a class).

This commit fixes this problem by recording the signatures of method
before and after erasure.

Fixes sbt/sbt#1171
2015-11-04 11:16:53 +01:00
Pierre DAL-PRA 8f1fb2d232 Fix additional warnings 2015-08-07 00:23:14 +02:00
Pierre DAL-PRA 54d54b9f4f Replace procedure syntax by explicit Unit annotation 2015-08-04 10:07:38 +02:00
Pierre DAL-PRA f0bd9001e6 Remove redundant collection conversions 2015-08-01 12:05:35 +02:00
Pierre DAL-PRA b9171e59ad Simplify operations on collections 2015-08-01 02:25:17 +02:00
eugene yokota be78b7fc4c Merge pull request #1759 from jedesah/topic/minor_cleanup
Minor code cleanup
2015-01-14 16:13:06 -05:00
Josh Suereth 488a62c8bf Merge pull request #1754 from Duhemm/fix-1655
Check for null type trees in dependency extraction
2014-12-04 17:57:44 -05:00
Jean-Rémi Desjardins ca736e55d3 Minor code cleanup 2014-12-03 09:56:34 -08:00
eugene yokota 7df9802f0c Merge pull request #1714 from sbt/wip/bytecode-enhancement
Expose mechanism whereby bytecode enhancement can be run *before* saving incremental compiler hashes.
2014-12-03 08:46:52 -05:00
Josh Suereth 067479f59e Debug issues with implicit usage for CompileSetup.
* Force CompileSetup Equiv typeclass to use Equiv relations defined locally.
* Add toString methods on many of the incremental compiler datatypes.
* Remove remaining binary compatibility issues in Defaults.scala.
2014-12-01 13:35:51 -05:00
Martin Duhem 18c521dd4b Check for null type trees in dependency extraction
In some cases the dependency extraction may encounter a null `TypeTree`
(eg. arguments of macro annotations that are untyped). In such cases,
we simply ignore the node.

Fixes #1593, #1655.
2014-11-29 12:17:32 +01:00
Martin Duhem 98c789b826 Abstract over dependency context in Compile
This commit completes the abstraction over dependency kinds in the
incremental compiler, started with #1340.
2014-11-19 10:35:07 +01:00
Josh Suereth 70cdce0830 Create a new API for calling Java toolchains.
* Create a new sbt.compiler.javac package
* Create new interfaces to control running `javac` and `javadoc` whether forked or local.
* Ensure new interfaces make use of `xsbti.Reporter`.
* Create new method on `xsbti.compiler.JavaCompiler` which takes a `xsbti.Reporter`
* Create a new mechanism to parse (more accurately) Warnings + Errors, to distinguish the two.
* Ensure older xsbti.Compiler implementations still succeed via catcing NoSuchMethodError.
* Feed new toolchain through sbt.actions.Compiler API via dirty hackery until we can break things in sbt 1.0
* Added a set of unit tests for parsing errors from Javac/Javadoc
* Added a new integration test for hidden compilerReporter key, including testing threading of javac reports.

Fixes #875, Fixes #1542,  Related #1178 could be looked into/cleaned up.
2014-10-29 20:06:08 -04:00
Martin Duhem 41f07be247 Port fix for #1544 from Dependency to ExtractUsedNames
The fix for sbt/sbt#1237 was unfortunately not completely correct,
and infinite loops could still occur during the extraction of used
names.

In sbt/sbt#1544, a fix that was robuster and easier to understand
was applied to `/compile/interface/src/main/scala/xsbt/Dependency.scala`
in a similar situation (cyclic chains of original trees in macro
expansions).

This commit ports this fix to `ExtractUsedNames.scala`.

Closes sbt/sbt#1640, sbt/sbt#1610.
2014-10-03 22:01:49 +02:00
Martin Duhem 8542c9b31a Fix SOE with macros in dependencies extraction
In some cases, expanded macros report that their original tree and
its expansion are the same, thus creating a cyclic chain. This chain
may then produce a SOE during dependencies or used names extraction.

This kind of problem was already reported in sbt/sbt#1237 and
sbt/sbt#1408. Unfortunately, the fix that was applied to the
dependencies extraction part was not sufficient.

Mark test 'source-dependencies/macro' as passing

Fixes #1544
2014-09-10 15:54:06 +02:00
Martin Duhem 26e2449263 Never inspect twice the same macro application
In Scala 2.10.4, this macro can produce a stack overflow :

    def foo(a: Any): Any = macro impl
    def impl(c: Context)(a: c.Expr[Any]): c.Expr[Any] = a

Here, an application such as `foo(someVal)` will produce the expansion
`someVal`. As expected, `someVal` has `original` tree `foo(someVal)`,
but if we inspect this tree, we will find that `someVal` has an
original tree, but it shouldn't.

Moreover, in Scala 2.11, some macros have their own application as
`original` trees.

See sbt/sbt#1237 for a description of these problems.

This commit fixes these two problems.

Fixes sbt/sbt#1237
2014-08-18 09:22:16 +02:00
Brian McKenna 2fefaf5758 Change "Not a simple type" warning to log message
Workaround for -Xfatal-warnings being triggered because of #830.
2014-07-30 07:45:03 -06:00
Josh Suereth 244abd3b6f Scalariforming test code 2014-05-07 11:52:23 -04:00
Eugene Yokota adb41611cf added scalariform 2014-05-01 12:50:07 -04:00
Martin Duhem 062cd1c776 Add link to corresponding issue in Scala issue tracker 2014-04-08 23:18:48 +02:00
Martin Duhem a80966e394 Handle macros that have themselves as original tree
It has been reported in sbt/sbt#1237 that stack overflows may occur during the
extraction of used names (and later of dependencies between files). This
problem has been introduced by sbt/sbt#1163, which was about recording the
dependencies of macro arguments.

When a macro is expanded, the compiler attaches the tree before expansion to
the tree representing the expanded macro. As of Scala 2.11-RC3, some macros
have themselves attached as original tree, which caused the same macro to be
inspected over and over until a stack overflow.

This commit solves this problem by making sure that the original of a macro
expansion will be inspected if and only if it is different from the expanded
tree.

Fixes sbt/sbt#1237
2014-04-07 11:33:47 +02:00
Martin Duhem 133ba07eb8 Unit test for dependency extraction from macro applications
Add a unit test which checks whether we capture dependencies introduced
by arguments to macros. Those dependencies are special because macros
get expanded during type checking and arguments to macros are not visible
during regular tree walk.
2014-03-20 19:13:20 +01:00
Martin Duhem b21e475364 Improve unit testing compiler
It was not possible to make `ScalaCompilerForUnitTesting` compile several
files in different runs, which means that it was not possible to compile
and use a macro in a test case, since macros cannot be used in the same
compilation run that defines them.

This commit allows a test case to provide multiple grouped snippets of
code that will be compiled in separate runs.

For instance :
    List(Map(<snippet A>, <snippet B>), Map(<snippet C>))

Here, <snippet A> and <snippet B> will be compiled together, and then
<snippet C> will be compiled, and will be able to use symbols defined
in <snippet A> or <snippet B>.
2014-03-19 22:21:29 +01:00