Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 500012

Summary: "empty package" is an invention not backed by JLS
Product: [Eclipse Project] JDT Reporter: Stephan Herrmann <stephan.herrmann>
Component: UIAssignee: JDT-UI-Inbox <jdt-ui-inbox>
Status: RESOLVED WORKSFORME QA Contact:
Severity: minor    
Priority: P3 CC: atg.sleepless, jgangemi, markus.kell.r
Version: 4.7   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:

Description Stephan Herrmann CLA 2016-08-19 18:14:09 EDT
Discussion in bug 495598 (with backdrops to bug 163807) highlights that JLS doesn't support a notion of packages without compilation units inside.

Strictly speaking this could mean that JDT should never use an "empty package" icon, but use the folder icon in its stead. Similar for textual references to "empty package" like in preferences.

OTOH, I know about the convenience to tell from the icon, whether a folder is on the classpath or not.

I just wonder if JDT's visualization has contributed to mis-educating people (including compiler writers) to believe that "empty packages" exist under the rule of JLS.

This has been discussed ages ago in bug 13702, but I believe JLS has changed since those days.
Comment 1 Stephan Herrmann CLA 2016-08-19 18:19:45 EDT
For you convenience:

From JLS 7.4.3:

 "A package is observable if and only if either:

  * A compilation unit containing a declaration of the package is observable (§7.3).

  * A subpackage of the package is observable."

(Where "subpackage" is a misleading notions in its own right, but that would be a different story).

Ergo: any "empty package" is not observable (whatever that means).
Comment 2 Anton Tanasenko CLA 2016-08-20 03:55:37 EDT
I think from an average developer's standpoint of view, JDT's package/empty package icons are an indication that something's on a classpath. IIRC, a folder structure is shown under source folder in case if something is excluded from the classpath.

So, personally, I think the empty package should stay as it is. Though certain corner cases it is not considered to be a package (such as deciding whether you can create a same-named class), this should be an IDE implementation concern. Throwing this confusing notion in the face of the user might only make things worse.
Comment 3 Stephan Herrmann CLA 2016-08-20 10:06:01 EDT
(In reply to Anton Tanasenko from comment #2)
> I think from an average developer's standpoint of view, JDT's package/empty
> package icons are an indication that something's on a classpath. IIRC, a
> folder structure is shown under source folder in case if something is
> excluded from the classpath.
> 
> So, personally, I think the empty package should stay as it is. Though
> certain corner cases it is not considered to be a package (such as deciding
> whether you can create a same-named class), this should be an IDE
> implementation concern. Throwing this confusing notion in the face of the
> user might only make things worse.

I mostly agree, except for one: it's not an implementation concern we are hiding, but a property of the language Java as per JLS. The corner cases show: we are not able / allowed to *fully* hide this detail of the Java language.

Still leaving things as they are is perhaps a valid (though not perfect) option.
Comment 4 Anton Tanasenko CLA 2016-08-20 10:36:25 EDT
(In reply to Stephan Herrmann from comment #3)
> I mostly agree, except for one: it's not an implementation concern we are
> hiding, but a property of the language Java as per JLS. The corner cases
> show: we are not able / allowed to *fully* hide this detail of the Java
> language.

I meant that the whole observable/non-observable thing only affects compilator writers. I really doubt that anyone in the app development world really creates same-named classes and packages (observable ones), especially when taking naming conventions into account. Jenkins/hudson does bring it a step closer, but such (non)packages are strictly for resources, so it doesn't cross the line.

OTOH, it looks like JDT's 'Empty package' equals JLS's 'non-observable package' for all intents and purposes, if I'm not missing any cases.
So you're not hiding it per se, you're just naming it differently :)
Comment 5 Markus Keller CLA 2016-09-14 14:04:57 EDT
I don't think the JLS8 can be taken to court about that. There are more contradictions:

In addition to comment 1, there's:

- §6.3:
"The package java is always in scope"

- §6.5.3.2 Qualified Package Names:
"If a package name is of the form Q.Id, then Q must also be a package name. The
package name Q.Id names a package that is the member named Id within the
package named by Q."

- §7:
"A package consists of a number of compilation units (§7.3)."

- §7.1 (non-normative):
"For example, in the Java SE platform API:
• The package java has subpackages awt, applet, io, lang, net, and util, but no
compilation units."

- §7.3:
"All the compilation units of the predefined package java and its subpackages lang and io are always observable."

- §7.4.3:
"The packages java, java.lang, and java.io are always observable."

=> "java" is repeatedly called a package although it doesn't contain any compilation units. We have to conclude that empty *parent* packages like "java" or "org" are backed by the JLS8.

Only empty *leaf* packages remain disputable. Yes, they are not observable. But the existence of compilation units does not seem to be a prerequisite for being a package.

Note that the "existence" of compilation units is already ill-defined. §7.3 says:
"CompilationUnit is the goal symbol (§2.1) for the syntactic grammar (§2.3) of Java programs."
Note that it doesn't talk about .java files. Since all parts of the CompilationUnit production are optional, even an empty .java file would be a compilation unit. Or, since JDT defines the host system, we can declare an empty folder on the file system as the container of an empty compilation unit.

Since an "empty package" is a necessary UI metaphor for a consistent story as outlined in bug 13702, I don't see us changing that.
Comment 6 Stephan Herrmann CLA 2016-09-14 14:29:21 EDT
Thanks for the research.

Even the "simplest" concept gets confusing in a language like Java ...

I don't really have a better story for visualization, so I'm fine with WORKSFORME.


(In reply to Anton Tanasenko from comment #4)
> ... it looks like JDT's 'Empty package' equals JLS's 'non-observable
> package' for all intents and purposes, 

Sounds like a fair description (except for the package 'java').


Wrt to bug 495598 we will have to say that conflicts only arise between a *non-empty* package and a class, or when an import resolves to a *non-empty* package.