diff --git a/src/hotspot/share/ci/ciField.cpp b/src/hotspot/share/ci/ciField.cpp index c75433a4d57..949213d3290 100644 --- a/src/hotspot/share/ci/ciField.cpp +++ b/src/hotspot/share/ci/ciField.cpp @@ -231,6 +231,9 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) { // Trust final fields in all boxed classes if (holder->is_box_klass()) return true; + // Trust final fields in records + if (holder->is_record()) + return true; // Trust final fields in String if (holder->name() == ciSymbol::java_lang_String()) return true; diff --git a/src/hotspot/share/ci/ciInstanceKlass.cpp b/src/hotspot/share/ci/ciInstanceKlass.cpp index 987e001b424..4fb1be82e98 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.cpp +++ b/src/hotspot/share/ci/ciInstanceKlass.cpp @@ -64,6 +64,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) : _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods(); _is_unsafe_anonymous = ik->is_unsafe_anonymous(); _is_hidden = ik->is_hidden(); + _is_record = ik->is_record(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: _has_injected_fields = -1; _implementor = NULL; // we will fill these lazily @@ -125,6 +126,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name, _has_injected_fields = -1; _is_unsafe_anonymous = false; _is_hidden = false; + _is_record = false; _loader = loader; _protection_domain = protection_domain; _is_shared = false; diff --git a/src/hotspot/share/ci/ciInstanceKlass.hpp b/src/hotspot/share/ci/ciInstanceKlass.hpp index 9ecc3da6e03..d03ecdc3a87 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.hpp +++ b/src/hotspot/share/ci/ciInstanceKlass.hpp @@ -57,6 +57,7 @@ private: bool _has_nonstatic_concrete_methods; bool _is_unsafe_anonymous; bool _is_hidden; + bool _is_record; ciFlags _flags; jint _nonstatic_field_size; @@ -200,6 +201,10 @@ public: return _is_hidden; } + bool is_record() const { + return _is_record; + } + ciInstanceKlass* get_canonical_holder(int offset); ciField* get_field_by_offset(int field_offset, bool is_static); ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 51b95e96ed5..63c068da6cc 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -3141,6 +3141,7 @@ int java_lang_reflect_Field::_name_offset; int java_lang_reflect_Field::_type_offset; int java_lang_reflect_Field::_slot_offset; int java_lang_reflect_Field::_modifiers_offset; +int java_lang_reflect_Field::_trusted_final_offset; int java_lang_reflect_Field::_signature_offset; int java_lang_reflect_Field::_annotations_offset; @@ -3150,6 +3151,7 @@ int java_lang_reflect_Field::_annotations_offset; macro(_type_offset, k, vmSymbols::type_name(), class_signature, false); \ macro(_slot_offset, k, vmSymbols::slot_name(), int_signature, false); \ macro(_modifiers_offset, k, vmSymbols::modifiers_name(), int_signature, false); \ + macro(_trusted_final_offset, k, vmSymbols::trusted_final_name(), bool_signature, false); \ macro(_signature_offset, k, vmSymbols::signature_name(), string_signature, false); \ macro(_annotations_offset, k, vmSymbols::annotations_name(), byte_array_signature, false); @@ -3214,6 +3216,10 @@ void java_lang_reflect_Field::set_modifiers(oop field, int value) { field->int_field_put(_modifiers_offset, value); } +void java_lang_reflect_Field::set_trusted_final(oop field) { + field->bool_field_put(_trusted_final_offset, true); +} + void java_lang_reflect_Field::set_signature(oop field, oop value) { field->obj_field_put(_signature_offset, value); } diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index c219abc954a..e33391c63e0 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -696,6 +696,7 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject { static int _type_offset; static int _slot_offset; static int _modifiers_offset; + static int _trusted_final_offset; static int _signature_offset; static int _annotations_offset; @@ -723,6 +724,8 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject { static int modifiers(oop field); static void set_modifiers(oop field, int value); + static void set_trusted_final(oop field); + static void set_signature(oop constructor, oop value); static void set_annotations(oop constructor, oop value); static void set_parameter_annotations(oop method, oop value); @@ -1121,6 +1124,7 @@ class java_lang_invoke_MemberName: AllStatic { MN_IS_FIELD = 0x00040000, // field MN_IS_TYPE = 0x00080000, // nested type MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected + MN_TRUSTED_FINAL = 0x00200000, // trusted final field MN_REFERENCE_KIND_SHIFT = 24, // refKind MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 94cee9fc61c..10789f564fd 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -266,6 +266,7 @@ template(returnType_name, "returnType") \ template(signature_name, "signature") \ template(slot_name, "slot") \ + template(trusted_final_name, "trustedFinal") \ \ /* Support for annotations (JDK 1.5 and above) */ \ \ diff --git a/src/hotspot/share/opto/convertnode.cpp b/src/hotspot/share/opto/convertnode.cpp index cf2af1f40f3..20de89a0d98 100644 --- a/src/hotspot/share/opto/convertnode.cpp +++ b/src/hotspot/share/opto/convertnode.cpp @@ -334,6 +334,13 @@ Node *ConvI2LNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* z = in(1); int op = z->Opcode(); if (op == Op_AddI || op == Op_SubI) { + if (!can_reshape) { + // Postpone this optimization to after parsing because with deep AddNode + // chains a large amount of dead ConvI2L nodes might be created that are + // not removed during parsing. As a result, we might hit the node limit. + phase->record_for_igvn(this); + return this_changed; + } Node* x = z->in(1); Node* y = z->in(2); assert (x != z && y != z, "dead loop in ConvI2LNode::Ideal"); diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index 7516ff594a5..5eebb5c2fce 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -126,6 +126,7 @@ enum { IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD, IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE, CALLER_SENSITIVE = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE, + TRUSTED_FINAL = java_lang_invoke_MemberName::MN_TRUSTED_FINAL, REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT, REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK, SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES, @@ -339,8 +340,10 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { } oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { + InstanceKlass* ik = fd.field_holder(); int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); + if (fd.is_trusted_final()) flags |= TRUSTED_FINAL; if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); int vmindex = fd.offset(); // determines the field uniquely when combined with static bit @@ -348,7 +351,7 @@ oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool java_lang_invoke_MemberName::set_flags (mname_oop, flags); java_lang_invoke_MemberName::set_method (mname_oop, NULL); java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); - java_lang_invoke_MemberName::set_clazz (mname_oop, fd.field_holder()->java_mirror()); + java_lang_invoke_MemberName::set_clazz (mname_oop, ik->java_mirror()); oop type = field_signature_type_or_null(fd.signature()); oop name = field_name_or_null(fd.name()); @@ -1107,6 +1110,7 @@ void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm, template(java_lang_invoke_MemberName,MN_IS_FIELD) \ template(java_lang_invoke_MemberName,MN_IS_TYPE) \ template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \ + template(java_lang_invoke_MemberName,MN_TRUSTED_FINAL) \ template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \ template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \ template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \ diff --git a/src/hotspot/share/runtime/fieldDescriptor.cpp b/src/hotspot/share/runtime/fieldDescriptor.cpp index 6123a502848..e3be65c6cca 100644 --- a/src/hotspot/share/runtime/fieldDescriptor.cpp +++ b/src/hotspot/share/runtime/fieldDescriptor.cpp @@ -58,6 +58,11 @@ Symbol* fieldDescriptor::generic_signature() const { return NULL; } +bool fieldDescriptor::is_trusted_final() const { + InstanceKlass* ik = field_holder(); + return is_final() && (is_static() || ik->is_hidden() || ik->is_record()); +} + AnnotationArray* fieldDescriptor::annotations() const { InstanceKlass* ik = field_holder(); Array* md = ik->fields_annotations(); diff --git a/src/hotspot/share/runtime/fieldDescriptor.hpp b/src/hotspot/share/runtime/fieldDescriptor.hpp index 189f785bb4c..a2594a5ef29 100644 --- a/src/hotspot/share/runtime/fieldDescriptor.hpp +++ b/src/hotspot/share/runtime/fieldDescriptor.hpp @@ -102,6 +102,8 @@ class fieldDescriptor { bool has_initialized_final_update() const { return access_flags().has_field_initialized_final_update(); } bool has_generic_signature() const { return access_flags().field_has_generic_signature(); } + bool is_trusted_final() const; + inline void set_is_field_access_watched(const bool value); inline void set_is_field_modification_watched(const bool value); inline void set_has_initialized_final_update(const bool value); diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index a09746c3185..6d403b838bd 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -614,7 +614,7 @@ const size_t minimumSymbolTableSize = 1024; product(bool, OmitStackTraceInFastThrow, true, \ "Omit backtraces for some 'hot' exceptions in optimized code") \ \ - manageable(bool, ShowCodeDetailsInExceptionMessages, false, \ + manageable(bool, ShowCodeDetailsInExceptionMessages, true, \ "Show exception messages from RuntimeExceptions that contain " \ "snippets of the failing code. Disable this to improve privacy.") \ \ diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index e9366f8fa18..02e7b1973fa 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -897,6 +897,9 @@ oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { java_lang_reflect_Field::set_slot(rh(), fd->index()); java_lang_reflect_Field::set_name(rh(), name()); java_lang_reflect_Field::set_type(rh(), type()); + if (fd->is_trusted_final()) { + java_lang_reflect_Field::set_trusted_final(rh()); + } // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); java_lang_reflect_Field::set_override(rh(), false); diff --git a/src/java.base/share/classes/java/io/PipedWriter.java b/src/java.base/share/classes/java/io/PipedWriter.java index a2489357f88..eb09adc8ce6 100644 --- a/src/java.base/share/classes/java/io/PipedWriter.java +++ b/src/java.base/share/classes/java/io/PipedWriter.java @@ -112,7 +112,7 @@ public class PipedWriter extends Writer { * Implements the {@code write} method of {@code Writer}. * * @param c the {@code char} to be written. - * @throw IOException if the pipe is + * @throws IOException if the pipe is * {@code broken}, * {@link #connect(java.io.PipedReader) unconnected}, closed * or an I/O error occurs. diff --git a/src/java.base/share/classes/java/io/SequenceInputStream.java b/src/java.base/share/classes/java/io/SequenceInputStream.java index 05f797fc9a0..441b4ad970c 100644 --- a/src/java.base/share/classes/java/io/SequenceInputStream.java +++ b/src/java.base/share/classes/java/io/SequenceInputStream.java @@ -121,7 +121,7 @@ public class SequenceInputStream extends InputStream { * skipped over) from the current underlying input stream * without blocking or {@code 0} if this input stream * has been closed by invoking its {@link #close()} method - * @throw IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * * @since 1.1 */ diff --git a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html index 9d69fc6a17f..a427266453b 100644 --- a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html +++ b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html @@ -282,7 +282,7 @@ The resulting run method is: } } -
+

Can I combine the two techniques to produce a thread that may be safely "stopped" or "suspended"?

Yes, it's reasonably straightforward. The one subtlety is that the @@ -324,6 +324,5 @@ If the stop method calls Thread.interrupt, as described above, it needn't call notify as well, but it still must be synchronized. This ensures that the target thread won't miss an interrupt due to a race condition. -

diff --git a/src/java.base/share/classes/java/lang/invoke/MemberName.java b/src/java.base/share/classes/java/lang/invoke/MemberName.java index dbd8d746830..afbb9ae636d 100644 --- a/src/java.base/share/classes/java/lang/invoke/MemberName.java +++ b/src/java.base/share/classes/java/lang/invoke/MemberName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -480,7 +480,8 @@ final class MemberName implements Member, Cloneable { IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor IS_FIELD = MN_IS_FIELD, // field IS_TYPE = MN_IS_TYPE, // nested type - CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation detected + CALLER_SENSITIVE = MN_CALLER_SENSITIVE, // @CallerSensitive annotation detected + TRUSTED_FINAL = MN_TRUSTED_FINAL; // trusted final field static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED; static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE; @@ -520,6 +521,8 @@ final class MemberName implements Member, Cloneable { public boolean isCallerSensitive() { return testAllFlags(CALLER_SENSITIVE); } + /** Query whether this member is a trusted final field. */ + public boolean isTrustedFinalField() { return testAllFlags(TRUSTED_FINAL|IS_FIELD); } /** Utility method to query whether this member is accessible from a given lookup class. */ public boolean isAccessibleFrom(Class lookupClass) { diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index ca161156c74..ff87bcedcaf 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -118,6 +118,7 @@ class MethodHandleNatives { MN_IS_FIELD = 0x00040000, // field MN_IS_TYPE = 0x00080000, // nested type MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected + MN_TRUSTED_FINAL = 0x00200000, // trusted final field MN_REFERENCE_KIND_SHIFT = 24, // refKind MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 23f31cc6b85..4038f5841d7 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -3273,10 +3273,10 @@ return mh1; private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException { MemberName field = new MemberName(f, isSetter); if (isSetter && field.isFinal()) { - if (field.isStatic()) { - throw field.makeAccessException("static final field has no write access", this); - } else if (field.getDeclaringClass().isHidden()){ - throw field.makeAccessException("final field in a hidden class has no write access", this); + if (field.isTrustedFinalField()) { + String msg = field.isStatic() ? "static final field has no write access" + : "final field has no write access"; + throw field.makeAccessException(msg, this); } } assert(isSetter @@ -3839,7 +3839,7 @@ return mh1; refc = lookupClass(); } return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), - this.allowedModes == TRUSTED && !getField.getDeclaringClass().isHidden()); + this.allowedModes == TRUSTED && !getField.isTrustedFinalField()); } /** Check access and get the requested constructor. */ private MethodHandle getDirectConstructor(Class refc, MemberName ctor) throws IllegalAccessException { diff --git a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java index 4707276c720..3db39d8e92c 100644 --- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java +++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java @@ -177,10 +177,16 @@ public class AccessibleObject implements AnnotatedElement { * to the caller's module.

* *

This method cannot be used to enable {@linkplain Field#set write} - * access to a final field declared in a {@linkplain Class#isHidden() hidden class}, - * since such fields are not modifiable. The {@code accessible} flag when - * {@code true} suppresses Java language access control checks to only - * enable {@linkplain Field#get read} access to such fields. + * access to a non-modifiable final field. The following fields + * are non-modifiable: + *

+ *

The {@code accessible} flag when {@code true} suppresses Java language access + * control checks to only enable {@linkplain Field#get read} access to + * these non-modifiable final fields. * *

If there is a security manager, its * {@code checkPermission} method is first called with a diff --git a/src/java.base/share/classes/java/lang/reflect/Field.java b/src/java.base/share/classes/java/lang/reflect/Field.java index 5589dc7bb7b..75bf314c5e0 100644 --- a/src/java.base/share/classes/java/lang/reflect/Field.java +++ b/src/java.base/share/classes/java/lang/reflect/Field.java @@ -72,6 +72,7 @@ class Field extends AccessibleObject implements Member { private String name; private Class type; private int modifiers; + private boolean trustedFinal; // Generics and annotations support private transient String signature; // generic info repository; lazily initialized @@ -119,6 +120,7 @@ class Field extends AccessibleObject implements Member { String name, Class type, int modifiers, + boolean trustedFinal, int slot, String signature, byte[] annotations) @@ -127,6 +129,7 @@ class Field extends AccessibleObject implements Member { this.name = name; this.type = type; this.modifiers = modifiers; + this.trustedFinal = trustedFinal; this.slot = slot; this.signature = signature; this.annotations = annotations; @@ -148,7 +151,7 @@ class Field extends AccessibleObject implements Member { if (this.root != null) throw new IllegalArgumentException("Can not copy a non-root Field"); - Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations); + Field res = new Field(clazz, name, type, modifiers, trustedFinal, slot, signature, annotations); res.root = this; // Might as well eagerly propagate this if already present res.fieldAccessor = fieldAccessor; @@ -728,7 +731,9 @@ class Field extends AccessibleObject implements Member { * this {@code Field} object; *

  • the field is non-static; and
  • *
  • the field's declaring class is not a {@linkplain Class#isHidden() - * hidden class}.
  • + * hidden class}; and + *
  • the field's declaring class is not a {@linkplain Class#isRecord() + * record class}.
  • * * If any of the above checks is not met, this method throws an * {@code IllegalAccessException}. @@ -1145,10 +1150,14 @@ class Field extends AccessibleObject implements Member { } @Override - Field getRoot() { + /* package-private */ Field getRoot() { return root; } + /* package-private */ boolean isTrustedFinal() { + return trustedFinal; + } + /** * {@inheritDoc} * diff --git a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java index 2ed950cc76f..6ac890156b0 100644 --- a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java +++ b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,6 +118,10 @@ class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess { return (T) obj.getRoot(); } + public boolean isTrustedFinalField(Field f) { + return f.isTrustedFinal(); + } + public T newInstance(Constructor ctor, Object[] args, Class caller) throws IllegalAccessException, InstantiationException, InvocationTargetException { diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java index 8e537b68cbf..4082fae336f 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,6 +96,9 @@ public interface JavaLangReflectAccess { /** Gets the root of the given AccessibleObject object; null if arg is the root */ public T getRoot(T obj); + /** Tests if this is a trusted final field */ + public boolean isTrustedFinalField(Field f); + /** Returns a new instance created by the given constructor with access check */ public T newInstance(Constructor ctor, Object[] args, Class caller) throws IllegalAccessException, InstantiationException, InvocationTargetException; diff --git a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index 3152089a272..410297cac0b 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import jdk.internal.HotSpotIntrinsicCandidate; +import jdk.internal.access.SharedSecrets; import jdk.internal.misc.VM; /** Common utility routines used by both java.lang and @@ -336,6 +337,14 @@ public class Reflection { return false; } + /* + * Tests if the given Field is a trusted final field and it cannot be + * modified reflectively regardless of the value of its accessible flag. + */ + public static boolean isTrustedFinalField(Field field) { + return SharedSecrets.getJavaLangReflectAccess().isTrustedFinalField(field); + } + /** * Returns an IllegalAccessException with an exception message based on * the access that is denied. diff --git a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java index 2a7728df542..4f344d22a8f 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java +++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java @@ -181,7 +181,9 @@ public class ReflectionFactory { field = root; } } - return UnsafeFieldAccessorFactory.newFieldAccessor(field, override); + boolean isFinal = Modifier.isFinal(field.getModifiers()); + boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field)); + return UnsafeFieldAccessorFactory.newFieldAccessor(field, isReadOnly); } public MethodAccessor newMethodAccessor(Method method) { diff --git a/src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorFactory.java b/src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorFactory.java index ba292087bfd..d13043ce988 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorFactory.java +++ b/src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorFactory.java @@ -29,13 +29,12 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; class UnsafeFieldAccessorFactory { - static FieldAccessor newFieldAccessor(Field field, boolean override) { + static FieldAccessor newFieldAccessor(Field field, boolean isReadOnly) { Class type = field.getType(); boolean isStatic = Modifier.isStatic(field.getModifiers()); boolean isFinal = Modifier.isFinal(field.getModifiers()); boolean isVolatile = Modifier.isVolatile(field.getModifiers()); boolean isQualified = isFinal || isVolatile; - boolean isReadOnly = isFinal && (isStatic || !override || field.getDeclaringClass().isHidden()); if (isStatic) { // This code path does not guarantee that the field's // declaring class has been initialized, but it must be diff --git a/src/java.management/share/classes/java/lang/management/package.html b/src/java.management/share/classes/java/lang/management/package.html index ff95579fad9..c10a97618f3 100644 --- a/src/java.management/share/classes/java/lang/management/package.html +++ b/src/java.management/share/classes/java/lang/management/package.html @@ -234,7 +234,7 @@ java.lang.NullPointerException NullPointerException} to be thrown.

    The java.lang.management API is thread-safe. -@see {@linkplain javax.management JMX Specification} +@see javax.management JMX Specification @author Mandy Chung @since 1.5 diff --git a/src/java.xml.crypto/share/classes/com/sun/org/slf4j/internal/Logger.java b/src/java.xml.crypto/share/classes/com/sun/org/slf4j/internal/Logger.java index e459d390ef8..ab98cefb648 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/slf4j/internal/Logger.java +++ b/src/java.xml.crypto/share/classes/com/sun/org/slf4j/internal/Logger.java @@ -103,14 +103,14 @@ public class Logger { } } - public void log0(Level level, String s, Throwable e) { + private void log0(Level level, String s, Throwable e) { if (impl.isLoggable(level)) { var sf = WALKER.walk(f -> f.skip(2).findFirst()).get(); impl.logp(Level.FINE, sf.getClassName(), sf.getMethodName(), s, e); } } - public void log0(Level level, String s, Object... o) { + private void log0(Level level, String s, Object... o) { if (impl.isLoggable(level)) { var sf = WALKER.walk(f -> f.skip(2).findFirst()).get(); impl.logp(Level.FINE, sf.getClassName(), sf.getMethodName(), diff --git a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java b/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java index dbb577aa52d..2d8fc787956 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java @@ -1168,7 +1168,7 @@ public class Checker extends DocTreePathScanner { return; } } - env.messages.warning(SYNTAX, tree, "dc.empty", tree.getKind().tagName); + env.messages.warning(MISSING, tree, "dc.empty", tree.getKind().tagName); } boolean hasNonWhitespace(TextTree tree) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 2986bf1d60d..55e27282e46 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -999,7 +999,10 @@ public class LambdaToMethod extends TreeTranslator { private JCExpression makeReceiver(VarSymbol rcvr) { if (rcvr == null) return null; JCExpression rcvrExpr = make.Ident(rcvr); - Type rcvrType = tree.ownerAccessible ? tree.sym.enclClass().type : tree.expr.type; + boolean protAccess = + isProtectedInSuperClassOfEnclosingClassInOtherPackage(tree.sym, owner); + Type rcvrType = tree.ownerAccessible && !protAccess ? tree.sym.enclClass().type + : tree.expr.type; if (rcvrType == syms.arrayClass.type) { // Map the receiver type to the actually type, not just "array" rcvrType = tree.getQualifierExpression().type; @@ -2270,11 +2273,6 @@ public class LambdaToMethod extends TreeTranslator { types.erasure(owner.enclClass().asType())); } - boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage() { - return ((tree.sym.flags() & PROTECTED) != 0 && - tree.sym.packge() != owner.packge()); - } - /** * Erasure destroys the implementation parameter subtype * relationship for intersection types. @@ -2311,7 +2309,7 @@ public class LambdaToMethod extends TreeTranslator { needsVarArgsConversion() || isArrayOp() || (!nestmateLambdas && isPrivateInOtherClass()) || - isProtectedInSuperClassOfEnclosingClassInOtherPackage() || + isProtectedInSuperClassOfEnclosingClassInOtherPackage(tree.sym, owner) || !receiverAccessible() || (tree.getMode() == ReferenceMode.NEW && tree.kind != ReferenceKind.ARRAY_CTOR && @@ -2386,6 +2384,12 @@ public class LambdaToMethod extends TreeTranslator { } } + private boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage(Symbol targetReference, + Symbol currentClass) { + return ((targetReference.flags() & PROTECTED) != 0 && + targetReference.packge() != currentClass.packge()); + } + /** * Signature Generation */ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/Versions.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/Versions.java new file mode 100644 index 00000000000..9d08ee670f6 --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/Versions.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.javadoc.internal; + +import java.util.ResourceBundle; + +import static java.util.ResourceBundle.getBundle; + +public final class Versions { + + private Versions() { throw new AssertionError(); } + + /** + * Returns the version of the {@code javadoc} tool and the Standard doclet. + * + *

    This is typically the same as the version of the JDK platform being + * used to run the tool, but may be different when running the tool on an + * older version of the platform. + * + * @throws RuntimeException in an unlikely event of the version info + * not being available + * + * @apiNote This method does not return {@code null}, has the return type of + * {@code Optional}, or throw a checked exception. Those + * would warp the API to cater for something that is probably a result of + * a build error anyway. Hence, {@code RuntimeException}. + * + * @return the version + */ + public static Runtime.Version javadocVersion() throws RuntimeException { + /* + * The "jdk.javadoc.internal.tool.resources.version" resource bundle is + * non-localized and represented by a class compiled from a source like this: + * + * $ cat build/.../support/gensrc/jdk.javadoc/jdk/javadoc/internal/tool/resources/version.java + * package jdk.javadoc.internal.tool.resources; + * + * public final class version extends java.util.ListResourceBundle { + * protected final Object[][] getContents() { + * return new Object[][] { + * { "full", "15-internal+0-2020-06-02-1426246.duke..." }, + * { "jdk", "15" }, + * { "release", "15-internal" }, + * }; + * } + * } + * + * The string keyed by "full" should be parseable by Runtime.Version.parse() + */ + ResourceBundle bundle = getBundle("jdk.javadoc.internal.tool.resources.version"); + return Runtime.Version.parse(bundle.getString("full")); + } + + /** + * Returns a short string representation of the provided version. + * + *

    Examples of strings returned from this method are: "15" and + * "15-internal". + * + * @return a short string representation of the provided version + * + * @throws NullPointerException if {@code v == null} + */ + public static String shortVersionStringOf(Runtime.Version v) { + String svstr = String.valueOf(v.feature()); + if (v.pre().isPresent()) { + svstr += "-" + v.pre().get(); + } + return svstr; + } + + /** + * Returns a full string representation of the provided version. + * + *

    Examples of strings returned from this method are "14+36-1461" and + * "15-internal+0-2020-06-02-1426246.duke...". + * + * @return a full string representation of the provided version + * + * @throws NullPointerException if {@code v == null} + */ + public static String fullVersionStringOf(Runtime.Version v) { + return v.toString(); + } +} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java index 41262280e82..50a11e061db 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java @@ -27,6 +27,7 @@ package jdk.javadoc.internal.doclets.formats.html; import java.io.IOException; import java.io.Writer; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -105,8 +106,12 @@ public class AbstractIndexWriter extends HtmlDocletWriter { addHeading(uc, contentTree); HtmlTree dl = HtmlTree.DL(HtmlStyle.index); + Map duplicateLabelCheck = new HashMap<>(); + memberlist.forEach(e -> duplicateLabelCheck.compute(e.getFullyQualifiedLabel(utils), + (k, v) -> v == null ? 1 : v + 1)); for (IndexItem indexItem : memberlist) { - addDescription(indexItem, dl); + addDescription(indexItem, dl, + duplicateLabelCheck.get(indexItem.getFullyQualifiedLabel(utils)) > 1); } contentTree.add(dl); } @@ -120,14 +125,14 @@ public class AbstractIndexWriter extends HtmlDocletWriter { contentTree.add(heading); } - protected void addDescription(IndexItem indexItem, Content dl) { + protected void addDescription(IndexItem indexItem, Content dl, boolean addModuleInfo) { SearchIndexItem si = indexItem.getSearchTag(); if (si != null) { addDescription(si, dl); } else { si = new SearchIndexItem(); si.setLabel(indexItem.getLabel()); - addElementDescription(indexItem, dl, si); + addElementDescription(indexItem, dl, si, addModuleInfo); searchItems.add(si); } } @@ -138,8 +143,10 @@ public class AbstractIndexWriter extends HtmlDocletWriter { * @param indexItem the element to be documented * @param dlTree the content tree to which the description will be added * @param si the search index item + * @param addModuleInfo whether to include module information */ - protected void addElementDescription(IndexItem indexItem, Content dlTree, SearchIndexItem si) { + protected void addElementDescription(IndexItem indexItem, Content dlTree, SearchIndexItem si, + boolean addModuleInfo) { Content dt; Element element = indexItem.getElement(); String label = indexItem.getLabel(); @@ -165,6 +172,9 @@ public class AbstractIndexWriter extends HtmlDocletWriter { dt = HtmlTree.DT(getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.INDEX, (TypeElement)element).strong(true))); si.setContainingPackage(utils.getPackageName(utils.containingPackage(element))); + if (configuration.showModules && addModuleInfo) { + si.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(element))); + } si.setCategory(Category.TYPES); dt.add(" - "); addClassInfo((TypeElement)element, dt); @@ -175,6 +185,9 @@ public class AbstractIndexWriter extends HtmlDocletWriter { getDocLink(LinkInfoImpl.Kind.INDEX, containingType, element, new StringContent(label)))); si.setContainingPackage(utils.getPackageName(utils.containingPackage(element))); si.setContainingClass(utils.getSimpleName(containingType)); + if (configuration.showModules && addModuleInfo) { + si.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(element))); + } if (utils.isExecutableElement(element)) { String url = HtmlTree.encodeURL(links.getName(getAnchor((ExecutableElement)element))); if (!label.equals(url)) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java index 7613136899f..b9a6fc52922 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java @@ -205,8 +205,6 @@ public class DeprecatedListWriter extends SubWriterHolderWriter { private EnumMap writerMap; - private HtmlConfiguration configuration; - private final Navigation navBar; /** @@ -218,7 +216,6 @@ public class DeprecatedListWriter extends SubWriterHolderWriter { public DeprecatedListWriter(HtmlConfiguration configuration, DocPath filename) { super(configuration, filename); - this.configuration = configuration; this.navBar = new Navigation(null, configuration, PageMode.DEPRECATED, path); NestedClassWriterImpl classW = new NestedClassWriterImpl(this); writerMap = new EnumMap<>(DeprElementKind.class); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java index 5a961c692c7..56eee939d96 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java @@ -276,7 +276,7 @@ public class HelpWriter extends HtmlDocletWriter { HtmlTree.CODE(new StringContent(example[0])), example[1]))); } Content searchSpecLink = HtmlTree.A( - resources.getText("doclet.help.search.spec.url", Runtime.version().feature()), + resources.getText("doclet.help.search.spec.url", configuration.getDocletVersion().feature()), getContent("doclet.help.search.spec.title")); Content searchRefer = HtmlTree.P(getContent("doclet.help.search.refer", searchSpecLink)); section.add(searchIntro) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java index a189a431636..a055d21daa8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java @@ -42,6 +42,7 @@ import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.Reporter; import jdk.javadoc.doclet.StandardDoclet; import jdk.javadoc.doclet.Taglet; +import jdk.javadoc.internal.Versions; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import jdk.javadoc.internal.doclets.toolkit.DocletException; import jdk.javadoc.internal.doclets.toolkit.Messages; @@ -51,8 +52,6 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFile; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; -import static javax.tools.Diagnostic.Kind.*; - /** * Configure the output based on the command-line options. *

    @@ -142,31 +141,29 @@ public class HtmlConfiguration extends BaseConfiguration { contents = new Contents(this); options = new HtmlOptions(this); - String v; + Runtime.Version v; try { - // the version bundle is not localized - ResourceBundle rb = ResourceBundle.getBundle(versionBundleName, Locale.getDefault()); - try { - v = rb.getString("release"); - } catch (MissingResourceException e) { - v = defaultDocletVersion; - } - } catch (MissingResourceException e) { - v = defaultDocletVersion; + v = Versions.javadocVersion(); + } catch (RuntimeException e) { + assert false : e; + v = Runtime.version(); // arguably, the only sensible default } docletVersion = v; } - private static final String versionBundleName = "jdk.javadoc.internal.tool.resources.version"; - private static final String defaultDocletVersion = System.getProperty("java.version"); - public final String docletVersion; + private final Runtime.Version docletVersion; public final Date startTime = new Date(); @Override - public String getDocletVersion() { + public Runtime.Version getDocletVersion() { return docletVersion; } + @Override + public String getDocletVersionString() { + return Versions.shortVersionStringOf(docletVersion); + } + @Override public Resources getDocResources() { return docResources; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index c8ec0e7e88f..26999451093 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -431,7 +431,7 @@ public class HtmlDocletWriter { Content htmlComment = contents.newPage; List additionalStylesheets = configuration.getAdditionalStylesheets(); additionalStylesheets.addAll(localStylesheets); - Head head = new Head(path, configuration.docletVersion, configuration.startTime) + Head head = new Head(path, configuration.getDocletVersionString(), configuration.startTime) .setTimestamp(!options.noTimestamp()) .setDescription(description) .setGenerator(getGenerator(getClass())) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java index 2794ca8c883..e9ace055240 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java @@ -75,7 +75,7 @@ public class IndexRedirectWriter extends HtmlDocletWriter { */ private void generateIndexFile() throws DocFileIOException { Content htmlComment = contents.newPage; - Head head = new Head(path, configuration.docletVersion, configuration.startTime) + Head head = new Head(path, configuration.getDocletVersionString(), configuration.startTime) .setTimestamp(!options.noTimestamp()) .setDescription("index redirect") .setGenerator(getGenerator(getClass())) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java index a5043d8492d..0f2c6181d00 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchIndexItem.java @@ -148,6 +148,9 @@ public class SearchIndexItem { if (!containingPackage.isEmpty()) { item.append("\"p\":\"").append(containingPackage).append("\","); } + if (!containingModule.isEmpty()) { + item.append("\"m\":\"").append(containingModule).append("\","); + } item.append("\"l\":\"").append(label).append("\""); if (!url.isEmpty()) { item.append(",\"u\":\"").append(url).append("\""); @@ -155,8 +158,11 @@ public class SearchIndexItem { item.append("}"); break; case MEMBERS: - item.append("{") - .append("\"p\":\"").append(containingPackage).append("\",") + item.append("{"); + if (!containingModule.isEmpty()) { + item.append("\"m\":\"").append(containingModule).append("\","); + } + item.append("\"p\":\"").append(containingPackage).append("\",") .append("\"c\":\"").append(containingClass).append("\",") .append("\"l\":\"").append(label).append("\""); if (!url.isEmpty()) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java index 5262a5ca144..f1c58b93957 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java @@ -235,7 +235,7 @@ public class SourceToHTMLConverter { * @param path the path for the file. */ private void writeToFile(Content body, DocPath path, TypeElement te) throws DocFileIOException { - Head head = new Head(path, configuration.docletVersion, configuration.startTime) + Head head = new Head(path, configuration.getDocletVersionString(), configuration.startTime) // .setTimestamp(!options.notimestamp) // temporary: compatibility! .setTitle(resources.getText("doclet.Window_Source_title")) // .setCharset(options.charset) // temporary: compatibility! diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js index 9a684ca1b55..c4e4e8b6c84 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js @@ -34,6 +34,7 @@ var searchPattern = ""; var RANKING_THRESHOLD = 2; var NO_MATCH = 0xffff; var MAX_RESULTS_PER_CATEGORY = 500; +var UNNAMED = ""; function escapeHtml(str) { return str.replace(//g, ">"); } @@ -48,14 +49,16 @@ function getURLPrefix(ui) { return ui.item.l + slash; } else if (ui.item.category === catPackages && ui.item.m) { return ui.item.m + slash; - } else if ((ui.item.category === catTypes && ui.item.p) || ui.item.category === catMembers) { - $.each(packageSearchIndex, function(index, item) { - if (item.m && ui.item.p == item.l) { - urlPrefix = item.m + slash; - } - }); - return urlPrefix; - } else { + } else if (ui.item.category === catTypes || ui.item.category === catMembers) { + if (ui.item.m) { + urlPrefix = ui.item.m + slash; + } else { + $.each(packageSearchIndex, function(index, item) { + if (item.m && ui.item.p === item.l) { + urlPrefix = item.m + slash; + } + }); + } return urlPrefix; } return urlPrefix; @@ -121,7 +124,7 @@ $.widget("custom.catcomplete", $.ui.autocomplete, { rMenu.menu.bindings = $(); $.each(items, function(index, item) { var li; - if (item.l !== noResult.l && item.category !== currentCategory) { + if (item.category && item.category !== currentCategory) { ul.append("

  • " + item.category + "
  • "); currentCategory = item.category; } @@ -141,15 +144,15 @@ $.widget("custom.catcomplete", $.ui.autocomplete, { if (item.category === catModules) { label = getHighlightedText(item.l, matcher); } else if (item.category === catPackages) { - label = (item.m) - ? getHighlightedText(item.m + "/" + item.l, matcher) - : getHighlightedText(item.l, matcher); + label = getHighlightedText(item.l, matcher); } else if (item.category === catTypes) { - label = (item.p) + label = (item.p && item.p !== UNNAMED) ? getHighlightedText(item.p + "." + item.l, matcher) : getHighlightedText(item.l, matcher); } else if (item.category === catMembers) { - label = getHighlightedText(item.p + "." + (item.c + "." + item.l), matcher); + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.c + "." + item.l, matcher) + : getHighlightedText(item.c + "." + item.l, matcher); } else if (item.category === catSearchTags) { label = getHighlightedText(item.l, matcher); } else { @@ -165,7 +168,11 @@ $.widget("custom.catcomplete", $.ui.autocomplete, { div.html(label + " (" + item.h + ")"); } } else { - div.html(label); + if (item.m) { + div.html(item.m + "/" + label); + } else { + div.html(label); + } } return li; } @@ -317,7 +324,7 @@ $(function() { collision: "flip" }, select: function(event, ui) { - if (ui.item.l !== noResult.l) { + if (ui.item.category) { var url = getURLPrefix(ui); if (ui.item.category === catModules) { url += "module-summary.html"; @@ -330,13 +337,13 @@ $(function() { } else if (ui.item.category === catTypes) { if (ui.item.u) { url = ui.item.u; - } else if (ui.item.p === "") { + } else if (ui.item.p === UNNAMED) { url += ui.item.l + ".html"; } else { url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html"; } } else if (ui.item.category === catMembers) { - if (ui.item.p === "") { + if (ui.item.p === UNNAMED) { url += ui.item.c + ".html" + "#"; } else { url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#"; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index 063cbaef5e1..a3356bdb1fa 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -144,7 +144,7 @@ doclet.help.package.intro=\ each. These pages may contain six categories: doclet.help.module.intro=\ Each module has a page that contains a list of its packages, dependencies on other modules, \ - and services, with a summary for each. These page may contain three categories: + and services, with a summary for each. These pages may contain three categories: doclet.help.class_interface.head=\ Class or Interface doclet.help.class_interface.intro=\ @@ -164,7 +164,6 @@ doclet.help.class_interface.declaration=\ doclet.help.class_interface.description=\ Class or Interface Description doclet.help.class_interface.summary=\ - Each summary entry contains the first sentence from the detailed description for that item. \ The summary entries are alphabetical, while the detailed descriptions are in the order they \ appear in the source code. This preserves the logical groupings established by the programmer. doclet.help.use.head=\ @@ -189,7 +188,7 @@ doclet.help.tree.package=\ hierarchy for only that package. doclet.help.deprecated.body=\ The {0} page lists all of the API that have been deprecated. A deprecated API is not \ - recommended for use, generally due to improvements, and a replacement API is usually given. \ + recommended for use, generally due to shortcomings, and a replacement API is usually given. \ Deprecated APIs may be removed in future implementations. doclet.help.index.head=\ Index @@ -198,9 +197,9 @@ doclet.help.index.body=\ and fields, as well as lists of all packages and all classes. doclet.help.serial_form.body=\ Each serializable or externalizable class has a description of its serialization fields and \ - methods. This information is of interest to re-implementors, not to developers using the API. \ + methods. This information is of interest to those who implement rather than use the API. \ While there is no link in the navigation bar, you can get to this information by going to any \ - serialized class and clicking "Serialized Form" in the "See also" section of the class \ + serialized class and clicking "Serialized Form" in the "See Also" section of the class \ description. doclet.help.constants.body=\ The {0} page lists the static final fields and their values. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java index c27710cc431..2f537fc6bc7 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java @@ -151,11 +151,19 @@ public abstract class BaseConfiguration { public abstract Resources getDocResources(); /** - * Returns a string identifying the version of the doclet. + * Returns the version of the {@link #doclet doclet}. * - * @return a version string + * @return the version */ - public abstract String getDocletVersion(); + public abstract Runtime.Version getDocletVersion(); + + /** + * Returns a short string representation of the version returned by + * {@linkplain #getDocletVersion()}. + * + * @return a short string representation of the version + */ + public abstract String getDocletVersionString(); /** * This method should be defined in all those doclets (configurations), diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Comparators.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Comparators.java index dbe42598ba5..3a2931c6886 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Comparators.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Comparators.java @@ -139,9 +139,15 @@ public class Comparators { @Override public int compare(Element e1, Element e2) { int result = compareFullyQualifiedNames(e1, e2); - if (result == 0) - result = compareModuleNames(e1, e2); - return result; + if (result != 0) { + return result; + } + // if elements are executable compare their parameter arrays + result = compareParameters(e1, e2); + if (result != 0) { + return result; + } + return compareModuleNames(e1, e2); } }; } @@ -256,19 +262,11 @@ public class Comparators { if (result != 0) { return result; } - // if element kinds are the same, and are methods, - // compare the method parameters - if (hasParameters(e1)) { - List parameters1 = ((ExecutableElement)e1).getParameters(); - List parameters2 = ((ExecutableElement)e2).getParameters(); - result = compareParameters(false, parameters1, parameters2); - if (result != 0) { - return result; - } - result = compareParameters(true, parameters1, parameters2); - if (result != 0) { - return result; - } + // if element kinds are the same, and are executable, + // compare the parameter arrays + result = compareParameters(e1, e2); + if (result != 0) { + return result; } // else fall back on fully qualified names result = compareFullyQualifiedNames(e1, e2); @@ -383,15 +381,7 @@ public class Comparators { if (result != 0) { return result; } - if (hasParameters(e1) && hasParameters(e2)) { - List parameters1 = ((ExecutableElement)e1).getParameters(); - List parameters2 = ((ExecutableElement)e2).getParameters(); - result = compareParameters(false, parameters1, parameters2); - if (result != 0) { - return result; - } - result = compareParameters(true, parameters1, parameters2); - } + result = compareParameters(e1, e2); if (result != 0) { return result; } @@ -504,6 +494,34 @@ public class Comparators { return 0; } + /** + * Compares the parameter arrays of two elements if they both are executable. + * @param e1 the first element + * @param e2 the second element + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second + */ + protected int compareParameters(Element e1, Element e2) { + int result = 0; + if (hasParameters(e1) && hasParameters(e2)) { + List parameters1 = ((ExecutableElement)e1).getParameters(); + List parameters2 = ((ExecutableElement)e2).getParameters(); + result = compareParameters(false, parameters1, parameters2); + if (result != 0) { + return result; + } + result = compareParameters(true, parameters1, parameters2); + } + return result; + } + + /** + * Compares the kinds of two elements. + * @param e1 the first element + * @param e2 the second element + * @return a negative integer, zero, or a positive integer as the first + * argument is less than, equal to, or greater than the second + */ protected int compareElementKinds(Element e1, Element e2) { return Integer.compare(getKindIndex(e1), getKindIndex(e2)); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexItem.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexItem.java index d88d1fa4e13..75e818c8d24 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexItem.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexItem.java @@ -26,7 +26,6 @@ package jdk.javadoc.internal.doclets.toolkit.util; import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem; -import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -90,6 +89,16 @@ public class IndexItem { return label; } + public String getFullyQualifiedLabel(Utils utils) { + if (typeElement != null) { + return utils.getFullyQualifiedName(typeElement) + "." + label; + } else if (element != null) { + return utils.getFullyQualifiedName(element); + } else { + return label; + } + } + public Element getElement() { return element; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkFactory.java index cc6deb73720..261c2d53886 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,6 +109,7 @@ public abstract class LinkFactory { @Override public Content visitWildcard(WildcardType type, LinkInfo linkInfo) { linkInfo.isTypeBound = true; + link.add(getTypeAnnotationLinks(linkInfo)); link.add("?"); TypeMirror extendsBound = type.getExtendsBound(); if (extendsBound != null) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java index ef695034c0e..24cce42cf57 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java @@ -31,16 +31,14 @@ import java.io.PrintWriter; import java.text.BreakIterator; import java.text.Collator; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.IllformedLocaleException; import java.util.List; import java.util.Locale; -import java.util.MissingResourceException; import java.util.Objects; -import java.util.ResourceBundle; import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import javax.tools.JavaFileManager; @@ -62,6 +60,7 @@ import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet.Option; import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.StandardDoclet; +import jdk.javadoc.internal.Versions; import jdk.javadoc.internal.tool.Main.Result; import jdk.javadoc.internal.tool.ToolOptions.ToolOption; @@ -167,17 +166,30 @@ public class Start { @Override public void version() { - showVersion("javadoc.version", "release"); + showVersion("javadoc.version", orDefault(() -> Versions.shortVersionStringOf(toolVersion()))); } @Override public void fullVersion() { - showVersion("javadoc.fullversion", "full"); + showVersion("javadoc.fullversion", orDefault(() -> Versions.fullVersionStringOf(toolVersion()))); + } + + private String orDefault(Supplier s) { + try { + return s.get(); + } catch (RuntimeException e) { + assert false : e; + return Log.getLocalizedString("version.not.available"); + } } }; return new ToolOptions(context, messager, helper); } + private Runtime.Version toolVersion() { + return Versions.javadocVersion(); + } + private void showUsage() { showUsage("main.usage", ToolOption.Kind.STANDARD, "main.usage.foot"); } @@ -196,26 +208,8 @@ public class Start { messager.notice(footerKey); } - private static final String versionRBName = "jdk.javadoc.internal.tool.resources.version"; - private static ResourceBundle versionRB; - - private void showVersion(String labelKey, String versionKey) { - messager.notice(labelKey, messager.programName, getVersion(versionKey)); - } - - private static String getVersion(String key) { - if (versionRB == null) { - try { - versionRB = ResourceBundle.getBundle(versionRBName); - } catch (MissingResourceException e) { - return Log.getLocalizedString("version.not.available"); - } - } - try { - return versionRB.getString(key); - } catch (MissingResourceException e) { - return Log.getLocalizedString("version.not.available"); - } + private void showVersion(String labelKey, String value) { + messager.notice(labelKey, messager.programName, value); } private void showToolOptions(ToolOption.Kind kind) { diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/Type.java b/src/jdk.jdi/share/classes/com/sun/jdi/Type.java index 91ab3dee148..c5d7554799c 100644 --- a/src/jdk.jdi/share/classes/com/sun/jdi/Type.java +++ b/src/jdk.jdi/share/classes/com/sun/jdi/Type.java @@ -152,7 +152,7 @@ public interface Type extends Mirror { * Returns the name of this type. The result is of the same form as * the name returned by {@link Class#getName()}. * The returned name may not be a - * binary name. + * binary name. * * @return the name of this type */ diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java b/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java index e236da0838a..ae2fe364bfb 100644 --- a/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java +++ b/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java @@ -44,7 +44,7 @@ public interface ClassUnloadEvent extends Event { /** * Returns the {@linkplain com.sun.jdi.Type#name() name of the class} * that has been unloaded. The returned string may not be a - * binary name. + * binary name. * * @see Class#getName() */ diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index c56dc1beb12..0d99cc3b0b2 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStream; import java.io.PrintStream; +import java.net.URI; import java.nio.charset.Charset; import java.time.Instant; import java.util.ArrayList; @@ -50,6 +51,9 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; import jdk.internal.shellsupport.doc.JavadocFormatter; import jdk.internal.jshell.tool.StopDetectingInputStream.State; @@ -974,6 +978,15 @@ class ConsoleIOContext extends IOContext { int pendingBraces = 0; com.sun.tools.javac.util.Context ctx = new com.sun.tools.javac.util.Context(); + SimpleJavaFileObject source = new SimpleJavaFileObject(URI.create("mem://snippet"), + JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return code; + } + }; + ctx.put(DiagnosticListener.class, d -> {}); + com.sun.tools.javac.util.Log.instance(ctx).useSource(source); com.sun.tools.javac.parser.ScannerFactory scannerFactory = com.sun.tools.javac.parser.ScannerFactory.instance(ctx); com.sun.tools.javac.parser.Scanner scanner = diff --git a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java index cbdeddbfba4..d8074ddcbea 100644 --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -636,13 +636,18 @@ public final class Unsafe { * @see #getInt(Object, long) */ @ForceInline + @SuppressWarnings("preview") public long objectFieldOffset(Field f) { if (f == null) { throw new NullPointerException(); } - if (f.getDeclaringClass().isHidden()) { + Class declaringClass = f.getDeclaringClass(); + if (declaringClass.isHidden()) { throw new UnsupportedOperationException("can't get field offset on a hidden class: " + f); } + if (declaringClass.isRecord()) { + throw new UnsupportedOperationException("can't get field offset on a record (preview): " + f); + } return theInternalUnsafe.objectFieldOffset(f); } @@ -664,13 +669,18 @@ public final class Unsafe { * @see #getInt(Object, long) */ @ForceInline + @SuppressWarnings("preview") public long staticFieldOffset(Field f) { if (f == null) { throw new NullPointerException(); } - if (f.getDeclaringClass().isHidden()) { + Class declaringClass = f.getDeclaringClass(); + if (declaringClass.isHidden()) { throw new UnsupportedOperationException("can't get field offset on a hidden class: " + f); } + if (declaringClass.isRecord()) { + throw new UnsupportedOperationException("can't get field offset on a record (preview): " + f); + } return theInternalUnsafe.staticFieldOffset(f); } @@ -685,13 +695,18 @@ public final class Unsafe { * this class. */ @ForceInline + @SuppressWarnings("preview") public Object staticFieldBase(Field f) { if (f == null) { throw new NullPointerException(); } - if (f.getDeclaringClass().isHidden()) { + Class declaringClass = f.getDeclaringClass(); + if (declaringClass.isHidden()) { throw new UnsupportedOperationException("can't get base address on a hidden class: " + f); } + if (declaringClass.isRecord()) { + throw new UnsupportedOperationException("can't get base address on a record (preview): " + f); + } return theInternalUnsafe.staticFieldBase(f); } diff --git a/src/jdk.zipfs/share/classes/module-info.java b/src/jdk.zipfs/share/classes/module-info.java index f74a926c239..dcb2545b74a 100644 --- a/src/jdk.zipfs/share/classes/module-info.java +++ b/src/jdk.zipfs/share/classes/module-info.java @@ -234,9 +234,9 @@ import java.util.Set; * null/unset * * A value representing the version entry to use when accessing a - * + * * multi-release JAR. If the JAR is not a - * + * * multi-release JAR, the value will be ignored and the JAR will be * considered un-versioned. *

    diff --git a/test/hotspot/jtreg/compiler/stringopts/TestLongStringConcat.java b/test/hotspot/jtreg/compiler/stringopts/TestLongStringConcat.java new file mode 100644 index 00000000000..a1cb9f774d1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/stringopts/TestLongStringConcat.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8237950 + * @summary Test very long chain of StringBuilder append calls. + * @run main/othervm -Xbatch compiler.stringopts.TestLongStringConcat + */ + +package compiler.stringopts; + +public class TestLongStringConcat { + + public static String test() { + return (new StringBuilder("")).append("1").append("2").append("3").append("4"). + append("5").append("6").append("7").append("8").append("9").append("10"). + append("11").append("12").append("13").append("14").append("15").append("16"). + append("17").append("18").append("19").append("20").append("21").append("22"). + append("23").append("24").append("25").append("26").append("27").append("28"). + append("29").append("30").append("31").append("32").append("33").append("34"). + append("35").append("36").append("37").append("38").append("39").append("40"). + append("41").append("42").append("43").append("44").append("45").append("46"). + append("47").append("48").append("49").append("50").append("51").append("52"). + append("53").append("54").append("55").append("56").append("57").append("58"). + append("59").append("60").append("61").append("62").append("63").append("64"). + append("65").append("66").append("67").append("68").append("69").append("70"). + append("71").append("72").append("73").append("74").append("75").append("76"). + append("77").append("78").append("79").append("80").append("81").append("82"). + append("83").append("84").append("85").append("86").append("87").append("88"). + append("89").append("90").append("91").append("92").append("93").append("94"). + append("95").append("96").append("97").append("98").append("99").append("100"). + append("101").append("102").append("103").append("104").append("105"). + append("106").append("107").append("108").append("109").append("110"). + append("111").append("112").append("113").append("114").append("115"). + append("116").append("117").append("118").append("119").append("120"). + append("121").append("122").append("123").append("124").append("125"). + append("126").append("127").append("128").append("129").append("130"). + append("131").append("132").append("133").append("134").append("135"). + append("136").append("137").append("138").append("139").append("140"). + append("141").append("142").append("143").append("144").append("145"). + append("146").append("147").append("148").append("149").append("150"). + append("151").append("152").append("153").append("154").append("155"). + append("156").append("157").append("158").append("159").append("160"). + append("161").append("162").append("163").append("164").append("165"). + append("166").append("167").append("168").append("169").append("170"). + append("171").append("172").append("173").append("174").append("175"). + append("176").append("177").append("178").append("179").append("180"). + append("181").append("182").append("183").append("184").append("185"). + append("186").append("187").append("188").append("189").append("190"). + append("191").append("192").append("193").append("194").append("195"). + append("196").append("197").append("198").append("199").append("200"). + toString(); + } + + public static void main(String[] args) { + for (int i = 0; i < 100_000; ++i) { + test(); + } + } +} diff --git a/test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/SuppressMessagesTest.java b/test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/SuppressMessagesTest.java index b791d5872cb..b6d5acc7a46 100644 --- a/test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/SuppressMessagesTest.java +++ b/test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/SuppressMessagesTest.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2019 SAP SE. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,12 @@ /** * @test - * @summary Test that the default of flag ShowCodeDetailsInExceptionMessages is 'false', - * i.e., make sure the VM does not print the message on default. + * @summary Test that the default of flag ShowCodeDetailsInExceptionMessages is 'true', + * i.e., make sure the VM does print the message by default. * @bug 8218628 * @library /test/lib * @compile -g SuppressMessagesTest.java - * @run main/othervm SuppressMessagesTest noMessage + * @run main/othervm SuppressMessagesTest printMessage */ /** * @test diff --git a/test/hotspot/jtreg/vmTestbase/jit/t/t104/t104.gold b/test/hotspot/jtreg/vmTestbase/jit/t/t104/t104.gold index e3a49f7ec64..64a23127c8b 100644 --- a/test/hotspot/jtreg/vmTestbase/jit/t/t104/t104.gold +++ b/test/hotspot/jtreg/vmTestbase/jit/t/t104/t104.gold @@ -1,2 +1,2 @@ Exception thrown. -java.lang.NullPointerException +java.lang.NullPointerException: Cannot enter synchronized block because "" is null diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/src/Fields.java b/test/jdk/java/lang/invoke/unreflect/Fields.java similarity index 100% rename from test/jdk/java/lang/invoke/defineHiddenClass/src/Fields.java rename to test/jdk/java/lang/invoke/unreflect/Fields.java diff --git a/test/jdk/java/lang/invoke/unreflect/TEST.properties b/test/jdk/java/lang/invoke/unreflect/TEST.properties new file mode 100644 index 00000000000..2ab57ceb5d6 --- /dev/null +++ b/test/jdk/java/lang/invoke/unreflect/TEST.properties @@ -0,0 +1,24 @@ +# +# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +enablePreview=true diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/UnreflectTest.java b/test/jdk/java/lang/invoke/unreflect/UnreflectTest.java similarity index 86% rename from test/jdk/java/lang/invoke/defineHiddenClass/UnreflectTest.java rename to test/jdk/java/lang/invoke/unreflect/UnreflectTest.java index f1bf40c7906..206287c57c6 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/UnreflectTest.java +++ b/test/jdk/java/lang/invoke/unreflect/UnreflectTest.java @@ -23,9 +23,10 @@ /** * @test - * @compile src/Fields.java - * @run testng/othervm UnreflectTest - * @summary Test Lookup::unreflectSetter and Lookup::unreflectVarHandle + * @bug 8238358 8247444 + * @run testng/othervm --enable-preview UnreflectTest + * @summary Test Lookup::unreflectSetter and Lookup::unreflectVarHandle on + * trusted final fields (declared in hidden classes and records) */ import java.io.IOException; @@ -89,6 +90,24 @@ public class UnreflectTest { readWriteAccessibleObject(hiddenClass, "NON_FINAL", o, false); } + static record TestRecord(int i) { + static final Object STATIC_FINAL = new Object(); + static Object STATIC_NON_FINAL = new Object(); + } + + /* + * Test Lookup::unreflectSetter and Lookup::unreflectVarHandle that + * cannot write the value of a non-static final field in a record class + */ + @SuppressWarnings("preview") + public void testFieldsInRecordClass() throws Throwable { + assertTrue(TestRecord.class.isRecord()); + Object o = new TestRecord(1); + readOnlyAccessibleObject(TestRecord.class, "STATIC_FINAL", null, true); + readWriteAccessibleObject(TestRecord.class, "STATIC_NON_FINAL", null, false); + readOnlyAccessibleObject(TestRecord.class, "i", o, true); + } + /* * Verify read-only access via unreflectSetter and unreflectVarHandle */ diff --git a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java index 2ad1547b575..b121bac5ef5 100644 --- a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java +++ b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8235369 8235550 + * @bug 8235369 8235550 8247444 * @summary reflection test for records * @compile --enable-preview -source ${jdk.version} RecordReflectionTest.java * @run testng/othervm --enable-preview RecordReflectionTest @@ -187,4 +187,19 @@ public class RecordReflectionTest { assertEquals(f.getAnnotatedType().getAnnotations().length, 1); assertEquals(f.getAnnotatedType().getAnnotations()[0].toString(), annos[0].toString()); } + + public void testReadOnlyFieldInRecord() throws Throwable { + R2 o = new R2(1, 2); + Class recordClass = R2.class; + String fieldName = "i"; + Field f = recordClass.getDeclaredField(fieldName); + assertTrue(f.trySetAccessible()); + assertTrue(f.get(o) != null); + try { + f.set(o, null); + assertTrue(false, "should fail to set " + fieldName); + } catch (IllegalAccessException e) { + } + } + } diff --git a/test/jdk/sun/misc/UnsafeFieldOffsets.java b/test/jdk/sun/misc/UnsafeFieldOffsets.java index aeaa92206a9..e2c63c350f4 100644 --- a/test/jdk/sun/misc/UnsafeFieldOffsets.java +++ b/test/jdk/sun/misc/UnsafeFieldOffsets.java @@ -22,10 +22,12 @@ */ /* @test + * @bug 8238358 8247444 * @summary Ensure that sun.misc.Unsafe::objectFieldOffset and staticFieldOffset - * throw UnsupportedOperationException on Field of a hidden class + * throw UnsupportedOperationException on Field of a hidden or record class * @modules jdk.unsupported - * @run main UnsafeFieldOffsets + * @compile --enable-preview -source ${jdk.version} UnsafeFieldOffsets.java + * @run testng/othervm --enable-preview UnsafeFieldOffsets */ import sun.misc.Unsafe; @@ -38,6 +40,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + public class UnsafeFieldOffsets { static class Fields { static final Object STATIC_FINAL = new Object(); @@ -45,9 +50,14 @@ public class UnsafeFieldOffsets { final Object FINAL = new Object(); Object NON_FINAL = new Object(); } + record TestRecord(int i) { + static final Object STATIC_FINAL = new Object(); + static Object STATIC_NON_FINAL = new Object(); + } private static Unsafe UNSAFE = getUnsafe(); private static final Class HIDDEN_CLASS = defineHiddenClass(); + private static final Class RECORD_CLASS = TestRecord.class; private static Unsafe getUnsafe() { try { @@ -65,7 +75,7 @@ public class UnsafeFieldOffsets { try { byte[] bytes = Files.readAllBytes(cf); Class c = MethodHandles.lookup().defineHiddenClass(bytes, true).lookupClass(); - assertHiddenClass(c); + assertTrue(c.isHidden()); return c; } catch (IOException e) { throw new UncheckedIOException(e); @@ -74,13 +84,8 @@ public class UnsafeFieldOffsets { } } - public static void main(String[] args) throws Exception { - // non-hidden class - testStaticField(Fields.class, "STATIC_FINAL"); - testStaticField(Fields.class, "STATIC_NON_FINAL"); - testInstanceField(Fields.class, "FINAL"); - testInstanceField(Fields.class, "NON_FINAL"); - + @Test + public void testNormalClass() throws Throwable { // hidden class testStaticField(HIDDEN_CLASS, "STATIC_FINAL"); testStaticField(HIDDEN_CLASS, "STATIC_NON_FINAL"); @@ -88,13 +93,30 @@ public class UnsafeFieldOffsets { testInstanceField(HIDDEN_CLASS, "NON_FINAL"); } + @Test + public void testHiddenClass() throws Throwable { + // hidden class + testStaticField(HIDDEN_CLASS, "STATIC_FINAL"); + testStaticField(HIDDEN_CLASS, "STATIC_NON_FINAL"); + testInstanceField(HIDDEN_CLASS, "FINAL"); + testInstanceField(HIDDEN_CLASS, "NON_FINAL"); + } + + @Test + public void testRecordClass() throws Throwable { + // record class + testRecordStaticField(RECORD_CLASS, "STATIC_FINAL"); + testRecordStaticField(RECORD_CLASS, "STATIC_NON_FINAL"); + testRecordInstanceField(RECORD_CLASS, "i"); + } + private static void testStaticField(Class c, String name) throws Exception { Field f = c.getDeclaredField(name); try { UNSAFE.staticFieldOffset(f); - assertNonHiddenClass(c); + assertFalse(c.isHidden(), "Expected UOE thrown: " + c); } catch (UnsupportedOperationException e) { - assertHiddenClass(c); + assertTrue(c.isHidden(), "Expected hidden class: " + c); } } @@ -102,19 +124,31 @@ public class UnsafeFieldOffsets { Field f = c.getDeclaredField(name); try { UNSAFE.objectFieldOffset(f); - assertNonHiddenClass(c); + assertFalse(c.isHidden(), "Expected UOE thrown: " + c); } catch (UnsupportedOperationException e) { - assertHiddenClass(c); + assertTrue(c.isHidden(), "Expected hidden class: " + c); } } - private static void assertNonHiddenClass(Class c) { - if (c.isHidden()) - throw new RuntimeException("Expected UOE but not thrown: " + c); + @SuppressWarnings("preview") + private static void testRecordStaticField(Class c, String name) throws Exception { + Field f = c.getDeclaredField(name); + try { + UNSAFE.staticFieldOffset(f); + assertFalse(c.isRecord(), "Expected UOE thrown: " + c); + } catch (UnsupportedOperationException e) { + assertTrue(c.isRecord(), "Expected record class: " + c); + } } - private static void assertHiddenClass(Class c) { - if (!c.isHidden()) - throw new RuntimeException("Expected hidden class but is not: " + c); + @SuppressWarnings("preview") + private static void testRecordInstanceField(Class c, String name) throws Exception { + Field f = c.getDeclaredField(name); + try { + UNSAFE.objectFieldOffset(f); + assertFalse(c.isRecord(), "Expected UOE thrown: " + c); + } catch (UnsupportedOperationException e) { + assertTrue(c.isRecord(), "Expected record class: " + c); + } } } diff --git a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java index 05a437a0286..81732538029 100644 --- a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java +++ b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java @@ -24,7 +24,7 @@ /* * @test * @bug 4927552 8026567 8071982 8162674 8175200 8175218 8183511 8186332 - * 8169819 8074407 8191030 8182765 8184205 + * 8169819 8074407 8191030 8182765 8184205 8243533 * @summary test generated docs for deprecated items * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -164,9 +164,28 @@ public class TestDeprecatedDocs extends JavadocTester { """, """ -

    Deprecated. +
    Deprecated, for removal: This \ + API element is subject to removal in a future version.
    class_test4 passes.
    + """, + """ + +
    Deprecated. +
    class_test5 passes.
    +
    + """, + """ + +
    Deprecated. +
    class_test6 passes.
    +
    + """, + """ + +
    Deprecated. +
    class_test7 passes.
    +
    """); checkOutput("pkg/TestClass.html", false, @@ -355,6 +374,78 @@ public class TestDeprecatedDocs extends JavadocTester { -
    """); + """, + """ +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """, + """ +
    +
    Methods
    MethodDescription
    pkg.DeprecatedClassByAnnotation.method()
    pkg.TestAnnotationType.optional() +
    annotation_test2 passes.
    +
    pkg.TestAnnotationType.required() +
    annotation_test3 passes.
    +
    pkg.TestClass.method() +
    class_test5 passes. This is the second sentence of deprecated description for a method.
    +
    pkg.TestClass.overloadedMethod​(int) +
    class_test7 passes. Overloaded method 2.
    +
    pkg.TestClass.overloadedMethod​(String) +
    class_test6 passes. Overloaded method 1.
    +
    + + + + + + + + + + + + + + + + + + + + """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/pkg/TestClass.java b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/pkg/TestClass.java index 0fb178252ce..82f7ab2e81f 100644 --- a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/pkg/TestClass.java +++ b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/pkg/TestClass.java @@ -41,7 +41,23 @@ public class TestClass { public TestClass() {} /** - * @deprecated class_test4 passes. This is the second sentence of deprecated description for a method. + * @deprecated class_test4 passes. Overloaded constructor. + */ + @Deprecated(forRemoval=true) + public TestClass(String s) {} + + /** + * @deprecated class_test5 passes. This is the second sentence of deprecated description for a method. */ public void method() {} + + /** + * @deprecated class_test6 passes. Overloaded method 1. + */ + public void overloadedMethod(String s) {} + + /** + * @deprecated class_test7 passes. Overloaded method 2. + */ + public void overloadedMethod(int i) {} } diff --git a/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java b/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java new file mode 100644 index 00000000000..a3ee65ac70d --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testHelpPage/TestHelpPage.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8246078 + * @library ../../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build javadoc.tester.* + * @run main TestHelpPage + */ + +import javadoc.tester.JavadocTester; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TestHelpPage extends JavadocTester { + + public static void main(String... args) throws Exception { + TestHelpPage tester = new TestHelpPage(); + tester.runTests(); + } + + @Test + public void test() { + + setOutputDirectoryCheck(DirectoryCheck.NONE); + setAutomaticCheckLinks(false); + setAutomaticCheckAccessibility(false); + + javadoc("--version"); + List lines = getOutputLines(Output.OUT); + System.out.println("lines: " + Arrays.toString(lines.toArray())); + String firstLine = lines.get(0); + Matcher m = Pattern.compile("javadoc\\s+(.*)").matcher(firstLine); + m.matches(); + String vstr = m.group(1); + System.out.printf("vstr='%s'%n", vstr); + Runtime.Version v = Runtime.Version.parse(vstr); + System.out.printf("v=%s, v.feature()=%s%n", v, v.feature()); + + javadoc("-d", "out", + "-sourcepath", testSrc, + testSrc("TestHelpPage.java")); + checkExit(Exit.OK); + + checking("Reference to a particular version"); + Pattern searchSpecLink = Pattern.compile( + "\\Q\\E"); + + String helpContents = readOutputFile("help-doc.html"); + Matcher m2 = searchSpecLink.matcher(helpContents); + if (!m2.find()) { + failed("Reference not found: " + helpContents); + return; + } + + if (!String.valueOf(v.feature()).equals(m2.group(1))) { + failed("Reference to a wrong version: " + m2.group(1)); + return; + } + + boolean foundMore = false; + while (m2.find()) { + // print all found before failing + foundMore = true; + System.out.println(m2.group(0)); + } + if (foundMore) { + failed("Multiple references: " + helpContents); + } else { + passed("All good"); + } + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java b/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java index 324f13b9d01..a416b697844 100644 --- a/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java +++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModulePackages.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8178070 8196201 8184205 8246429 + * @bug 8178070 8196201 8184205 8246429 8198705 * @summary Test packages table in module summary pages * @library /tools/lib ../../lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -167,6 +167,14 @@ public class TestModulePackages extends JavadocTester {
    Package p
    """); + checkOutput("type-search-index.js", true, + """ + {"p":"p","m":"m","l":"C"},{"p":"p","m":"o","l":"C"}"""); + checkOutput("member-search-index.js", true, + """ + {"m":"m","p":"p","c":"C","l":"C()","u":"%3Cinit%3E()"}""", + """ + {"m":"o","p":"p","c":"C","l":"C()","u":"%3Cinit%3E()"}"""); } @Test diff --git a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java index c97128c8ad9..18dd2b1c462 100644 --- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java +++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java @@ -726,14 +726,16 @@ public class TestSearch extends JavadocTester { return ui.item.l + slash; } else if (ui.item.category === catPackages && ui.item.m) { return ui.item.m + slash; - } else if ((ui.item.category === catTypes && ui.item.p) || ui.item.category === catMembers) { - $.each(packageSearchIndex, function(index, item) { - if (item.m && ui.item.p == item.l) { - urlPrefix = item.m + slash; - } - }); - return urlPrefix; - } else { + } else if (ui.item.category === catTypes || ui.item.category === catMembers) { + if (ui.item.m) { + urlPrefix = ui.item.m + slash; + } else { + $.each(packageSearchIndex, function(index, item) { + if (item.m && ui.item.p === item.l) { + urlPrefix = item.m + slash; + } + }); + } return urlPrefix; } return urlPrefix; diff --git a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java index d29adf5622d..83b70b37f86 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java @@ -24,7 +24,7 @@ /* * @test * @bug 8005091 8009686 8025633 8026567 6469562 8071982 8071984 8162363 8175200 8186332 8182765 - * 8187288 + * 8187288 8241969 * @summary Make sure that type annotations are displayed correctly * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -335,6 +335,35 @@ public class TestTypeAnnotations extends JavadocTester { tation in typeannos">@WldB("m") java.lang.String> returnWcExtends()"""); + checkOutput("typeannos/SelfTest.html", true, + """ +
    MyList<@WldA ?> returnWcExtends\ + ()
    """, + """ +
    MyList<@WldA ? extends @WldA MyList<@WldB("m") ?>>&\ + nbsp;complex()
    """); + + checkOutput("typeannos/SelfWithValue.html", true, + """ +
    MyList<@WldB("m") ?> returnWcEx\ + tends()
    """, + """ +
    MyList<@WldB("m") ? extends MyList<@WldB\ + ("m") ? super java.lang.String>> com\ + plex()
    """); + + // Test for receiver annotations (Receivers.java). checkOutput("typeannos/DefaultUnmodified.html", true, """ diff --git a/test/langtools/jdk/javadoc/tool/doclint/DocLintTest.java b/test/langtools/jdk/javadoc/tool/doclint/DocLintTest.java index 7c16d266a31..295873ddd21 100644 --- a/test/langtools/jdk/javadoc/tool/doclint/DocLintTest.java +++ b/test/langtools/jdk/javadoc/tool/doclint/DocLintTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8004834 8007610 8129909 8182765 + * @bug 8004834 8007610 8129909 8182765 8247815 * @summary Add doclint support into javadoc * @modules jdk.compiler/com.sun.tools.javac.main */ @@ -178,7 +178,7 @@ public class DocLintTest { Main.Result.OK, EnumSet.of(Message.DL_WRN12)); - test(List.of(htmlVersion, rawDiags, "-Xdoclint:syntax"), + test(List.of(htmlVersion, rawDiags, "-Xdoclint:missing"), Main.Result.OK, EnumSet.of(Message.DL_WRN12)); @@ -186,7 +186,7 @@ public class DocLintTest { Main.Result.ERROR, EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); - test(List.of(htmlVersion, rawDiags, "-Xdoclint:syntax", "-private"), + test(List.of(htmlVersion, rawDiags, "-Xdoclint:missing,syntax", "-private"), Main.Result.ERROR, EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); diff --git a/test/langtools/jdk/jshell/IndentUITest.java b/test/langtools/jdk/jshell/IndentUITest.java index efa993ad359..4f39cbbfc42 100644 --- a/test/langtools/jdk/jshell/IndentUITest.java +++ b/test/langtools/jdk/jshell/IndentUITest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8241950 + * @bug 8241950 8247932 * @summary Check the UI behavior of indentation * @library /tools/lib * @modules @@ -70,6 +70,11 @@ public class IndentUITest extends UITesting { waitOutput(out, "^void test2\\(\\) \\{\n" + CONTINUATION_PROMPT + " System.err.println\\(1\\);\n" + CONTINUATION_PROMPT + "\\}"); + inputSink.write(INTERRUPT); + waitOutput(out, "\u001B\\[\\?2004h" + PROMPT); + inputSink.write("\"\"\"\n"); + waitOutput(out, "^\"\"\"\n" + + CONTINUATION_PROMPT); }); } diff --git a/test/langtools/jdk/jshell/ToolSimpleTest.java b/test/langtools/jdk/jshell/ToolSimpleTest.java index dc840d1445d..d51efae0703 100644 --- a/test/langtools/jdk/jshell/ToolSimpleTest.java +++ b/test/langtools/jdk/jshell/ToolSimpleTest.java @@ -132,7 +132,7 @@ public class ToolSimpleTest extends ReplToolTesting { + "| Caused by: java.io.IOException: bar\n" + "| at n (#2:1)\n" + "| ...\n" - + "| Caused by: java.lang.NullPointerException\n" + + "| Caused by: java.lang.NullPointerException: Cannot invoke \"String.toString()\" because \"null\" is null\n" + "| at p (#1:1)\n" + "| ..."), (a) -> assertCommand(a, "/drop p", diff --git a/test/langtools/tools/doclint/EmptyAuthorTest.java b/test/langtools/tools/doclint/EmptyAuthorTest.java index 0a5db470e6b..ecd7e91271c 100644 --- a/test/langtools/tools/doclint/EmptyAuthorTest.java +++ b/test/langtools/tools/doclint/EmptyAuthorTest.java @@ -1,11 +1,11 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptyAuthorTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptyAuthorTest.out EmptyAuthorTest.java + * @run main DocLintTester -Xmsgs:-missing EmptyAuthorTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptyAuthorTest.out EmptyAuthorTest.java */ /** @author */ diff --git a/test/langtools/tools/doclint/EmptyExceptionTest.java b/test/langtools/tools/doclint/EmptyExceptionTest.java index 6a5db240020..8a93ec69d02 100644 --- a/test/langtools/tools/doclint/EmptyExceptionTest.java +++ b/test/langtools/tools/doclint/EmptyExceptionTest.java @@ -1,15 +1,15 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptyExceptionTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptyExceptionTest.out EmptyExceptionTest.java + * @run main DocLintTester -Xmsgs:-missing EmptyExceptionTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptyExceptionTest.out EmptyExceptionTest.java */ /** . */ public class EmptyExceptionTest { /** @exception NullPointerException */ - int emptyException() throws NullPointerException { } + void emptyException() throws NullPointerException { } } diff --git a/test/langtools/tools/doclint/EmptyParamTest.java b/test/langtools/tools/doclint/EmptyParamTest.java index 37f76ae075c..ce92ecc19e5 100644 --- a/test/langtools/tools/doclint/EmptyParamTest.java +++ b/test/langtools/tools/doclint/EmptyParamTest.java @@ -1,15 +1,15 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptyParamTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptyParamTest.out EmptyParamTest.java + * @run main DocLintTester -Xmsgs:-missing EmptyParamTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptyParamTest.out EmptyParamTest.java */ /** . */ public class EmptyParamTest { /** @param i */ - int emptyParam(int i) { } + void emptyParam(int i) { } } diff --git a/test/langtools/tools/doclint/EmptyReturnTest.java b/test/langtools/tools/doclint/EmptyReturnTest.java index b0c787fe6fe..34ff7f4cbd8 100644 --- a/test/langtools/tools/doclint/EmptyReturnTest.java +++ b/test/langtools/tools/doclint/EmptyReturnTest.java @@ -1,15 +1,15 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptyReturnTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptyReturnTest.out EmptyReturnTest.java + * @run main DocLintTester -Xmsgs:-missing EmptyReturnTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptyReturnTest.out EmptyReturnTest.java */ /** . */ public class EmptyReturnTest { /** @return */ - int emptyReturn() { } + int emptyReturn() { return 0; } } diff --git a/test/langtools/tools/doclint/EmptySerialDataTest.java b/test/langtools/tools/doclint/EmptySerialDataTest.java index 38c04659910..f6c353069e8 100644 --- a/test/langtools/tools/doclint/EmptySerialDataTest.java +++ b/test/langtools/tools/doclint/EmptySerialDataTest.java @@ -1,11 +1,11 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptySerialDataTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptySerialDataTest.out EmptySerialDataTest.java + * @run main DocLintTester -Xmsgs:-missing EmptySerialDataTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptySerialDataTest.out EmptySerialDataTest.java */ import java.io.ObjectOutputStream; @@ -13,6 +13,10 @@ import java.io.Serializable; /** . */ public class EmptySerialDataTest implements Serializable { - /** @serialData */ + /** + * . + * @serialData + * @param s . + */ private void writeObject(ObjectOutputStream s) { } } diff --git a/test/langtools/tools/doclint/EmptySerialDataTest.out b/test/langtools/tools/doclint/EmptySerialDataTest.out index f34a77a144c..dcfa059796d 100644 --- a/test/langtools/tools/doclint/EmptySerialDataTest.out +++ b/test/langtools/tools/doclint/EmptySerialDataTest.out @@ -1,5 +1,5 @@ -EmptySerialDataTest.java:16: warning: no description for @serialData - /** @serialData */ - ^ +EmptySerialDataTest.java:18: warning: no description for @serialData + * @serialData + ^ 1 warning diff --git a/test/langtools/tools/doclint/EmptySerialFieldTest.java b/test/langtools/tools/doclint/EmptySerialFieldTest.java index 533370969ab..79789cc6588 100644 --- a/test/langtools/tools/doclint/EmptySerialFieldTest.java +++ b/test/langtools/tools/doclint/EmptySerialFieldTest.java @@ -1,11 +1,11 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptySerialFieldTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptySerialFieldTest.out EmptySerialFieldTest.java + * @run main DocLintTester -Xmsgs:-missing EmptySerialFieldTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptySerialFieldTest.out EmptySerialFieldTest.java */ import java.io.ObjectStreamField; diff --git a/test/langtools/tools/doclint/EmptySinceTest.java b/test/langtools/tools/doclint/EmptySinceTest.java index 4af2249a18c..5992cc9d901 100644 --- a/test/langtools/tools/doclint/EmptySinceTest.java +++ b/test/langtools/tools/doclint/EmptySinceTest.java @@ -1,15 +1,15 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptySinceTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptySinceTest.out EmptySinceTest.java + * @run main DocLintTester -Xmsgs:-missing EmptySinceTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptySinceTest.out EmptySinceTest.java */ /** . */ public class EmptySinceTest { /** @since */ - int emptySince() { } + void emptySince() { } } diff --git a/test/langtools/tools/doclint/EmptyVersionTest.java b/test/langtools/tools/doclint/EmptyVersionTest.java index 43590818cc0..e2c3799410f 100644 --- a/test/langtools/tools/doclint/EmptyVersionTest.java +++ b/test/langtools/tools/doclint/EmptyVersionTest.java @@ -1,15 +1,15 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 + * @bug 8004832 8247815 * @summary Add new doclint package * @modules jdk.compiler/com.sun.tools.doclint * @build DocLintTester - * @run main DocLintTester -Xmsgs:-syntax EmptyVersionTest.java - * @run main DocLintTester -Xmsgs:syntax -ref EmptyVersionTest.out EmptyVersionTest.java + * @run main DocLintTester -Xmsgs:-missing EmptyVersionTest.java + * @run main DocLintTester -Xmsgs:missing -ref EmptyVersionTest.out EmptyVersionTest.java */ /** . */ public class EmptyVersionTest { /** @version */ - int missingVersion() { } + void missingVersion() { } } diff --git a/test/langtools/tools/doclint/MultipleDocLintOptionsTest.java b/test/langtools/tools/doclint/MultipleDocLintOptionsTest.java index b85af8e22ca..6a306cf64cb 100644 --- a/test/langtools/tools/doclint/MultipleDocLintOptionsTest.java +++ b/test/langtools/tools/doclint/MultipleDocLintOptionsTest.java @@ -1,8 +1,8 @@ /* * @test /nodynamiccopyright/ - * @bug 8198552 + * @bug 8198552 8247815 * @summary Check that -Xdoclint: option can be specified multiple times - * @compile/fail/ref=MultipleDocLintOptionsTest.out -Xdoclint:html -Xdoclint:syntax -XDrawDiagnostics MultipleDocLintOptionsTest.java + * @compile/fail/ref=MultipleDocLintOptionsTest.out -Xdoclint:html -Xdoclint:missing -XDrawDiagnostics MultipleDocLintOptionsTest.java */ /** */ diff --git a/test/langtools/tools/javac/doclint/DocLintTest.java b/test/langtools/tools/javac/doclint/DocLintTest.java index 471bd084585..110c002c277 100644 --- a/test/langtools/tools/javac/doclint/DocLintTest.java +++ b/test/langtools/tools/javac/doclint/DocLintTest.java @@ -135,7 +135,7 @@ public class DocLintTest { Main.Result.OK, EnumSet.of(Message.DL_WRN12)); - test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), + test(Arrays.asList(rawDiags, "-Xdoclint:syntax,missing"), Main.Result.ERROR, EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); diff --git a/test/langtools/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest2.java b/test/langtools/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest2.java index aa17b0d8530..02e1d95cf2f 100644 --- a/test/langtools/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest2.java +++ b/test/langtools/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest2.java @@ -23,45 +23,58 @@ /* * @test - * @bug 8234729 + * @bug 8234729 8242214 * @summary Javac should eagerly change code generation for method references to avert IllegalAccessError in future. + * @compile ProtectedInaccessibleMethodRefTest2.java * @run main ProtectedInaccessibleMethodRefTest2 */ import pack.I; import pack.J; +import java.lang.reflect.Method; import java.nio.file.Path; import java.nio.file.Paths; import java.util.function.Function; -import java.lang.reflect.Method; -import java.util.concurrent.Callable; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; public final class ProtectedInaccessibleMethodRefTest2 extends I { public static void main(String... args) { ProtectedInaccessibleMethodRefTest2 m = new ProtectedInaccessibleMethodRefTest2(); m.test(Paths.get("test")); - // Verify that the method reference has been folded into a lambda. - boolean lambdaFound = false; + // Verify that the method references have been folded into lambdas: + Set methodNames = new HashSet<>(); for (Method meth : ProtectedInaccessibleMethodRefTest2.class.getDeclaredMethods()) { - if (meth.getName().equals("lambda$test$0")) { - lambdaFound = true; - break; - } + methodNames.add(meth.getName()); } - if (!lambdaFound) { + List expectedMethods = + Arrays.asList("lambda$test$0", "lambda$test$1", "lambda$test$2"); + if (!methodNames.containsAll(expectedMethods)) { throw new AssertionError("Did not find evidence of new code generation"); } } void test(Path outputDir) { - Sub c = new Sub(this::readFile); - c.check(outputDir); + Sub c1 = new Sub(this::readFile); + c1.check(outputDir); + Sub c2 = new Sub(ProtectedInaccessibleMethodRefTest2::readFile, this); + c2.check(outputDir); + Sub c3 = new Sub(ProtectedInaccessibleMethodRefTest2::readFile2); + c3.check(outputDir); } + public class Sub extends J { Sub(Function fileReader) { super(fileReader); } + Sub(BiFunction fileReader, + ProtectedInaccessibleMethodRefTest2 instance) { + super(p -> fileReader.apply(instance, p)); + } } } diff --git a/test/langtools/tools/javac/lambda/methodReference/pack/I.java b/test/langtools/tools/javac/lambda/methodReference/pack/I.java index 02f6356a786..018ed463d92 100644 --- a/test/langtools/tools/javac/lambda/methodReference/pack/I.java +++ b/test/langtools/tools/javac/lambda/methodReference/pack/I.java @@ -29,4 +29,8 @@ public class I { protected String readFile(Path file) { return file.toString(); } + + protected static String readFile2(Path file) { + return file.toString(); + } }
    Constructors
    ConstructorDescription
    pkg.DeprecatedClassByAnnotation()
    pkg.TestClass() +
    class_test3 passes. This is the second sentence of deprecated description for a constructor.
    +
    pkg.TestClass​(String) +
    class_test4 passes. Overloaded constructor.
    +