Skip to content

Affected source files lookup algorithm

homedirectory edited this page Nov 25, 2022 · 3 revisions

Affected source files lookup algorithm

Abstract

This document describes a part of incremental compilation in Eclipse IDE - the lookup algorithm of affected source files, which occurs whenever a type being compiled has structural changes.

Whenever a type is structurally changed, the incremental compiler will perform a lookup for affected source files. A source file is considered to be affected if it contains a definition of a type that references the structurally changed type.

This reference is searched in the type's dependency info, which includes the following:

  • Imported types (even unused ones) (static imports count too)
  • Supertypes (the whole hierarchy)
  • Type parameters & type arguments
  • Declared types of its members (e.g. field types)
  • Return and parameter types of methods
  • Javadoc links
  • var keyword
  • .class literals

Also see special case for multiple types with same simple name.


Javadoc

Javadoc reference is considered to have the following form:

{@link NAME}

Where NAME is either a qualified or simple name of a referenced type. Plain uses of NAME (i.e. without {@link }) don't count as javadoc references.

The following algorithm description assumes that no import statements of referenced types are present. That is, the only reference contained is the one in the javadoc.

The lookup algorithm behaves slightly differently when simple names are used instead of qualified names, so both cases need to be described.

  1. {@link QUALIFIED_NAME} will mark this type as affected by changes to the referenced type.
  2. {@link SIMPLE_NAME} will marks this type as affected only if it is located in a package that is a sub-package of the referenced type.

For example, consider the following package hierarchy:

top
|- a
   |- Ref.java
   |- Qual.java
   |- Simple.java
   |- b
      |- Ref.java
      |- Qual.java
      |- Simple.java
|- c
   |- Qual.java
   |- Simple.java

Context:

  • All types named Qual contain {@link a.Ref}.
  • All types named Simple contain {@link Ref}.
  • a.b.Ref was included for the sake of simulating a case when there are multiple types with same simple name. It is not referenced by its qualified name by any of the Qual and Simple types.

Affected sources of a.Ref include:

  • a.Qual, a.Simple // same package
  • a.b.Ref // has the same simple name
  • a.b.Qual, a.b.Simple // sub-package
  • c.Qual // different package branch

Affected sources of a.b.Ref include:

  • a.b.Qual, a.b.Simple // same package

var keyword

Usage of var keyword is a special case, since it works without having an import statement for the type that var stands for. Solely having a reference of type var will not cause the source to be marked as affected. However, any reference to the underlying type members or methods will.

Example method body of a type that would not be affected:

var ref = RefFactory.getRef();

Note that such class would not contain Ref anywhere, which is the type that var stands for. Hence, it would not be considered affected by changes to Ref.

Example method body of a type that would be affected:

var ref = RefFactory.getRef();
String s = ref.name; // reference counts

If after this you are questsioning whether this would be considered affected:

Ref ref = RefFactory.getRef();

The answer is yes, even though there is no usage of members of Ref.


Types with same simple name

The lookup algorithm will always look for dependents of the type being compiled in its package. It might find sources in that package that reference a different type, but which has the sample simple name. Such source file will be marked as affected, even though it contains no references to the type being compiled.

For example, consider the following package hierarchy:

top
|- a
   |- Ref.java
   |- User.java
|- Ref.java

User has the following contents:

package a;
import a.Ref;

class User {
  void work() {
    Ref ref = new Ref();
  }
}

Structural changes to Ref will cause a.User to be marked as effected, even though a.User doesn't contain any references to Ref, but to a.Ref instead.

Clone this wiki locally