Bug 10318 - Feature Request: new Code Assist API required
Summary: Feature Request: new Code Assist API required
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows 2000
: P2 normal (vote)
Target Milestone: 2.0 M4   Edit
Assignee: David Audel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 1569 1723 6089
  Show dependency tree
 
Reported: 2002-02-26 18:01 EST by Darin Wright CLA
Modified: 2002-03-25 06:46 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Darin Wright CLA 2002-02-26 18:01:51 EST
The debugger needs to perform code assist against arbitrary source and binary 
types. For example, in the variables view, when the selected variable is not 
that of the current stack frame, we need to code assist in the context of the 
declared type of the selected variable. This is almost like code assisting in a 
new method in the associated type.

If the selected variable is a source type, we can similate the code assist by 
creating a working copy of the associated compilation unit, but when the type 
is binary we fail, as we are not able to modify the contents of the binary's 
assocaited source buffer with the contents in the variables view. Creating 
working copies for each code assist is also expensive.
Comment 1 Philipe Mulet CLA 2002-02-27 05:36:50 EST
What exactly do you want ? New API on code assist taking a snippet and a type 
(with imports) - note that then no context information would be accessible, 
except fields/methods in the same type.

Or do you want to be able to create a working copy on a classfile, which I 
don't think is much more expensive than what is already involved in 
codeassisting anyway.
Comment 2 Darin Wright CLA 2002-02-27 09:06:59 EST
What we provide is a snippet and a type (with its imports). We do not have a 
position within the type, as we are creating a snippet relative to the entire 
type. Thus, creating a working copy of a classfile might work, but we would 
need to somehow fake a position within the buffer at which to start code 
assisting.

Also, would it be beneficial to be able to code assist relative to a type that 
does not have source. I.e. just get access to members in the type. In this 
case  working copy would not help.

Thus, an API on IType, that just takes a snippet would be the semantics we are 
looking for. I believe we could do any other magic on our end of the completion 
request (if we want to provide access to local variables, etc).
Comment 3 David Audel CLA 2002-03-08 05:16:36 EST
We could define an API receiver an IType, a snippet source and some variable 
information (visible variables like for snippet evaluation).

However this wouldn't work if referring to local types, unless we get the 
entire unit and a snippet insertion position instead. But then, if no source is 
available no context would be available.

Comment 4 David Audel CLA 2002-03-13 12:09:01 EST
I need to know what you want.

a new API on IClassFile to call when the type is binary. And when the type is 
not binary you create a working copie.
or
a new API on ICodeAssist (IClassFile and ICompilationUnit) to call when the 
type is binary or not.

the API should look like this

complete(
   char[] codeSnippet,
   int codeSnippetPosition,
   char[][] localVariableTypeNames,
   char[][] localVariableNames, 
   int[] localVariableModifiers,
   boolean isStatic,
   boolean isConstructorCall,
   ICompletionRequestor requestor
) 
Comment 5 Darin Wright CLA 2002-03-13 13:17:55 EST
I vote for a new Code Assist API to call when a type is binary or not (the 
second suggestion). The API you gave is good - I will add some parameter 
desciprtions to make sure I understand them:

complete(
   char[] codeSnippet,
   int codeSnippetPosition,
   char[][] localVariableTypeNames,
   char[][] localVariableNames, 
   int[] localVariableModifiers,
   boolean isStatic,
   boolean isConstructorCall,
   ICompletionRequestor requestor
) 

@param codeSnippet - the complete expression that the user has typed in
@param codeSnippetPosition - the position with in 'codeSnippet' where the user 
is performing code assist
@param localVariableTypesNames - an array (possibly empty) of fully qualified 
type names of local variables visible at the current scope
@param localVariableNames - an array (possibly empty) of local variable names 
that are visible at the current scope
@param localVariableModifiers - an array (possible empty) of modifiers for 
local variables (generally, we cannot provide this info since JDI does not tell 
us if a local if final - but this should be provided for completeness)
@param isStatic - whether the current scope is in a static context
@param isConsuctorCall - whether the current scope is within a constructor (why 
do you need this?)
@param requestor - the object to report results to

How does this behave with local types? Does it just work, or do you need more 
info?
Comment 6 David Audel CLA 2002-03-14 06:02:16 EST
Parameter 'isConstructorCall' is not necessary.

Comment 7 David Audel CLA 2002-03-14 06:41:53 EST
There are 3 possible context for completion :
1) a compilation unit
   if a position to insert snippet in source are given,then paramaters are not 
