Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jdt-core-dev] 36888 - closing the gap between compilation units and working copies

I agree to better encapsulate the need for expressing clients (like search
engine), but in other cases where the starting handles isn't client
specific, then we wanted to be able to provide the proper context. Think of
a type hierarchy where the focus is the primary one, but some of the
subtypes are owned by a client.

Maybe we shouldn't worry about these situations which would simplify the
story.



|---------+------------------------------>
|         |           Martin             |
|         |           Aeschlimann/Zurich/|
|         |           IBM@IBMCH          |
|         |           Sent by:           |
|         |           jdt-core-dev-admin@|
|         |           eclipse.org        |
|         |                              |
|         |                              |
|         |           05/26/2003 01:42 PM|
|         |           Please respond to  |
|         |           jdt-core-dev       |
|         |                              |
|---------+------------------------------>
  >----------------------------------------------------------------------------------------------------------------------|
  |                                                                                                                      |
  |       To:       jdt-core-dev@xxxxxxxxxxx                                                                             |
  |       cc:                                                                                                            |
  |       Subject:  Re: [jdt-core-dev] 36888 - closing the gap between compilation units and working copies              |
  |                                                                                                                      |
  >----------------------------------------------------------------------------------------------------------------------|





Why not forcing the client (refactoring) to first get the unit with the
refactoring's owner? E.g. that would be JavaCore.create(primaryCu.getPath
(), refactoringOwner);
or add a method on ICompilationUnit:
getCorresponding(ICompilationUnitOwner)
Having the new CompilationUnit handle (now with the refactoring owner),
parseCompilationUnit(ICompilationUnit unit, boolean resolveBindings) can be
used so the owner is given by the ICompilationUnit.

This would avoid several methods from being duplicated with the additional
argument and also clearly separates the process of how to get a client's
CU.
You also avoid handling problems like in
IType.newTypeHierarchy(ICompilationUnitOwner owner, IProgressMonitor
monitor)
when the type does not exist in the owners world.

I was thinking that it might be a good idea to add the factory methods to
ICompilationUnitOwner
JavaCore.create(..) -> owner.create
JavaCore.newRegion() ->  owner.newRegion

To avoid adding parameters to methods in SearchEngine it would make sense
to create a SearchEngine for a own:
   new SearchEngine(compilationUnitOwner)

So from the list before, the methods that need a new parameter would be
reduced to:
org.eclipse.jdt.core.jdom.DOMFactory
+ DOMFactory()

org.eclipse.jdt.core.CorrectionEngine
+ CorrectionEngine(Map setting)
(note: Could be deprecated, we don't use it for quick assist)


org.eclipse.jdt.core.IJavaProject
+ findElement(IPath path)
+ findType(String packageName, String typeQualifiedName)
+ findType(String fullyQualifiedName)
+ newEvaluationContext()
+ newTypeHierarchy(IType type, IRegion region, IProgressMonitor monitor)
(note: Could be deprecated, client can use IType.newTypeHierarchy)

Martin


                                                                           
 Philippe P                                                                
 Mulet/France/IBM@IBMFR                                                    
 Sent by:                                                               To 
 jdt-core-dev-admin@ecli         jdt-core-dev@xxxxxxxxxxx                  
 pse.org                                                                cc 
                                                                           
                                                                   Subject 
 21.05.2003 13:32                Re: [jdt-core-dev] 36888 - closing the    
                                 gap between compilation units and working 
                                 copies                                    
    Please respond to                                                      
  jdt-core-dev@eclipse.o                                                   
            rg                                                             
                                                                           
                                                                           
                                                                           
                                                                           






Just to clarify. Some of the APIs listed below could implicitly infer the
client layer from the current unit/type information. For instance,
AST.parseCompilationUnit(...) could parse and resolve bindings in the
context of the parsed unit client. However, this would not work if
attempting to parse a primary unit in the context of refactoring client,
where only referenced units are manipulated in working copies.

Thus we have to consider that the mixed world may occur, and an explicit
client will indicate which viewpoint is used.




                     Jerome

                     Lanneluc/France/IBM        To:
jdt-core-dev@xxxxxxxxxxx

                     @IBMFR                     cc:

                     Sent by:                   Subject:  Re:
[jdt-core-dev] 36888 - closing the gap between compilation units and
working copies
                     jdt-core-dev-admin@

                     eclipse.org



                     05/21/2003 01:14 PM

                     Please respond to

                     jdt-core-dev








The following APIs would need to be duplicated so that a client can be
passed in:

org.eclipse.jdt.core.dom.AST
+ parseCompilationUnit(ICompilationUnit unit, boolean resolveBindings)
+ parseCompilationUnit(IClassFile classFile, boolean resolveBindings)
+ parseCompilationUnit(ICompilationUnit unit, boolean resolveBindings)

org.eclipse.jdt.core.jdom.DOMFactory
+ DOMFactory()

org.eclipse.jdt.core.CorrectionEngine
+ CorrectionEngine(Map setting)

org.eclipse.jdt.core.ICodeAssist
+ codeComplete(int offset, ICodeCompletionRequestor requestor)
+ codeComplete(int offset, ICompletionRequestor requestor)
+ codeSelect(int offset, int length)

org.eclipse.jdt.core.IJavaProject
+ findElement(IPath path)
+ findType(String packageName, String typeQualifiedName)
+ findType(String fullyQualifiedName)
+ newEvaluationContext()
+ newTypeHierarchy(IRegion region, IProgressMonitor monitor)
+ newTypeHierarchy(IType type, IRegion region, IProgressMonitor monitor)

org.eclipse.jdt.core.IPackageFragment
+ getCompilationUnit(String name)
+ getCompilationUnits()

org.eclipse.jdt.core.IType
+ codeComplete(
     char[] snippet,
     int insertion,
     nt position,
     char[][] localVariableTypeNames,
     char[][] localVariableNames,
     int[] localVariableModifiers,
     boolean isStatic,
     ICompletionRequestor requestor)
+ loadTypeHierachy(InputStream input, IProgressMonitor monitor)
+ newSupertypeHierarchy(IProgressMonitor monitor)
+ newSupertypeHierarchy(IWorkingCopy[] workingCopies, IProgressMonitor
monitor)
+ newTypeHierarchy(IJavaProject project, IProgressMonitor monitor)
+ newTypeHierarchy(IProgressMonitor monitor)
+ resolveType(String typeName)

org.eclipse.jdt.core.IWorkingCopy
+ reconcile(boolean forceProblemDetection, IProgressMonitor monitor)

org.eclipse.jdt.core.JavaCore
+ createCompilationUnitFrom(IFile file)

org.eclipse.jdt.core.search.SearchEngine
+ createHierarchyScope(IType type)
+ search(
     IWorkspace workspace,
     ISearchPattern searchPattern,
     IJavaSearchScope scope,
     IJavaSearchResultCollector resultCollector)
+ search(
     IWorkspace workspace,
     IJavaElement element,
     int limitTo,
     IJavaSearchScope scope,
     IJavaSearchResultCollector resultCollector)
+ search(
     IWorkspace workspace,
     String patternString,
     int searchFor,
     int limitTo,
     IJavaSearchScope scope,
     IJavaSearchResultCollector resultCollector)
+ searchDeclarationsOfAccessedFields(
     IWorkspace workspace,
     IJavaElement enclosingElement,
     IJavaSearchResultCollector resultCollector)
+ searchDeclarationsOfReferencedTypes(
     IWorkspace workspace,
     IJavaElement enclosingElement,
     IJavaSearchResultCollector resultCollector)
+ searchDeclarationsOfSentMessages(
     IWorkspace workspace,
     IJavaElement enclosingElement,
     IJavaSearchResultCollector resultCollector)




|---------+------------------------------>
|         |           Philippe P         |
|         |           Mulet/France/IBM@IB|
|         |           MFR                |
|         |           Sent by:           |
|         |           jdt-core-dev-admin@|
|         |           eclipse.org        |
|         |                              |
|         |                              |
|         |           05/20/2003 06:55 PM|
|         |           Please respond to  |
|         |           jdt-core-dev       |
|         |                              |
|---------+------------------------------>
 >
------------------------------------------------------------------------------------------------------------------------|


 |
|
 |       To:       jdt-core-dev@xxxxxxxxxxx
|
 |       cc:
|
 |       Subject:  Re: [jdt-core-dev] 36888 - closing the gap between
compilation units and working copies                |
 |
|
 >
------------------------------------------------------------------------------------------------------------------------|






The notion of an implicit working copy owner allowing to work transparently
in the client layer (where working copies automatically take precedence
over units) is introducing a risk for layer collisions. For instance, some
3rd party code could run inside a callback, where it would be embedded
inside some other client activity. This would easily cause issues, since
the 3rd party code would be treated as running as the active client (if
any). This could be quite deadly for JDT/UI callbacks which could be
activated in various ways, and since JDT/UI activity wouldn't be wrapped
inside client runnables, then JDT/UI could be fairly endangered.

Since we don't want to build a chain as weak as its weakest link portion,
we are now considering passing an explicit client through our APIs. By
default, existing APIs would be kept and denoting the primary world (where
JDT/UI would live), and new APIs would allow to specify a custom client for
the duration of the action.

We are currently exploring how much damage this creates inside our
component, and will post on this topic once we have gathered more
information.

----- Forwarded by Philippe P Mulet/France/IBM on 05/20/2003 06:48 PM -----

                     Philippe P Mulet

                                              To:
jdt-core-dev@xxxxxxxxxxx

                     05/20/2003 11:55         cc:

                     AM                       From:    Philippe P
Mulet/France/IBM@IBMFR

                                              Subject: Re: [jdt-core-dev]
36888 - closing the gap between compilation units and working copies
                                              (Document link: Philippe P
Mulet)





See below <PM></PM>, also added some indentations.




                     Dirk

                     Baeumer/Zurich/IBM@        To:
jdt-core-dev@xxxxxxxxxxx

                     IBMCH                      cc:

                     Sent by:                   Subject:  Re:
[jdt-core-dev] 36888 - closing the gap between compilation units and
working copies
                     jdt-core-dev-admin@

                     eclipse.org



                     05/19/2003 06:31 PM

                     Please respond to

                     jdt-core-dev











See my comments below

<DB>
</DB>

Dirk




            Philippe P
            Mulet/France/IBM@
            IBMFR                                                      To
            Sent by:                  jdt-core-dev@xxxxxxxxxxx
            jdt-core-dev-admi                                          cc
            n@xxxxxxxxxxx
                                                                  Subject
                                      [jdt-core-dev] 36888 - closing the
            05/19/2003 05:19          gap between compilation units and
            PM                        working copies


            Please respond to
            jdt-core-dev@ecli
                 pse.org






Please answer to jdt-core-dev@xxxxxxxxxxx.

This work item is intending to ease manipulating of working copies for
clients. As of today, there are currently two typical users:
     long lifecycle: editor. As long as the editor is openend, a working
     copy is kept active, and will be shown in various views, and be
     updated as changes are notified. In particular, the package view must
     handle the lazy creation of working copies as it shows units which
     can then be opened in editor. In order for several editors (opened in
     different perspective on the same unit) to share their contents, we
     support a notion of shared working copies (we will answer back the
     existing one if already active).
     short lifecycle: refactoring. A working copy is created for a short
     duration, a few changes are performed, then it is discarded. No need
     to react to changes in the meantime, but need to be able to have
     changes performed simultaneously amongst several units to be aware of
     each other.

Goal
+  Provide a way to edit directly a compilation unit. Since working copies
  are used to update units, a compilation unit should implicitly provide a
  built-in working copy used for the Java editor. In practice, a handle
  onto a compilation unit would remain the same whether it is reflecting a
  file or an editor contents.

+  Other shared working copies should implicitly be aware of each other.
  For instance, when refactoring performs a change across several units at
  once, these modification must be visible to other refactored units:
  search, name resolution, etc... In particular, the built-in working
  copies associated with units should be aware of each other.

Proposal
+  ICompilationUnit is enrished to support built-in working copy behavior,
  and thus working copy behavior is directly spec'ed there.
  A compilation unit handle reflects the filesystem until it is toggled
  into working mode (#becomeWorkingCopy()) and until it exits this mode
  (#discardWorkingCopy()).

+  Other clients needing working copies would register for an operation
  relative to this specific client (WorkingCopyOwner). In order to
  register a client working copy owner, a WorkingCopyOwner#run(Runnable)
  action would be invoked, and for the duration of this operation, all
  subsequent working copies created by ICompilationUnit#getWorkingCopy()
  would be owned by this very client. These would automatically be aware
  of each other and for this very client only; i.e., during this client
  operation, its owned working copies would automatically take precedence
  over the underlying resource (even if already opened in editor).

  This is roughly what can be achieved today using shared working copies,
  but the notion of client is currently explicit and only a few APIs are
  able to support these shared working copies to achieve awareness (type
  hierarchy and search). With the notion of an implicitly registered
  client, all APIs would be untouched, and implicitely give precedence to
  this client specific working copies.

API implications for 2.1 clients
+  Units open in editor would take precedence over the filesystem. This is
  likely the behavior they need anyway. Thus when navigating inside a unit
  element, they may now see unsaved changes.
  IWorkingCopy would be deleted, since no longer needed as a separate
  entity (no more gap).

+  Shared working copies would be the default behavior. If needing more
  than one working copy on the same unit at once, then a different client
  should be registered. Thus the support for arbitrary individual working
  copies would disappear.

Example: Refactoring wants to rename a field declaration
+  It performs a search for references to this field, and finds matches in
  term of true compilation units. Note that since these compilation units
  have built-in working copy support, these matches could reflect unsaved
  editor contents.
+  Refactoring decides to update these references, and creates working
  copies for these so as to edit them.
+  From thereon, all resolution actions would implicitly consider these
  refactoring working copies in place of the original units.
+  However, if performing a further reference search outside these
  refactoring working copies, a regular unit handle would be returned, and
  it would need to be converted into a working copy again before being
  edited as the refactoring client.
+  At any time, using IPackageFragment#getCompilationUnit would answer back
  the original unit (either associated file contents or editor contents).

<DB>
 Basically this means that we don't get a client world for packages and
 projects. Is this correct? From refactoring we have the need that we
 are able to create a new class in a package (without having the CU on
 disk). This new compilation unit should be consider by operations like
 search, type hierarchy, AST building, type bindings, ...

 What happens if I call IPackageFragement#getCompilationUnit() in this
 case. Will the new CU be part of the result ?

 Additional questions are:
   - how can we delete a CU from a package in the refactoring world ?

   - if the package fragment always returns the original unit will
     becomesWorkingCopy always convert the CU into the same refactoring
     working copy as long as there exists one?
</DB>
<PM>
 Initially our intent was that IPackageFragment#getCompilationUnit() would
 always answer primary client units (file or editor contents). But indeed
for
 consistency reason, it should also give precedence to current client
owned
 working copies. The rational for our initial reserve was that we were
afraid
 of some client still being inadvertently active while some callback is
invoking
 code from JDT/UI which would now implicitly access the active client
layer by
 mistake. However, other type of actions (search, type hierarchies,
etc...) would
 also cause this to happen. So in a consistent manner,
IPackageFragment#getCompilationUnit()
 should also find existing owned working copies as well.

 When it comes to deleting virtually, this could be achieved by marking
working copies as such,
 we currently do not support this, but could add it. Additions would be
already supported, since
 working copies can be created on not yet existing resources.

 If a unit was already a working copy, then yes likely, #becomeWorkingCopy
would answer back the same
 one, though you could check #isWorkingCopy() prior to doing it.
BecomeWorkingCopy is rather meant for the
 primary world only to achieve handle stability.

 Also note that there would be no support for creating working copies of
package fragments.
</PM>

Question/Answers
Q: How can I distinguish in between a filesystem unit versus an editor
  working copy ?
A: The handle remains stable, but it can be asked whether it is a working
  copy or not (#isWorkingCopy).
Q: How can I get the contents of the original compilation unit, once it is
  open in editor ?
  Use resource API to read its contents.
Q: What happens if a unit opened in editor is modified on the filesystem ?
A: Once a compilation unit is opened in editor, the editor changes will
  take precedence over the filesystem resource changes. In practice,
  unless listening to resource changes, there will no longer be a way to
  notice these, since the editor contents is implicitly hiding the file
  contents.
Q: Can client code be nested in each other ?
A: Yes, registering a client would support nesting. Only the most specific
  client would be active at once.
Q: Is becomeWorkingCopy()/discardWorkingCopy() a good name for the
  activating the built-in working copy ?
A: Unclear. Maybe it should rather clearly state that this is a reserved
  working copy for editors ? Suggestions are welcome.
Q: Would the builder see the unsaved editor contents through the built-in
  working copy support ?
A: No, this would only be an artifact for the Java model tools (search,
  codeassist, formatter, dom, eval) which aren't used by the Java builder.






_______________________________________________
jdt-core-dev mailing list
jdt-core-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/jdt-core-dev


_______________________________________________
jdt-core-dev mailing list
jdt-core-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/jdt-core-dev






_______________________________________________
jdt-core-dev mailing list
jdt-core-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/jdt-core-dev





_______________________________________________
jdt-core-dev mailing list
jdt-core-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/jdt-core-dev





_______________________________________________
jdt-core-dev mailing list
jdt-core-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/jdt-core-dev







Back to the top