Java Element Deltas

Last revised 12:00 Thursday September 6, 2001

Original work item: "IJavaElementDelta should carry information about marker changes (ProblemMarkers)."

Markers and Java Elements

The workspace allows markers to be associated with resources. The Java compiler associates Java problem markers with Java source files; these markers locate the error within the compilation unit by source character position.

The Java model does not directly support markers on Java elements. It does provide a means (ICompilationUnit.getElementAt) for mapping from a source character position within a compilation unit resource to the nearest enclosing Java element. Since all Java problem markers carry a source character position, any Java problem marker can be mapped to the nearest enclosing Java element. In most cases, this element will be a fine-grained Java element corresponding to a declaration of a Java method, field, type, or import. In the worst case, it maps to the compilation unit element itself. Thus it is always possible in principle to associate markers with Java elements.

The Java UI visually annotates Java elements that have problems (with a red X).

The cost of mapping from a marker position to a fine-grained Java element requires opening (and parsing) the compilation unit. Once opened, additional markers within the same compilation unit can be mapped with negligible additional cost.

Java Element Deltas

Unlike workspace resource deltas, Java element deltas do not currently include information about marker changes.

The Java UI needs to maintain the visual annotations on Java elements that have problems.

There are three kinds of Java element deltas issued:

  1. By the Java model when IWorkingCopy.commit is called to save a compilation unit working copy.
  2. By the Java model when IWorkingCopy.reconcile is called during editing.
  3. By the Java model in response to notification of a workspace resource delta affecting a compilation unit resource.

The first two kinds of Java element delta are always issued against fine-grained Java elements. The previous fine-grained structure of the compilation unit is compared to the current fine-grained structure. These deltas are recognizable as kind CHANGED at the compilation unit level with F_CHILDREN flag set and F_CONTENT flag not set.

The last kind of Java element delta is never fine-grained; it goes no finer than the compilation unit element itself. This is because the fine-grained structure of the previous state of the compilation unit is not available (the Java model does not necessarily have a record of the previous structure (although it might be in an internal cache), and cannot compute it since it does not a copy of the previous state of the compilation unit). These deltas are recognizable as kind CHANGED at the compilation unit level with F_CHILDREN flag not set and with F_CONTENT flag set.

Markers and Java Element Deltas

Java problems markers on Java compilation units originate when the Java builder is called. These markers are associated with Java compilation unit files, and come to the attention of the Java model via a problem delta associated with the resource delta that follows the build. The Java builder only deletes or adds Java problem markers; it never changes existing ones. The Java builder does not decorate Java problem markers with information other than the source character position.

(IWorkingCopy.reconcile also returns a set of tranisent markers.)

When the user opens a compilation unit, the Java editor creates and locates visual markers corresponding to the Java problem markers. These visual markers are sticky, and move around as the text is edited.

When the user navigates into an already open compilatation unit from a problem marker in the Tasks view, the Java editor automatically adjusts the positions to account for recent edits.

When the Java editor saves a compilation unit, it permanently adjusts the source positions of Java problem markers associated with the corresponding compilation unit. This is done because the next build may be a ways off and these markers show up in the Tasks view (the Java editor might be closed).

Java element deltas also carry information about non-Java resources; this is surfaced by IJavaElementDelta.getResourceDeltas. This works as follows: when a non-Java resource is affected, the corresponding resource delta is exposed on the nearest parent Java element. For files directly under the project, the resource delta will be associated with Java element delta for the IJavaProject; for files sitting in the same folder as a Java source file, the resource delta will be associated with Java element delta for the IPackageFragment; for files sitting inside a source folder but not in any package fragment, the resource delta will be associated with Java element delta for the IPackageFragmentRoot (this includes the case where the project itself is a package fragment root. Thus the IJavaElementDelta.getResourceDeltas mechanism is only of use for discovering non-resource deltas; it is not useful for discovering marker changes to resources corresponding to Java elements.

Thus the only way a client can find out about most marker deltas is to register its own resource change listener with the workspace. Since the client would still need to register a Java model change listener, having to do raises the question of relative ordering of these two notifications (there is no guarantee which will comes first).

Proposal: Expose corresponding resource deltas on Java element delta

The proposed change is to improve the Java element delta to expose the corresponding resource deltas whenever they are available. This would be done via the following new method on IJavaElementDelta:

/**
 * Returns the workspace resource delta for the resource that corresponds directly to the
 * Java element, or <code>null</code> if either there is no resource that corresponds
 * to the Java element, or there is a corresponding resource but there is no resource delta
 * for it.
 * <p>
 * Note that a Java element delta that does not arise from a workspace resource delta will always
 * return <code>null</code>.
 * </p>
 * <p>
 * If the result is non-<code>null</code>, then
 * <code>getCorrespondingResourceDelta().getResource()</code> is the same resource as
 * <code>getElement().getCorrespondingResource()</code>.
 * </p>
 *
 * @return the corresponding workspace resource delta, or <code>null</code> if not applicable or none
 */
public IResourceDelta getCorrespondingResourceDelta();

Resource deltas will be available when the Java element delta results from the Java model receiving a resource change notification. When this happens, the resource delta for the corresponding will be made available from the Java element delta for the Java element:

Note that the proposed API change would not break compatibility with Eclipse 1.0. It adds a new method to an interface that is not intended to be implemented by clients.

With the proposed change, a client of the Java model would be able to discover marker changes to both Java and non-Java resource by registering for Java model changes and composing IJavaElementDelta.getCorrespondingResourceDelta and IResourceDelta.getMarkerDeltas. These marker changes will only be present on Java element deltas stemming from workspace resource deltas. They are no marker deltas associated with fine-grained Java element deltas arising from working copy reconciliation or saving (no markers have changes).

Other things we considered:

Document History