Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » From o.e.j.core.CompletionProposal to erased method signature?
From o.e.j.core.CompletionProposal to erased method signature? [message #1408138] Thu, 14 August 2014 10:22 Go to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Hi,

I am currently trying to determine, given a o.e.j.core.CompletionProposal (of kind METHOD_REF* or METHOD_NAME_REFERENCE) and a TypeBinding for the method call's receiver, what method this will complete to. In particular, I want the erased method signature as it would appear in Java bytecode.

Doing this by-hand is quite challenging:

One option would be to get the numerous signatures from the CompletionProposal (getDeclarationSignature, getReceiverSignature, getSignature, even fOriginalSignature via reflection). Alas, replacing the various type parameters with their erased bounds is tricky, as the information what exactly 'T' refers to can come from the method's generic signature or any superclass's or interface's.

Another option is to get the availableMethods() from the receiver's TypeBinding (downcasting to ReferenceBinding) and then match those one by one against the CompletionProposal's signature until a match is found. Then, the erased method signature could be extracted from the matching MethodBinding. Here the tricky part is likely to be the matching (due to overloading).

As either way looks awfully complicated, I wonder whether there's a simpler/more direct way to determine what method a CompletionProposal refers to. Any help is greatly appreciated.

Best wishes,

Andreas
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408240 is a reply to message #1408138] Thu, 14 August 2014 15:21 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
After a quick glance a variant of your second option looks viable to me:
- start by ReferenceBinding.getMethods(proposal.getName())
- then indeed match overloads using the signature

Remaining challenge: from the actual receiver type you may need to walk up the type hierarchy ...
UNLESS, you actually hold the ReferenceBinding for the declaring class (from the proposal's declaration type name and package).

HTH,
Stephan
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408257 is a reply to message #1408240] Thu, 14 August 2014 15:55 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Thank you, Stephan, for taking a look. Your advice should help me fix Bug 441806 in Code Recommenders.

Follow-up: I don't have a ReferenceBinding for the declaring class, unfortunately, just one for the actual receiver type. Do I thus have to implement the type hierarchy walking (probing with ReferenceBinding.getMethods() at each level) myself or does there exist a utility method somewhere in JDT that I can use for this?
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408260 is a reply to message #1408257] Thu, 14 August 2014 16:08 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
If you need an exact result, hierarchy traversal is actually quite painful, because you should observe the exact rules for overriding, which is not s.t. I'd recommend for Recommenders Smile.
The compiler uses a complex machine starting at Scope.findMethod(..) which probably cannot be used from outside (independent of access restrictions).

In that light, retrieving the actual declaring class's ReferenceBinding using the declaring type name from the proposal should be easier. Don't you have a LookupEnvironment in your hands, already?

S.
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408310 is a reply to message #1408260] Thu, 14 August 2014 18:51 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Yes, we do have a LookupEnvironment. Smile Thanks for the pointer.

One issue I am still struggling with is that the MethodBinding knows about its erased signature (which I am after) but the CompletionProposal's signature (or fOriginalSignature) is not erased otherwise we would be done already.

So the question is: How do I match an CompletionProposal to a MethodBinding?

Here's a couple of signatures from my test cases:
MethodBinding.signature()    CompletionProposal.getSignature()

(Ljava/util/Collection;)V    (Ljava.util.Collection<Ljava.lang.Number;>;)V
(Ljava/util/Collection;)V    (Ljava.util.Collection<*>;)V
(Ljava/util/Collection;)V    (Ljava.util.Collection<+Ljava.lang.Number;>;)V
(Ljava/util/Collection;)V    (Ljava.util.Collection<-Ljava.lang.Number;>;)V
(Ljava/lang/Object;)V        (TT;)V
(Ljava/lang/Number;)V        (TN;)V
(Ljava/lang/Object;)V        <T:Ljava.lang.Object;>(TT;)V
(Ljava/lang/Number;)V        <N:Ljava.lang.Number;>(TN;)V

If I could turn the right-hand side into the left-hand side I would be done, but that conversion turned out to be hard (hence my post to this forum).

So how to turn a MethodBinding instead into one or more signatures that I could use to match a signature as given on the right-hand side?
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408311 is a reply to message #1408310] Thu, 14 August 2014 18:53 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
check MethodBinding.genericSignature() ...
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408519 is a reply to message #1408311] Fri, 15 August 2014 09:02 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Quote:
check MethodBinding.genericSignature() ...

Yes, that matches (up to a slashes/dots mismatch) CompletionProposal.getSignature() if MethodBinding.genericSignature() is not null, which happens if the method in question is not a generic method.

Now, simply matching CompletionProposal.getSignature() to MethodBinding.signature() in "genericSignature() == null" case is probably(?) a bad idea, as MethodBinding.signature()'s Javadoc states that it should only be called during/after code generation.

But matching against the method MethodBinding is unnecessary if the CompletionProposal.getSignature() is not a generic signature anyway. The only remaining question I thus have is whether there is an easy way to figure that out, i.e., whether CompletionProposal.getSignature() contains any generics-related information or not.

If there does not exist such a method (I couldn't find one, but JDT is huge, so I may have missed it), I guess I will have to dismantle the signature myself using Signature.getParameterTypes/getReturnType and then check with Signature.getTypeSignatureKind for anything generics-related. Does this sound like the way to go to you?

BTW, thanks for your help so far. Much appreciated.
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1408525 is a reply to message #1408519] Fri, 15 August 2014 09:29 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Quote:
But matching against the method MethodBinding is unnecessary if the CompletionProposal.getSignature() is not a generic signature anyway.

I fear I was a bit confused when I wrote this. Yes, I wouldn't need to match against the MethodBinding in the first place when the CompletionProposal doesn't have a generic signature, but if it does then I do need to get the low-level, bytecode signature out of the MethodBinding. So far, I have been thinking of doing this using MethodBinding.signature() but the Javadoc suggests that I shouldn't do that.

So, how to get at the desired erased signature once I have matched (one way or another) the MethodBinding?
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1409598 is a reply to message #1408525] Mon, 18 August 2014 13:50 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
Coming from the method binding, checking whether it is generic can be done by s.t. like:
methodBinding.original().typeVariables() != Binding.NO_TYPE_VARIABLES


Coming from the signature you might be looking for Signature.getTypeParameters()?
If you get a parameterized method, you should have the original in proposal.getOriginalSignature(), and that should expose the type parameters.

(sorry about the confusion of names, but here binding.typeVariables() and Signature.getTypeParameters() refer to the same thing - which I admit isn't kosher ..)

S.
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1409925 is a reply to message #1409598] Tue, 19 August 2014 10:16 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Hi Stephan. Thanks again for your help. I'm slowly getting there. And in true TDD fashion I've started with a test suite for my "MethodBinding -> erased signature" method. Smile

There's one test case where MethodBinding.genericSignature() returns something I didn't expect from the erased (bytecode) signature:
  class Example {
    <N extends Number & Comparable> void method(N n) {
      this.method(null);
    }
  }

If I obtain a MethodBinding for method, both method.genericSignature and method.signature() answer "(Ljava/lang/Comparable;)V". I would, however, expect "(Ljava/lang/Number;)V", as that's what javap shows for the signature of the method. Am I missing something here? When looking at the MethodBinding in question in the debugger, it says

  void method(Comparable#RAW & java.lang.Number) 

with a parameter of IntersectionCastTypeBinding. Can you explain what's going on here?
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1409967 is a reply to message #1409925] Tue, 19 August 2014 12:50 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Interestingly, MethodBinding.original().signature() is "(Ljava/lang/Number;)V" rather than "(Ljava/lang/Comparable;)V" for the above case.
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1411071 is a reply to message #1409967] Fri, 22 August 2014 10:15 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Hi Stephan. I am afraid I spotted a problem with the current approach of matching the CompletionProposal's signature against the MethodBinding's. Maybe you can help me out.

The problem occurs if the CompletionProposal's declaring type (as obtained from the LookupEnvironment) is a BinaryTypeBinding. In that case, ReferenceBinding.getMethod returns MethodBindings with parameters like Collection#RAW. An example:

For a declaring type of
  public class java.util.ArrayList<E extends java.lang.Object>
	extends Unresolved type java.util.AbstractList<E>
	implements : List<E>, Unresolved type java.util.RandomAccess, Unresolved type java.lang.Cloneable, Unresolved type java.io.Serializable
I get constructor overloads of
[public void <init>() , public void <init>(int) , public void <init>(Collection#RAW) ]

Now, matching the third of these against the CompletionProposal's Signature of "(Ljava/util/Collection<+TE;>;)V" is tricky (lots of fiddly String-manipulation, unless there exists a nice helper method that strips off type parameters).

Interestingly, other methods of ArrayList are kept with their type parameters:
public boolean add(E)
so our approach will certainly help with matching in these cases.

Do you think that falling back to the CompletionProposal's signature with type parameters stripped off will work, i.e., that only parameterized arguments are "raw" in BinaryTypeBindings, but that I will always see type variables (like "E" in the "add" example above) if used as parameters? (All these type parameters and parameter types make my head hurt Wink)

FWIW, the actual code is at <https://git.eclipse.org/r/#/c/31964/14/plugins/org.eclipse.recommenders.completion.rcp/src/org/eclipse/recommenders/completion/rcp/utils/ProposalUtils.java>, with the matching of overloads happening in lines 90 ff.

Best wishes,

Andreas

Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1411189 is a reply to message #1411071] Fri, 22 August 2014 16:13 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
I'm surprised to see a binary constructor having a raw parameter.

You might want to set a conditional breakpoint inside BinaryTypeBinding.createMethod() (to catch that specific constructor) and see if method.getGenericSignature() answers anything.
If the bytecode contains a signature, then this should be available and be used to create a parameterized type for the parameter.

If signature is found and still a raw type is created, I could imagine this to be caused by failure to resolve the type, so we proceed with an UnresolvedReferenceBinding, which later is resolved(?) to its raw variant.

Not quite sure what's going on ...
S.
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1411220 is a reply to message #1411189] Fri, 22 August 2014 18:14 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Quote:
I'm surprised to see a binary constructor having a raw parameter.

You might want to set a conditional breakpoint inside BinaryTypeBinding.createMethod() (to catch that specific constructor) and see if method.getGenericSignature() answers anything.
If the bytecode contains a signature, then this should be available and be used to create a parameterized type for the parameter.

If signature is found and still a raw type is created, I could imagine this to be caused by failure to resolve the type, so we proceed with an UnresolvedReferenceBinding, which later is resolved(?) to its raw variant.

Will certainly debug this later. FWIW, this happened under Juno and I couldn't reproduce it under Luna yet. (Haven't tested Kepler so far.)
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1411823 is a reply to message #1411220] Sun, 24 August 2014 14:54 Go to previous messageGo to next message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Another interesting problem popped up:

In a scenario like the following
new Comparator() {
  public int compare(Object lhs, Object rhs) {
    compare<Ctrl+Space>
  }
}
the declarationSignature of the InternalCompletionProposal is just "LObject;", which is not very helpful for the LookupEnvironment.getType(compoundName) call needed to obtain a MethodBinding for compare.

Is there a way to handle LocalTypeBinding declaring types like
Anonymous type : (id=NoId)
final class $Local$
	extends java.lang.Object
	implements : Comparator#RAW
	enclosing type : org.example.Example
/*   methods   */
public int compare(java.lang.Object, java.lang.Object) 
(which is what Engine.getDeclarationSignature turns into CompletionProposal.getDeclarationSignature()) or is this a limitation the current approach of "search for MethodBindings matching the CompletionProposal's signature" cannot overcome?
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1414534 is a reply to message #1411823] Sun, 31 August 2014 16:34 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
Mh, "LObject;" looks bogus to me, but I can't think of a reliable way of lookup by name for an unnamed class Sad
Even if you had "MyClass$1" I couldn't think of an easy path for interpreting that name.
LookupEnvironment wouldn't understand it, nor would ReferenceBinding.getMemberType().
It's the AllocationExpression (AST) that owns the type binding.
Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1423996 is a reply to message #1414534] Mon, 15 September 2014 09:53 Go to previous messageGo to next message
phan han is currently offline phan hanFriend
Messages: 5
Registered: September 2014
Location: technology
Junior Member

I meet this case and the same questions are you.
Thank you for sharing information.
Follow-up: I don't have a ReferenceBinding for the declaring class, unfortunately, just one for the actual receiver type. Do I thus have to implement the type hierarchy walking (probing with ReferenceBinding.getMethods() at each level) myself or does there exist a utility method somewhere in JDT that I can use for this?
Thank's!

Ads: Hiện nay https://internetvietnam.net/dang-ky-lap-dat-internet-fpt-tai-quan-3.html là rất cần thiết trong tình hình kinh tế đang phát triển và tình hình an ninh như hiện nay bởi quận 3 là quận trung tâm, là quận tập trung rất nhiều công ty, văn phòng, ngân hàng, showroom.
Quận 3 là một quận thuộc trung tâm thành phố nhu cầu lắp mạng fpt quận 3với những tòa nhà của chính phủ, viện bảo tang, bên cạnh đó là các tòa cao ốc văn phòng, công ty v.v... nhu cầu lắp đặt camera quan sát tại quận 3 ngày càng trở nên phổ biến hơn.

Lợi ích của hệ thống lắp đặt camera quan sát Quận 3

Tăng cường công tác bảo vệ an ninh cho cửa hàng 24/24h.
Phát hiện kịp thời những hành vi cướp đoạt tài sản,hạn chế đến mức thấp nhất những mất mát về tài sản.
Giúp người quản lý lắp đặt camera quận 4 https://internetvietnam.net/dang-ky-lap-dat-internet-fpt-tai-quan-4.html mọi hoạt động của nhân viên, rèn luyện tác phong làm việc nghiêm túc cho nhân viên
Ghi và lưu lại tài liệu để quảng bá thương hiệu.
Tạo sự tin tưởng cho khách hàng lắp mạng fpt quận 4 tới giao dịch,mua sắm.
Có thể giới thiệu với đối tác về cửa hàng của mình trực tuyến qua Internet, giúp tiết kiệm thời gian của mình cũng như đối tác.
Với phương trâm kinh doanh " Tất Cả Vì Sự Hài Lòng Khách Hàng" cộng thêm sự chuyên nghiệp, tận tâm của đội ngũ kỹ thuật, chúng tôi lắp đặt camera quận 5 đã dành được niềm tin yêu của khách hàng mà chúng tôi lắp mạng fpt quận 5 https://internetvietnam.net/dang-ky-lap-dat-internet-fpt-tai-quan-5.html đã hận hạnh được phục vụ trong suốt thời gian qua.
Dưới đây là một số gói lắp đặt camera quan sát giá rẻ mà Camera Tấn Phát ước tính ra cho quý khách hàng tham khảo và chọn lựa:

Khi quý khách có nhu cầu đến tham quan lắp đặt camera quận 6 hay mua sắm tại công ty chúng tôi, bên cạnh việc chiêm ngưỡng những thiết bị công nghệ được trưng bày khá da dạng và phong phú với nhiều mẫu mã chủng loại khác nhau thì chắc hẳn quý vị cũng sẽ thấy nhiều chiếc camera quan sat kết hợp để truyền tín hiệu đang âm thầm dõi mắt, giám sát an ninh, chúng không được phô trương, không được trưng bày đa dạng như bao sản phẩm khác thế nhưng chúng âm thầm bảo vệ mọi thứ tại đây. lắp đặt camera Quận 3 hiện nay có ba loại tiêu cự: cố định, không điều chỉnh được; có thể điều chỉnh lúc lắp đặt; có thể điều chỉnh lúc sử dụng.


Chúc mừng năm mới 2018!

[Updated on: Sat, 03 February 2018 05:46]

Report message to a moderator

Re: From o.e.j.core.CompletionProposal to erased method signature? [message #1424102 is a reply to message #1423996] Mon, 15 September 2014 13:09 Go to previous message
Andreas Sewe is currently offline Andreas SeweFriend
Messages: 111
Registered: June 2013
Senior Member
Quote:
I meet this case and the same questions are you.
Thank you for sharing information.

For what it's worth, here's our ProposalUtils class that came out of this discussion. Hope that helps as well.
Previous Topic:Inserting block for nested if-else
Next Topic:ContentAssist as web service
Goto Forum:
  


Current Time: Fri Apr 19 16:35:57 GMT 2024

Powered by FUDForum. Page generated in 0.03551 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top