Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.13.10] ExtractAPI: avoid unnecessary duplication of defs with primitive types #2414

Merged
merged 2 commits into from
Jan 25, 2016

Conversation

smarter
Copy link
Contributor

@smarter smarter commented Jan 23, 2016

NOTE: This PR is based on top of #2413 for convenience because they conflict with each other, but they could be made independent.


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

/cc @Duhemm

@eed3si9n eed3si9n added the ready label Jan 23, 2016
@typesafe-tools
Copy link

Can one of the admins verify this patch?

@smarter smarter changed the title ExtractAPI: avoid unnecessary duplication of defs with primitive types [0.13.10] ExtractAPI: avoid unnecessary duplication of defs with primitive types Jan 23, 2016
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.
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
@smarter
Copy link
Contributor Author

smarter commented Jan 25, 2016

Rebased.

@eed3si9n
Copy link
Member

LGTM pending Travis

@dwijnand
Copy link
Member

Scripted test "tests / nested-subproc" failed. Starting the "tests" suite again.

@Duhemm
Copy link
Contributor

Duhemm commented Jan 25, 2016

Thanks for the fixes!

Duhemm added a commit that referenced this pull request Jan 25, 2016
[0.13.10] ExtractAPI: avoid unnecessary duplication of defs with primitive types
@Duhemm Duhemm merged commit e966329 into sbt:0.13.10 Jan 25, 2016
@eed3si9n eed3si9n removed the ready label Jan 25, 2016
smarter added a commit to smarter/zinc that referenced this pull request Apr 9, 2016
The previous approach to value class API (introduced by sbt/sbt#2261 and
refined by sbt/sbt#2413 and sbt/sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced recompilations.
This is no longer necessary thanks to sbt#87: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that use a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of <init> change and since every class uses the name
<init>, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/zinc that referenced this pull request Apr 9, 2016
The previous approach to value class API (introduced by sbt/sbt#2261 and
refined by sbt/sbt#2413 and sbt/sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced recompilations.
This is no longer necessary thanks to sbt#87: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that use a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of <init> change and since every class uses the name
<init>, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/zinc that referenced this pull request Apr 9, 2016
The previous approach to value class API (introduced by sbt/sbt#2261 and
refined by sbt/sbt#2413 and sbt/sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced recompilations.
This is no longer necessary thanks to sbt#87: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of <init> change and since every class uses the name
<init>, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 14, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 14, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 15, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 15, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 15, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 15, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 16, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 18, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 19, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 20, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
smarter added a commit to smarter/sbt that referenced this pull request Apr 20, 2016
This is a backport of sbt/zinc#95

The previous approach to value class API (introduced by sbt#2261 and
refined by sbt#2413 and sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced
recompilations.
This is no longer necessary thanks to sbt#2523: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of `<init>` changes and since every class uses the name
`<init>`, we don't need to do anything special to trigger recompilations
either.
eed3si9n pushed a commit to eed3si9n/scala that referenced this pull request May 14, 2019
The previous approach to value class API (introduced by sbt/sbt#2261 and
refined by sbt/sbt#2413 and sbt/sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced recompilations.
This is no longer necessary thanks to scala#87: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of <init> change and since every class uses the name
<init>, we don't need to do anything special to trigger recompilations
either.
lrytz pushed a commit to lrytz/scala that referenced this pull request Nov 5, 2019
The previous approach to value class API (introduced by sbt/sbt#2261 and
refined by sbt/sbt#2413 and sbt/sbt#2414) was to store both unerased and
erased signatures so that changes to value classes forced recompilations.
This is no longer necessary thanks to scala#87: if a class type is
used, then it becomes a dependency of the current class and its name is
part of the used names of the current class. Since the name hash of a
class changes if it stops or start extending AnyVal, this is enough to
force recompilation of anything that uses a value class type. If the
underlying type of a value class change, its name hash doesn't change,
but the name hash of <init> change and since every class uses the name
<init>, we don't need to do anything special to trigger recompilations
either.

Rewritten from sbt/zinc@1e7e99e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants