Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JDK-8315458 Implement JEP 463: Implicitly Declared Classes and Instance Main Method (Second Preview) #16461

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
4a34a4e
Implicit classes and instance main methods
JimLaskey Oct 31, 2023
a07b8d2
Remove obsolete tests
JimLaskey Nov 1, 2023
b98e40f
Remove .orig files
JimLaskey Nov 2, 2023
2bb3047
Remove MANDATED flag from implicit classes
JimLaskey Nov 2, 2023
05945eb
Update JEP number in PreviewFeature
JimLaskey Nov 2, 2023
edbe208
Don't store main method info globally. Use addition calls to fetch info.
JimLaskey Nov 2, 2023
7c92e85
Revised implicit class test
JimLaskey Nov 2, 2023
afdd078
Changes recommended by Jan
JimLaskey Nov 2, 2023
742fed7
Requested corrections
JimLaskey Nov 2, 2023
72033bc
Remove unnamed classes from examples.not-yet.txt
JimLaskey Nov 2, 2023
4b3c03f
Don't get args unless necessary
JimLaskey Nov 3, 2023
0bd5b47
Merge remote-tracking branch 'upstream/master' into 8315458
JimLaskey Nov 3, 2023
3ffff0d
Rename unnamed class tests and examples
JimLaskey Nov 6, 2023
7effbcf
Merge remote-tracking branch 'upstream/master' into 8315458
JimLaskey Nov 7, 2023
d3581d8
Update launch comments
JimLaskey Nov 7, 2023
338d63c
Clean up exception checks
JimLaskey Nov 8, 2023
f65efb0
Misspelling
JimLaskey Nov 8, 2023
0fb43a5
Update tests
JimLaskey Nov 8, 2023
8fedc67
Update LauncherHelper.java
JimLaskey Nov 10, 2023
1bf935f
Simplified and compatible main method finding
JimLaskey Nov 10, 2023
abf4881
Clean up previous commit
JimLaskey Nov 11, 2023
dd6703e
Reinstate test
JimLaskey Nov 11, 2023
701ba84
Filter abstract main methods and search interfaces for default main m…
JimLaskey Nov 14, 2023
598553f
Update comment in Filer.java to include implicitly declared classes
JimLaskey Nov 16, 2023
889f3ec
Allow nested class of same name as file
JimLaskey Nov 17, 2023
75f1e82
getMainMethod
JimLaskey Nov 18, 2023
468a20a
Update Class.java
JimLaskey Nov 18, 2023
90d4d1c
Clean up getMainMethod
JimLaskey Nov 19, 2023
8ef55fd
Add getMainMethod Test
JimLaskey Nov 19, 2023
27de4fe
Additional tests for getMainMethod
JimLaskey Nov 19, 2023
c5992d5
Move Implicitly Declared Classes to single directory
JimLaskey Nov 20, 2023
5542947
Add nested class test
JimLaskey Nov 20, 2023
abe35d5
Update findMainMethod as requested
JimLaskey Nov 20, 2023
b14c6a5
Update test
JimLaskey Nov 20, 2023
fd0c92f
Update Class.java
JimLaskey Nov 21, 2023
222e334
Handle javadoc on top level elements properly
JimLaskey Nov 22, 2023
420f6b4
Move findMainMethod to non-public access
JimLaskey Nov 23, 2023
690dac1
Remove Test
JimLaskey Nov 23, 2023
d7895da
Requested changes
JimLaskey Nov 24, 2023
daacc0b
Merge remote-tracking branch 'upstream/master' into 8315458
JimLaskey Nov 28, 2023
f313cc9
Update Class.java comment
JimLaskey Nov 28, 2023
c4fc2f9
Create TestImplicitClass.java
JimLaskey Nov 28, 2023
6ce7c84
Merge remote-tracking branch 'upstream/master' into 8315458
JimLaskey Nov 28, 2023
0d01c48
Requested changes
JimLaskey Nov 28, 2023
3017040
Add comments to invokeXXXX functions
JimLaskey Nov 28, 2023
2f7fdde
Windows line endings
JimLaskey Nov 29, 2023
cafc4db
Update test/jdk/tools/launcher/InstanceMainTest.java
JimLaskey Nov 29, 2023
7ed4045
Update test/jdk/tools/launcher/InstanceMainTest.java
JimLaskey Nov 29, 2023
cb0ed86
Correct comments
JimLaskey Nov 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 28 additions & 50 deletions src/java.base/share/classes/java/lang/Class.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,30 +190,21 @@
* a class or interface is hidden has no bearing on the characteristics
* exposed by the methods of class {@code Class}.
*
* <h2><a id=unnamedClasses>Unnamed Classes</a></h2>
*
* A {@code class} file representing an {@linkplain #isUnnamedClass unnamed class}
* is generated by a Java compiler from a source file for an unnamed class.
* The {@code Class} object representing an unnamed class is top-level,
* {@linkplain #isSynthetic synthetic}, and {@code final}. While an
* unnamed class does <em>not</em> have a name in its Java source
* form, several of the name-related methods of {@code java.lang.Class}
* do return non-null and non-empty results for the {@code Class}
* object representing an unnamed class.
* <h2><a id=implicitClasses>Implicit Classes</a></h2>
*
* Conventionally, a Java compiler, starting from a source file for an
* unnamed class, say {@code HelloWorld.java}, creates a
* implicit class, say {@code HelloWorld.java}, creates a
* similarly-named {@code class} file, {@code HelloWorld.class}, where
* the class stored in that {@code class} file is named {@code
* "HelloWorld"}, matching the base names of the source and {@code
* class} files.
*
* For the {@code Class} object of an unnamed class {@code
* For the {@code Class} object of an implicit class {@code
* HelloWorld}, the methods to get the {@linkplain #getName name} and
* {@linkplain #getTypeName type name} return results
* equal to {@code "HelloWorld"}. The {@linkplain #getSimpleName
* simple name} of such an unnamed class is the empty string and the
* {@linkplain #getCanonicalName canonical name} is {@code null}.
* simple name} of such an implicit class is {@code "HelloWorld"} and the
* {@linkplain #getCanonicalName canonical name} is {@code "HelloWorld"}.
*
* @param <T> the type of the class modeled by this {@code Class}
* object. For example, the type of {@code String.class} is {@code
Expand Down Expand Up @@ -1809,7 +1800,7 @@ public Class<?> getEnclosingClass() throws SecurityException {
/**
* Returns the simple name of the underlying class as given in the
* source code. An empty string is returned if the underlying class is
* {@linkplain #isAnonymousClass() anonymous} or {@linkplain #isUnnamedClass() unnamed}.
* {@linkplain #isAnonymousClass() anonymous}.
* A {@linkplain #isSynthetic() synthetic class}, one not present
* in source code, can have a non-empty name including special
* characters, such as "{@code $}".
Expand All @@ -1822,9 +1813,6 @@ public Class<?> getEnclosingClass() throws SecurityException {
* @since 1.5
*/
public String getSimpleName() {
if (isUnnamedClass()) {
return "";
}
ReflectionData<T> rd = reflectionData();
String simpleName = rd.simpleName;
if (simpleName == null) {
Expand Down Expand Up @@ -1874,7 +1862,6 @@ public String getTypeName() {
* <ul>
* <li>a {@linkplain #isLocalClass() local class}
* <li>a {@linkplain #isAnonymousClass() anonymous class}
* <li>an {@linkplain #isUnnamedClass() unnamed class}
* <li>a {@linkplain #isHidden() hidden class}
* <li>an array whose component type does not have a canonical name</li>
* </ul>
Expand All @@ -1894,9 +1881,6 @@ public String getTypeName() {
* @since 1.5
*/
public String getCanonicalName() {
if (isUnnamedClass()) {
return null;
}
ReflectionData<T> rd = reflectionData();
String canonicalName = rd.canonicalName;
if (canonicalName == null) {
Expand Down Expand Up @@ -1931,33 +1915,12 @@ private String getCanonicalName0() {
}
}

/**
* {@return {@code true} if and only if the underlying class
* is an unnamed class}
*
* @apiNote
* An unnamed class is not an {@linkplain #isAnonymousClass anonymous class}.
*
* @since 21
*
* @jls 7.3 Compilation Units
*/
@PreviewFeature(feature=PreviewFeature.Feature.UNNAMED_CLASSES,
reflective=true)
public boolean isUnnamedClass() {
return PreviewFeatures.isEnabled() && isSynthetic()
&& isTopLevelClass()
&& Modifier.isFinal(getModifiers());
}


/**
* Returns {@code true} if and only if the underlying class
* is an anonymous class.
*
* @apiNote
* An anonymous class is not a {@linkplain #isHidden() hidden class}.
* An anonymous class is not an {@linkplain #isUnnamedClass() unnamed class}.
*
* @return {@code true} if and only if this class is an anonymous class.
* @since 1.5
Expand Down Expand Up @@ -2922,6 +2885,21 @@ List<Method> getDeclaredPublicMethods(String name, Class<?>... parameterTypes) {
return result;
}

/**
* Returns the most specific {@code Method} object of this class, super class or
* interface that have the specified method name and parameter types.
*
* @param publicOnly true if only public methods are examined, otherwise all methods
* @param name the name of the method
* @param parameterTypes the parameter array
* @return the {@code Method} object for the method found from this class matching
* the specified name and parameters, or null if not found
*/
Method findMethod(boolean publicOnly, String name, Class<?>... parameterTypes) {
PublicMethods.MethodList res = getMethodsRecursive(name, parameterTypes, true, publicOnly);
return res == null ? null : getReflectionFactory().copyMethod(res.getMostSpecific());
}

/**
* Returns a {@code Constructor} object that reflects the specified
* constructor of the class represented by this
Expand Down Expand Up @@ -3750,7 +3728,7 @@ private Method getMethod0(String name, Class<?>[] parameterTypes) {
PublicMethods.MethodList res = getMethodsRecursive(
name,
parameterTypes == null ? EMPTY_CLASS_ARRAY : parameterTypes,
/* includeStatic */ true);
/* includeStatic */ true, /* publicOnly */ true);
return res == null ? null : res.getMostSpecific();
}

Expand All @@ -3759,9 +3737,10 @@ private Method getMethod0(String name, Class<?>[] parameterTypes) {
// via ReflectionFactory.copyMethod.
private PublicMethods.MethodList getMethodsRecursive(String name,
Class<?>[] parameterTypes,
boolean includeStatic) {
// 1st check declared public methods
Method[] methods = privateGetDeclaredMethods(/* publicOnly */ true);
boolean includeStatic,
boolean publicOnly) {
// 1st check declared methods
Method[] methods = privateGetDeclaredMethods(publicOnly);
PublicMethods.MethodList res = PublicMethods.MethodList
.filter(methods, name, parameterTypes, includeStatic);
// if there is at least one match among declared methods, we need not
Expand All @@ -3775,15 +3754,14 @@ private PublicMethods.MethodList getMethodsRecursive(String name,
// we must consult the superclass (if any) recursively...
Class<?> sc = getSuperclass();
if (sc != null) {
res = sc.getMethodsRecursive(name, parameterTypes, includeStatic);
res = sc.getMethodsRecursive(name, parameterTypes, includeStatic, publicOnly);
}

// ...and coalesce the superclass methods with methods obtained
// from directly implemented interfaces excluding static methods...
for (Class<?> intf : getInterfaces(/* cloneArray */ false)) {
res = PublicMethods.MethodList.merge(
res, intf.getMethodsRecursive(name, parameterTypes,
/* includeStatic */ false));
res, intf.getMethodsRecursive(name, parameterTypes, /* includeStatic */ false, publicOnly));
}

return res;
Expand Down
3 changes: 3 additions & 0 deletions src/java.base/share/classes/java/lang/System.java
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,9 @@ private static void setJavaLangAccess() {
public List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes) {
return klass.getDeclaredPublicMethods(name, parameterTypes);
}
public Method findMethod(Class<?> klass, boolean publicOnly, String name, Class<?>... parameterTypes) {
return klass.findMethod(publicOnly, name, parameterTypes);
}
public jdk.internal.reflect.ConstantPool getConstantPool(Class<?> klass) {
return klass.getConstantPool();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ public interface JavaLangAccess {
*/
List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes);

/**
* Return most specific method that matches name and parameterTypes.
*/
Method findMethod(Class<?> klass, boolean publicOnly, String name, Class<?>... parameterTypes);

/**
* Return the constant pool for a class.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ public enum Feature {
FOREIGN,
@JEP(number=459, title="String Templates", status="Second Preview")
STRING_TEMPLATES,
@JEP(number=445, title="Unnamed Classes and Instance Main Methods")
@JEP(number=445, title="Unnamed Classes and Instance Main Methods", status="Deprecated")
UNNAMED_CLASSES,
@JEP(number=463, title="Implicit Classes and Instance Main Methods", status="Preview")
IMPLICIT_CLASSES,
JimLaskey marked this conversation as resolved.
Show resolved Hide resolved
@JEP(number=446, title="Scoped Values", status="Preview")
SCOPED_VALUES,
@JEP(number=453, title="Structured Concurrency", status="Preview")
Expand Down
169 changes: 0 additions & 169 deletions src/java.base/share/classes/jdk/internal/misc/MainMethodFinder.java

This file was deleted.