Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 361240

Summary: [xtend2][builder] changing method signature does not cause dependent sources to be revalidated
Product: [Tools] Xtend Reporter: Knut Wannheden <knut.wannheden>
Component: CoreAssignee: Jan Koehnlein <jan>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: jan, sebastian.zarnekow, sven.efftinge, xtend-inbox
Version: 2.2.0Flags: jan: juno+
Target Milestone: M6   
Hardware: PC   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:

Description Knut Wannheden CLA 2011-10-18 07:23:46 EDT
Given a class Foo.xtend with:

class Foo {
  def String foo() {}
}

and an extending class Bar.xtend with:

class Bar extends Foo {
  override String foo() {}
}

If I now change the return type of Foo#foo() from String to Integer the resource Bar.xtend doesn't get rebuilt.

The problem is that the exported object for Foo#foo() doesn't capture information about the method signature.
Comment 1 Jan Koehnlein CLA 2012-03-07 12:08:28 EST
Added a signature hash including parameter/return/field types, exceptions and type parameters
Comment 2 Jan Koehnlein CLA 2012-03-07 12:08:47 EST
... and visibility
Comment 3 Jan Koehnlein CLA 2012-03-08 12:19:14 EST
Thinking again,  if we need the signature only for the isAffected mechanism, we should have a single signature on all client relevant parts of a type.
That also includes a hash of all superclasses / implemented interfaces. That way, we also rebuild clients of a subclass if the super class changes its API.
Comment 4 Jan Koehnlein CLA 2012-03-08 12:24:05 EST
Committed a first shot at the problem and several tests.