useful and we can find local type for free.
2) a class file with attached source
   this case is like the first case.
3) a class file without source
   in this case parameters are necessary and we can not find local type. But do 
you need to find local type if you do not have source ?

So i suggest a new API :
complete(
   char[] codeSnippet,
   int codeSnippetInsertionPosition,  // <-------- new parameter
   int codeSnippetPosition,
   char[][] localVariableTypeNames,
   char[][] localVariableNames, 
   int[] localVariableModifiers,
   boolean isStatic,
   ICompletionRequestor requestor
) 

@param codeSnippetInsertionPosition- the position with in source where the 
snippet is inserted.

'codeSnippetInsertionPosition' is used only if we can find source 
and 'localVariableTypeNames','localVariableNames','localVariableModifiers', 'isS
tatic' are used only if we can not find source.



Comment 8 Darin Wright CLA 2002-03-14 15:17:30 EST
(1) I would like to be able to specify -1 for codesnippet insertion point if we 
do not have a location. That way I can code assist relative to a type B, and 
provide access to locals in the stack frame, that do not exist in B (because we 
are in a stack frame context of A, and B is the type of an instance var of A).

(2) How precise to I have to be on the "codeSnippetPosition". I think the best 
I can do is give the offset of the beginning of the line that has not yet been 
executed.

(3) We could know we are in a local type even if there is no source (based on 
the receiving type name, like A$1).
Comment 9 Philipe Mulet CLA 2002-03-15 04:51:24 EST
Re(1) - sounds evil. You will get a combination of things which might be a 
little disturbing when trying to evaluate the snippet in the end. You could 
reach by simple name, variables defined in both stack frame. Is this what you 
really want to support at runtime ?

Re(2) - sounds good enough.

Re(3) - in order to figure inner types in the source, we need a source 
position, or a handle to the binary type (which is what you have in your hands 
I presume). The type name does help us much, we would need to find out how the 
compiler (us?) did choose to name it, however with the file debug attributes, 
we can easily figure a snippet insertion position I guess. But again, this is 
the information you already have in your hands, see(2).
Comment 10 Darin Wright CLA 2002-03-15 09:00:17 EST
(1) Yes, a little evil, and we may not do this. However, the reason I do not 
want to have to specify a code snippet insertion point, is because I do not 
always know what it is. If I am in the variables view, and have selected an 
instance var, which is a Vector, I am code assisting against Vector, but not at 
any particular position.

(2) If I know a position, I will give it to you

(3)I can likely resolve the handle for the inner type. Again, I may not have a 
position - what if it were an argument to another method in another type? Then 
I was code assisting against the argument?
Comment 11 David Audel CLA 2002-03-19 06:52:04 EST
ICodeAssist is not the right place to put this API, because several classes can 
be in the same compilation unit.
IType is a better place
Comment 12 David Audel CLA 2002-03-19 08:57:50 EST
New API added on org.eclipse.jdt.core.IType.

/**
 * Do code completion inside a code snippet in the context of the current type.
 * 
 * If the type can access to his source code and the insertion position is 
valid,
 * then completion is performed againt source. Otherwise the completion is 
performed
 * against type structure and given locals variables.
 * 
 * @param snippet the code snippet
 * @param insertion the position with in source where the snippet
 * is inserted. This position must not be in comments.
 * A possible value is -1, if the position is not known.
 * @param position the position with in snippet where the user 
 * is performing code assist.
 * @param localVariableTypesNames an array (possibly empty) of fully qualified 
 * type names of local variables visible at the current scope
 * @param localVariableNames an array (possibly empty) of local variable names 
 * that are visible at the current scope
 * @param localVariableModifiers an array (possible empty) of modifiers for 
 * local variables
 * @param isStatic whether the current scope is in a static context
 * @param requestor the completion requestor
 */
void codeComplete(
   char[] snippet, 
   int insertion, 
   int position, 
   char[][] localVariableTypeNames, 
   char[][] localVariableNames, 
   int[] localVariableModifiers, 
   boolean isStatic, 
   ICompletionRequestor requestor
) throws JavaModelException;
	

Fixed.
Comment 13 Darin Swanson CLA 2002-03-22 15:44:50 EST
I am making use of this new api in the code assist of Display view.
I keep getting a method #akeMethod showing up in the list?
Comment 14 David Audel CLA 2002-03-25 06:46:30 EST
I replace my fake method by an initializer to solve this problem.