For better performance, we should not require to hash fixed super types, e.g. from the JRE, and use their FQN instead. I could not find any service to detect if a tpye is fixed. Any hints welcome.
Comment 5 Jan Koehnlein CLA 2012-03-08 12:28:16 EST
We could use IJavaElement.isReadOnly on the mirror of the type resource (in the UI screnario, in non-UI every type is read.only).
Comment 6 Sven Efftinge CLA 2012-03-08 14:03:05 EST
Just had a StackOverflow  with the latest changes :

        at org.eclipse.xtext.util.OnChangeEvictingCache.get(OnChangeEvictingCache.java:75)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider.getHash(JvmDeclaredTypeSignatureHashProvider.java:61)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitTypeReference(JvmDeclaredTypeSignatureHashProvider.java:162)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitTypeReference(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor$InheritanceAware.doVisitParameterizedTypeReference(AbstractTypeReferenceVisitor.java:65)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitParameterizedTypeReference(JvmDeclaredTypeSignatureHashProvider.java:178)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitParameterizedTypeReference(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.common.types.impl.JvmParameterizedTypeReferenceImplCustom.accept(JvmParameterizedTypeReferenceImplCustom.java:53)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder.appendSuperTypeSignatures(JvmDeclaredTypeSignatureHashProvider.java:158)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder.appendSignature(JvmDeclaredTypeSignatureHashProvider.java:119)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder.appendMemberSignatures(JvmDeclaredTypeSignatureHashProvider.java:134)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder.appendSignature(JvmDeclaredTypeSignatureHashProvider.java:119)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$1.get(JvmDeclaredTypeSignatureHashProvider.java:63)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$1.get(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.util.OnChangeEvictingCache.get(OnChangeEvictingCache.java:75)
Comment 7 Jan Koehnlein CLA 2012-03-08 16:39:14 EST
Yes, this looks like an inner type that extends/implements the outer one. 
I should not add the signatures of inner types to the one of the surrounding type. Fix pushed to MASTER.
Comment 8 Sebastian Zarnekow CLA 2012-03-08 16:43:47 EST
Protected inner classes have a very high precendence when it comes to the linking of types (at least in Java). Does it make sense to add the name of protected / public inner types to the signature hash of the enclosing type?
Comment 9 Knut Wannheden CLA 2012-03-09 02:31:42 EST
This looks really nice!

Once we create warning markers for usages of @Deprecated members we should probably also consider adding annotations to the signature. Maybe there are other use cases for that as well.
Comment 10 Jan Koehnlein CLA 2012-03-09 05:28:17 EST
Added the qualified names of all inner types to the signature of the container.
Comment 11 Sebastian Zarnekow CLA 2012-03-09 05:56:26 EST
I still get a stack overflow:

java.lang.StackOverflowError
	at com.google.inject.internal.util.$Preconditions.checkPositionIndex(Preconditions.java:388)
	at com.google.inject.internal.util.$Preconditions.checkPositionIndexes(Preconditions.java:414)
	at com.google.inject.internal.util.$Iterators.forArray(Iterators.java:267)
	at com.google.inject.internal.util.$ImmutableList$RegularImmutableList.iterator(ImmutableList.java:368)
	at com.google.inject.internal.util.$ImmutableList$RegularImmutableList.iterator(ImmutableList.java:338)
	at com.google.inject.internal.Errors.convert(Errors.java:665)
	at com.google.inject.internal.Errors.format(Errors.java:523)
	at com.google.inject.internal.Errors.addMessage(Errors.java:508)
	at com.google.inject.internal.Errors.errorInUserCode(Errors.java:390)
	at com.google.inject.internal.Errors.errorInjectingConstructor(Errors.java:340)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:102)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
	at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:978)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
	at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:974)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$1.get(JvmDeclaredTypeSignatureHashProvider.java:63)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$1.get(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.util.OnChangeEvictingCache.get(OnChangeEvictingCache.java:75)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider.getHash(JvmDeclaredTypeSignatureHashProvider.java:61)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitTypeReference(JvmDeclaredTypeSignatureHashProvider.java:160)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitTypeReference(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor$InheritanceAware.doVisitParameterizedTypeReference(AbstractTypeReferenceVisitor.java:65)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitParameterizedTypeReference(JvmDeclaredTypeSignatureHashProvider.java:176)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitParameterizedTypeReference(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.common.types.impl.JvmParameterizedTypeReferenceImplCustom.accept(JvmParameterizedTypeReferenceImplCustom.java:53)
	at org.eclipse.xtext.common.types.util.AbstractTypeReferenceVisitor.visit(AbstractTypeReferenceVisitor.java:32)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitParameterizedTypeReference(JvmDeclaredTypeSignatureHashProvider.java:179)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder$3.doVisitParameterizedTypeReference(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.common.types.impl.JvmParameterizedTypeReferenceImplCustom.accept(JvmParameterizedTypeReferenceImplCustom.java:53)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder.appendSuperTypeSignatures(JvmDeclaredTypeSignatureHashProvider.java:156)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$SignatureHashBuilder.appendSignature(JvmDeclaredTypeSignatureHashProvider.java:119)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$1.get(JvmDeclaredTypeSignatureHashProvider.java:63)
	at org.eclipse.xtext.xbase.jvmmodel.JvmDeclaredTypeSignatureHashProvider$1.get(JvmDeclaredTypeSignatureHashProvider.java:1)
	at org.eclipse.xtext.util.OnChangeEvictingCache.get(OnChangeEvictingCache.java:75)
Comment 12 Sebastian Zarnekow CLA 2012-03-09 05:58:14 EST
I don't think that it's a good idea to sort the members since uri fragments are usually based on indizes thus a reordering of members can lead to outdated reference descriptions in the index, can't it?
Comment 13 Sebastian Zarnekow CLA 2012-03-09 06:00:09 EST
The stackoverflow could be caused by something like

MyList extends ArrayList<ArrayList<String>>, can't it?
Comment 14 Jan Koehnlein CLA 2012-03-09 06:07:36 EST
(In reply to comment #13)
> The stackoverflow could be caused by something like
> 
> MyList extends ArrayList<ArrayList<String>>, can't it?

Yep, I can reproduce it.
Comment 15 Sebastian Zarnekow CLA 2012-03-09 06:08:18 EST
class XtendClass extends ArrayList<String> {}

causes the stackoverflow
Comment 16 Knut Wannheden CLA 2012-03-09 07:56:32 EST
(In reply to comment #12)
> I don't think that it's a good idea to sort the members since uri fragments are
> usually based on indizes thus a reordering of members can lead to outdated
> reference descriptions in the index, can't it?

If all the members are also indexed as exported objects then the problem you're describing shouldn't be possible, because reordering the members would already cause the exported objects order to change and thus result in a delta. OTOH there is probably no advantage in doing a sort.
Comment 17 Jan Koehnlein CLA 2012-03-09 10:42:13 EST
Alright, I hope I have improved it now.

The stack overflow occured because String implements Comparable<String>
resulting in a endless loop. Type arguments are added to the signatures with
theit identifiers now instead of their hashes.

The sorting of members and supertypes has been removed as suggesten in comment 12.

I added 'relevant' annotation references to the signatures. These are the ones
that affect client's rebuild, such as @Deprecated. Feel free to add more.

I also introdcued the notion of sealed IMirrors, which refer to classes that
can be changed. For those, I don't have to calculate a hash as they don't
change. My  hope is that this boosts performance significntly.

Last but not least, there are a couple of new tests for more scenarios and for
the new features.
Comment 18 Jan Koehnlein CLA 2012-03-09 10:42:43 EST
Pushed to MASTER
Comment 19 Karsten Thoms CLA 2017-09-19 17:26:45 EDT
Closing all bugs that were set to RESOLVED before Neon.0
Comment 20 Karsten Thoms CLA 2017-09-19 17:38:02 EDT
Closing all bugs that were set to RESOLVED before Neon.0