From a8245e14333db3bf638aae114ffb77ca0cc0fa9c Mon Sep 17 00:00:00 2001 From: Akhilesh Singh Date: Fri, 8 Oct 2021 11:08:53 +0530 Subject: [PATCH] [NETBEANS-5828] : NB-Javac Upgrade to JDK-17 (#29) * [NETBEANS-5828] : Resolved auto merge conflicts from JDK-17+32 --- .../nb-javac/nbproject/project.properties | 2 +- .../javax/lang/model/SourceVersion.java | 23 +- .../javax/lang/model/element/Modifier.java | 24 +- .../javax/lang/model/element/TypeElement.java | 12 +- .../AbstractAnnotationValueVisitor14.java | 2 +- .../model/util/AbstractElementVisitor14.java | 2 +- .../model/util/AbstractTypeVisitor14.java | 2 +- .../lang/model/util/ElementKindVisitor14.java | 2 +- .../lang/model/util/ElementScanner14.java | 2 +- .../javax/lang/model/util/Elements.java | 18 +- .../util/SimpleAnnotationValueVisitor14.java | 2 +- .../model/util/SimpleElementVisitor14.java | 2 +- .../lang/model/util/SimpleTypeVisitor14.java | 2 +- .../lang/model/util/TypeKindVisitor14.java | 2 +- .../javax/tools/StandardJavaFileManager.java | 36 +- .../classes/javax/tools/ToolProvider.java | 3 +- .../com/sun/source/tree/CaseLabelTree.java | 36 ++ .../classes/com/sun/source/tree/CaseTree.java | 12 + .../com/sun/source/tree/ClassTree.java | 13 +- .../sun/source/tree/CompilationUnitTree.java | 28 +- .../sun/source/tree/DefaultCaseLabelTree.java | 35 ++ .../com/sun/source/tree/ExpressionTree.java | 2 +- .../sun/source/tree/GuardedPatternTree.java | 50 ++ .../source/tree/ParenthesizedPatternTree.java | 49 ++ .../com/sun/source/tree/PatternTree.java | 2 +- .../classes/com/sun/source/tree/Tree.java | 26 + .../com/sun/source/tree/TreeVisitor.java | 32 ++ .../com/sun/source/util/DocTreeFactory.java | 12 +- .../com/sun/source/util/DocTreeScanner.java | 179 +++++-- .../classes/com/sun/source/util/DocTrees.java | 1 + .../sun/source/util/SimpleDocTreeVisitor.java | 142 +++-- .../sun/source/util/SimpleTreeVisitor.java | 340 ++++++++++-- .../classes/com/sun/source/util/TreePath.java | 4 +- .../com/sun/source/util/TreeScanner.java | 369 ++++++++++--- .../com/sun/tools/doclint/DocLint.java | 2 - .../tools/javac/api/ClientCodeWrapper.java | 6 +- .../com/sun/tools/javac/api/JavacScope.java | 7 +- .../sun/tools/javac/api/JavacTaskImpl.java | 4 +- .../sun/tools/javac/api/JavacTaskPool.java | 16 +- .../com/sun/tools/javac/api/JavacTool.java | 12 +- .../com/sun/tools/javac/api/JavacTrees.java | 22 +- .../sun/tools/javac/code/AnnoConstruct.java | 4 +- .../com/sun/tools/javac/code/Attribute.java | 4 +- .../com/sun/tools/javac/code/ClassFinder.java | 2 +- .../com/sun/tools/javac/code/Directive.java | 4 +- .../com/sun/tools/javac/code/Flags.java | 22 +- .../com/sun/tools/javac/code/Lint.java | 10 +- .../com/sun/tools/javac/code/Preview.java | 57 +- .../com/sun/tools/javac/code/Scope.java | 55 +- .../com/sun/tools/javac/code/Source.java | 22 +- .../com/sun/tools/javac/code/Symbol.java | 27 +- .../sun/tools/javac/code/SymbolMetadata.java | 4 +- .../com/sun/tools/javac/code/Symtab.java | 17 +- .../com/sun/tools/javac/code/Type.java | 20 +- .../javac/code/TypeAnnotationPosition.java | 20 +- .../sun/tools/javac/code/TypeAnnotations.java | 13 +- .../com/sun/tools/javac/code/Types.java | 100 ++-- .../com/sun/tools/javac/comp/Analyzer.java | 24 +- .../com/sun/tools/javac/comp/Annotate.java | 18 +- .../sun/tools/javac/comp/ArgumentAttr.java | 20 +- .../com/sun/tools/javac/comp/Attr.java | 298 ++++++++--- .../com/sun/tools/javac/comp/AttrRecover.java | 2 +- .../com/sun/tools/javac/comp/Check.java | 167 ++++-- .../com/sun/tools/javac/comp/ConstFold.java | 3 +- .../sun/tools/javac/comp/DeferredAttr.java | 110 ++-- .../com/sun/tools/javac/comp/Enter.java | 29 + .../com/sun/tools/javac/comp/Flow.java | 227 +++++--- .../com/sun/tools/javac/comp/Infer.java | 7 +- .../tools/javac/comp/InferenceContext.java | 8 +- .../sun/tools/javac/comp/LambdaToMethod.java | 31 +- .../com/sun/tools/javac/comp/Lower.java | 210 ++++++-- .../javac/comp/MatchBindingsComputer.java | 43 +- .../com/sun/tools/javac/comp/MemberEnter.java | 4 + .../com/sun/tools/javac/comp/Modules.java | 3 +- .../com/sun/tools/javac/comp/Repair.java | 11 +- .../com/sun/tools/javac/comp/Resolve.java | 98 ++-- .../sun/tools/javac/comp/TransPatterns.java | 499 ++++++++++++++++-- .../com/sun/tools/javac/comp/TransTypes.java | 23 +- .../com/sun/tools/javac/comp/TreeDiffer.java | 8 +- .../com/sun/tools/javac/comp/TypeEnter.java | 11 +- .../com/sun/tools/javac/file/JRTIndex.java | 2 +- .../tools/javac/file/JavacFileManager.java | 23 +- .../com/sun/tools/javac/file/Locations.java | 2 +- .../sun/tools/javac/file/PathFileObject.java | 2 +- .../sun/tools/javac/file/RelativePath.java | 2 +- .../com/sun/tools/javac/jvm/CRTable.java | 7 +- .../com/sun/tools/javac/jvm/ClassFile.java | 77 +-- .../com/sun/tools/javac/jvm/ClassReader.java | 60 ++- .../com/sun/tools/javac/jvm/ClassWriter.java | 11 +- .../classes/com/sun/tools/javac/jvm/Code.java | 2 +- .../classes/com/sun/tools/javac/jvm/Gen.java | 39 +- .../com/sun/tools/javac/jvm/JNIWriter.java | 25 +- .../com/sun/tools/javac/jvm/PoolConstant.java | 2 +- .../com/sun/tools/javac/jvm/PoolWriter.java | 2 +- .../com/sun/tools/javac/jvm/Target.java | 13 +- .../com/sun/tools/javac/launcher/Main.java | 8 +- .../com/sun/tools/javac/main/Arguments.java | 12 +- .../javac/main/DelegatingJavaFileManager.java | 2 +- .../sun/tools/javac/main/JavaCompiler.java | 47 +- .../com/sun/tools/javac/main/Main.java | 2 +- .../com/sun/tools/javac/main/Option.java | 54 +- .../javac/model/AnnotationProxyMaker.java | 2 +- .../tools/javac/model/FilteredMemberList.java | 3 +- .../sun/tools/javac/model/JavacElements.java | 8 +- .../com/sun/tools/javac/model/JavacTypes.java | 2 +- .../tools/javac/parser/DocCommentParser.java | 24 +- .../sun/tools/javac/parser/JavaTokenizer.java | 13 +- .../sun/tools/javac/parser/JavacParser.java | 358 +++++++++---- .../tools/javac/parser/ReferenceParser.java | 4 +- .../tools/javac/parser/ScannerFactory.java | 2 +- .../com/sun/tools/javac/parser/Tokens.java | 57 +- .../sun/tools/javac/parser/UnicodeReader.java | 21 +- .../javac/platform/JDKPlatformProvider.java | 4 +- .../tools/javac/processing/JavacFiler.java | 10 +- .../JavacProcessingEnvironment.java | 9 +- .../processing/JavacRoundEnvironment.java | 12 +- .../javac/processing/PrintingProcessor.java | 80 ++- .../javac/resources/CompilerProperties.java | 165 ++++-- .../tools/javac/resources/compiler.properties | 89 +++- .../tools/javac/resources/javac.properties | 16 +- .../com/sun/tools/javac/tree/DocPretty.java | 4 +- .../com/sun/tools/javac/tree/JCTree.java | 208 +++++++- .../com/sun/tools/javac/tree/Pretty.java | 53 +- .../com/sun/tools/javac/tree/TreeCopier.java | 25 +- .../com/sun/tools/javac/tree/TreeInfo.java | 87 ++- .../com/sun/tools/javac/tree/TreeMaker.java | 32 +- .../com/sun/tools/javac/tree/TreeScanner.java | 17 +- .../sun/tools/javac/tree/TreeTranslator.java | 20 +- .../util/AbstractDiagnosticFormatter.java | 6 +- .../javac/util/BasicDiagnosticFormatter.java | 2 +- .../com/sun/tools/javac/util/Bits.java | 2 + .../com/sun/tools/javac/util/Constants.java | 6 +- .../com/sun/tools/javac/util/Context.java | 2 +- .../sun/tools/javac/util/Dependencies.java | 12 +- .../tools/javac/util/DiagnosticSource.java | 8 +- .../sun/tools/javac/util/IntHashTable.java | 60 +-- .../com/sun/tools/javac/util/Iterators.java | 2 +- .../sun/tools/javac/util/JCDiagnostic.java | 2 +- .../sun/tools/javac/util/JavacMessages.java | 2 +- .../tools/javac/util/LayoutCharacters.java | 16 +- .../com/sun/tools/javac/util/List.java | 2 +- .../classes/com/sun/tools/javac/util/Log.java | 45 +- .../javac/util/MandatoryWarningHandler.java | 22 +- .../com/sun/tools/javac/util/Names.java | 16 +- .../com/sun/tools/javac/util/Pair.java | 2 +- .../javac/util/RawDiagnosticFormatter.java | 10 +- .../javac/util/RichDiagnosticFormatter.java | 2 +- .../sun/tools/javac/util/SharedNameTable.java | 8 +- .../tools/javac/util/UnsharedNameTable.java | 8 +- .../shellsupport/doc/JavadocFormatter.java | 3 +- src/jdk.compiler/share/man/javac.1 | 7 +- src/jdk.compiler/share/man/serialver.1 | 2 +- .../com/sun/tools/classfile/Instruction.java | 4 + .../com/sun/tools/javap/ClassWriter.java | 4 +- .../com/sun/tools/javap/CodeWriter.java | 2 +- .../classes/com/sun/tools/jdeprscan/Main.java | 10 +- .../com/sun/tools/jdeprscan/scan/Scan.java | 2 +- .../classes/com/sun/tools/jdeps/Analyzer.java | 8 + .../com/sun/tools/jdeps/ClassFileReader.java | 4 +- .../com/sun/tools/jdeps/JdepsWriter.java | 2 +- .../sun/tools/jdeps/ModuleInfoBuilder.java | 2 +- .../java/lang/annotation/ElementType.java | 19 +- .../classes/jdk/internal/PreviewFeature.java | 28 +- src/jdk.jdeps/share/man/javap.1 | 2 +- src/jdk.jdeps/share/man/jdeprscan.1 | 2 +- src/jdk.jdeps/share/man/jdeps.1 | 2 +- 166 files changed, 4290 insertions(+), 1539 deletions(-) create mode 100644 src/jdk.compiler/share/classes/com/sun/source/tree/CaseLabelTree.java create mode 100644 src/jdk.compiler/share/classes/com/sun/source/tree/DefaultCaseLabelTree.java create mode 100644 src/jdk.compiler/share/classes/com/sun/source/tree/GuardedPatternTree.java create mode 100644 src/jdk.compiler/share/classes/com/sun/source/tree/ParenthesizedPatternTree.java diff --git a/make/langtools/netbeans/nb-javac/nbproject/project.properties b/make/langtools/netbeans/nb-javac/nbproject/project.properties index 6c0d23e..3d58b74 100644 --- a/make/langtools/netbeans/nb-javac/nbproject/project.properties +++ b/make/langtools/netbeans/nb-javac/nbproject/project.properties @@ -104,4 +104,4 @@ javac.test.classpath=\ ${build.dir}/lib/hamcrest-core-1.3.jar debug.classpath=${run.classpath} jnlp.enabled=false -nb-javac-ver=16.0.0.0 +nb-javac-ver=17.0.0.0 diff --git a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java index 5122e79..4c7336a 100644 --- a/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java +++ b/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java @@ -221,9 +221,23 @@ public enum SourceVersion { * The version recognized by the Java Platform, Standard Edition * 16. * + * Additions in this release include pattern matching for {@code + * instanceof} and records. + * * @since 16 */ - RELEASE_16; + RELEASE_16, + + /** + * The version recognized by the Java Platform, Standard Edition + * 17. + * + * Additions in this release include sealed classes and + * restoration of always-strict floating-point semantics. + * + * @since 17 + */ + RELEASE_17; // Note that when adding constants for newer releases, the // behavior of latest() and latestSupported() must be updated too. @@ -232,7 +246,7 @@ public enum SourceVersion { * {@return the latest source version that can be modeled} */ public static SourceVersion latest() { - return RELEASE_16; + return RELEASE_17; } private static final SourceVersion latestSupported = getLatestSupported(); @@ -246,10 +260,14 @@ public static SourceVersion latest() { */ private static SourceVersion getLatestSupported() { + try { String specVersion = System.getProperty("java.specification.version"); switch (specVersion) { + case "17": + return RELEASE_17; + case "16": return RELEASE_16; @@ -279,6 +297,7 @@ private static SourceVersion getLatestSupported() { } return RELEASE_5; + } diff --git a/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java b/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java index f8aef53..dfbd76d 100644 --- a/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java +++ b/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -66,33 +66,15 @@ public enum Modifier { /** The modifier {@code static} */ STATIC, /** - * {@preview Associated with sealed classes, a preview feature of the Java language. - * - * This enum constant is associated with sealed classes, a preview - * feature of the Java language. Preview features - * may be removed in a future release, or upgraded to permanent - * features of the Java language.} - * * The modifier {@code sealed} - * @since 15 + * @since 17 */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.SEALED_CLASSES, - essentialAPI=false) SEALED, /** - * {@preview Associated with sealed classes, a preview feature of the Java language. - * - * This enum constant is associated with sealed classes, a preview - * feature of the Java language. Preview features - * may be removed in a future release, or upgraded to permanent - * features of the Java language.} - * * The modifier {@code non-sealed} - * @since 15 + * @since 17 */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.SEALED_CLASSES, - essentialAPI=false) NON_SEALED { public String toString() { return "non-sealed"; diff --git a/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java b/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java index 6ba3377..0a8b389 100644 --- a/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java +++ b/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -201,12 +201,6 @@ default List getRecordComponents() { } /** - * {@preview Associated with sealed classes, a preview feature of the Java language. - * - * This method is associated with sealed classes, a preview - * feature of the Java language. Preview features - * may be removed in a future release, or upgraded to permanent - * features of the Java language.} * Returns the permitted classes of this class or interface * element in declaration order. * @@ -215,10 +209,8 @@ default List getRecordComponents() { * * @return the permitted classes, or an empty list if there are none * - * @since 15 + * @since 17 */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.SEALED_CLASSES, - essentialAPI=false) default List getPermittedSubclasses() { return Collections.unmodifiableList(new ArrayList()); } diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java index db9d370..08a2fb5 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor14.java @@ -44,7 +44,7 @@ * @see AbstractAnnotationValueVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public abstract class AbstractAnnotationValueVisitor14 extends AbstractAnnotationValueVisitor9 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java index b2af474..dbb9e73 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor14.java @@ -50,7 +50,7 @@ * @since 16 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public abstract class AbstractElementVisitor14 extends AbstractElementVisitor9 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java index 953c415..ac7ac4e 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor14.java @@ -47,7 +47,7 @@ * @see AbstractTypeVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public abstract class AbstractTypeVisitor14 extends AbstractTypeVisitor9 { /** * Constructor for concrete subclasses to call. diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java index 6a620e8..e16d232 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor14.java @@ -62,7 +62,7 @@ * @since 16 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public class ElementKindVisitor14 extends ElementKindVisitor9 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java index 905a7d4..eb483c9 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner14.java @@ -76,7 +76,7 @@ * @see ElementScanner9 * @since 16 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public class ElementScanner14 extends ElementScanner9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java index ec513fb..fc94c17 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -656,6 +656,22 @@ boolean overrides(ExecutableElement overrider, ExecutableElement overridden, */ boolean isFunctionalInterface(TypeElement type); + /** + * {@return {@code true} if the module element is an automatic + * module, {@code false} otherwise} + * + * @implSpec + * The default implementation of this method returns {@code + * false}. + * + * @param module the module element being examined + * @jls 7.7.1 Dependences + * @since 17 + */ + default boolean isAutomaticModule(ModuleElement module) { + return false; + } + /** * Returns the record component for the given accessor. Returns null if the * given method is not a record component accessor. diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java index f48dd4d..347b522 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor14.java @@ -52,7 +52,7 @@ * @see SimpleAnnotationValueVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public class SimpleAnnotationValueVisitor14 extends SimpleAnnotationValueVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java index e1d8a5a..23a7f10 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor14.java @@ -58,7 +58,7 @@ * @since 16 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public class SimpleElementVisitor14 extends SimpleElementVisitor9 { /** diff --git a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java index 3a1b6f5..25af668 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor14.java @@ -56,7 +56,7 @@ * @see SimpleTypeVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public class SimpleTypeVisitor14 extends SimpleTypeVisitor9 { /** * Constructor for concrete subclasses; uses {@code null} for the diff --git a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java index 9309b64..1adc974 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor14.java @@ -61,7 +61,7 @@ * @see TypeKindVisitor9 * @since 14 */ -@SupportedSourceVersion(RELEASE_16) +@SupportedSourceVersion(RELEASE_17) public class TypeKindVisitor14 extends TypeKindVisitor9 { /** * Constructor for concrete subclasses to call; uses {@code null} diff --git a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java index 34ed761..b1fee9e 100644 --- a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java +++ b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java @@ -190,16 +190,16 @@ Iterable getJavaFileObjectsFromFiles( * Returns file objects representing the given paths. * * @implSpec - * The default implementation converts each path to a file and calls - * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. - * IllegalArgumentException will be thrown if any of the paths - * cannot be converted to a file. + * The default implementation lazily converts each path to a file and calls + * {@link #getJavaFileObjectsFromFiles(Iterable) getJavaFileObjectsFromFiles}. + * {@code IllegalArgumentException} will be thrown + * if any of the paths cannot be converted to a file at the point the conversion happens. * * @param paths a list of paths * @return a list of file objects * @throws IllegalArgumentException if the list of paths includes * a directory or if this file manager does not support any of the - * given paths. + * given paths * * @since 13 */ @@ -229,10 +229,10 @@ public File next() { * Returns file objects representing the given paths. * * @implSpec - * The default implementation converts each path to a file and calls - * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. - * IllegalArgumentException will be thrown if any of the paths - * cannot be converted to a file. + * The default implementation lazily converts each path to a file and calls + * {@link #getJavaFileObjectsFromPaths(Collection) getJavaFileObjectsFromPaths}. + * {@code IllegalArgumentException} will be thrown + * if any of the paths cannot be converted to a file at the point the conversion happens. * * @param paths a list of paths * @return a list of file objects @@ -273,7 +273,8 @@ default Iterable getJavaFileObjectsFromPaths( * @param files an array of files * @return a list of file objects * @throws IllegalArgumentException if the array of files includes - * a directory + * a directory or if this file manager does not support any of the + * given paths * @throws NullPointerException if the given array contains null * elements */ @@ -287,10 +288,15 @@ default Iterable getJavaFileObjectsFromPaths( * getJavaFileObjectsFromPaths({@linkplain java.util.Arrays#asList Arrays.asList}(paths)) * * + * @implSpec + * The default implementation will only throw {@code NullPointerException} + * if {@linkplain #getJavaFileObjectsFromPaths(Collection)} throws it. + * * @param paths an array of paths * @return a list of file objects * @throws IllegalArgumentException if the array of files includes - * a directory + * a directory or if this file manager does not support any of the + * given paths * @throws NullPointerException if the given array contains null * elements * @@ -357,10 +363,10 @@ void setLocation(Location location, Iterable files) * will be cancelled. * * @implSpec - * The default implementation converts each path to a file and calls - * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. - * {@linkplain IllegalArgumentException IllegalArgumentException} - * will be thrown if any of the paths cannot be converted to a file. + * The default implementation lazily converts each path to a file and calls + * {@link #setLocation setLocation}. + * {@code IllegalArgumentException} will be thrown if any of the paths cannot + * be converted to a file at the point the conversion happens. * * @param location a location * @param paths a list of paths, if {@code null} use the default diff --git a/src/java.compiler/share/classes/javax/tools/ToolProvider.java b/src/java.compiler/share/classes/javax/tools/ToolProvider.java index e28d32e..4471f0a 100644 --- a/src/java.compiler/share/classes/javax/tools/ToolProvider.java +++ b/src/java.compiler/share/classes/javax/tools/ToolProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -24,7 +24,6 @@ */ package javax.tools; - /** * Provides methods for locating tool providers, for example, * providers of compilers. This class complements the diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/CaseLabelTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/CaseLabelTree.java new file mode 100644 index 0000000..4e8b295 --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/CaseLabelTree.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021, 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 com.sun.source.tree; + +import jdk.internal.PreviewFeature; + +/** + * A marker interface for {@code Tree}s that may be used as {@link CaseTree} labels. + * + * @since 17 + */ +@PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) +public interface CaseLabelTree extends Tree {} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/CaseTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/CaseTree.java index cdfcef3..a65896a 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/CaseTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/CaseTree.java @@ -27,6 +27,8 @@ import java.util.List; +import jdk.internal.PreviewFeature; + /** * A tree node for a {@code case} in a {@code switch} statement or expression. * @@ -65,6 +67,16 @@ public interface CaseTree extends Tree { @Deprecated() List getExpressions(); + /** + * Returns the labels for this case. + * For {@code default} case return a list with a single element, {@link DefaultCaseLabelTree}. + * + * @return labels for this case + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + List getLabels(); + /** * For case with kind {@linkplain CaseKind#STATEMENT}, * returns the statements labeled by the case. diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java index b1c0a89..6be81f3 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -87,23 +87,14 @@ public interface ClassTree extends StatementTree { List getImplementsClause(); /** - * {@preview Associated with sealed classes, a preview feature of the Java language. - * - * This method is associated with sealed classes, a preview - * feature of the Java language. Preview features - * may be removed in a future release, or upgraded to permanent - * features of the Java language.} - * * Returns the subclasses permitted by this type declaration. * * @implSpec this implementation returns an empty list * * @return the subclasses * - * @since 15 + * @since 17 */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.SEALED_CLASSES, - essentialAPI=false) default List getPermitsClause() { return new ArrayList<>(); } diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/CompilationUnitTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/CompilationUnitTree.java index 7bbd93d..a9aff46 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/CompilationUnitTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/CompilationUnitTree.java @@ -29,16 +29,29 @@ import javax.tools.JavaFileObject; /** - * Represents the abstract syntax tree for compilation units (source - * files) and package declarations (package-info.java). + * Represents the abstract syntax tree for ordinary compilation units + * and modular compilation units. * * @jls 7.3 Compilation Units * @jls 7.4 Package Declarations + * @jls 7.7 Module Declarations * * @author Peter von der Ahé * @since 1.6 */ public interface CompilationUnitTree extends Tree { + + /** + * Returns the module tree associated with this compilation unit, + * or {@code null} if there is no module declaration. + * @return the module tree + * @implSpec This implementation throws {@code UnsupportedOperationException} + * @since 17 + */ + default ModuleTree getModule() { + throw new UnsupportedOperationException(); + } + /** * Returns the annotations listed on any package declaration * at the head of this compilation unit, or {@code null} if there @@ -64,15 +77,18 @@ public interface CompilationUnitTree extends Tree { PackageTree getPackage(); /** - * Returns the import declarations appearing in this compilation unit. + * Returns the import declarations appearing in this compilation unit, + * or an empty list if there are no import declarations. * @return the import declarations */ List getImports(); /** - * Returns the type declarations appearing in this compilation unit. + * Returns the type declarations appearing in this compilation unit, + * or an empty list if there are no type declarations. * The list may also include empty statements resulting from * extraneous semicolons. + * A modular compilation unit does not contain any type declarations. * @return the type declarations */ List getTypeDecls(); @@ -84,8 +100,8 @@ public interface CompilationUnitTree extends Tree { JavaFileObject getSourceFile(); /** - * Returns the line map for this compilation unit, if available. - * Returns {@code null} if the line map is not available. + * Returns the line map for this compilation unit, if available, + * or {@code null} if the line map is not available. * @return the line map for this compilation unit */ LineMap getLineMap(); diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/DefaultCaseLabelTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/DefaultCaseLabelTree.java new file mode 100644 index 0000000..d8b5e18 --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/DefaultCaseLabelTree.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, 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 com.sun.source.tree; + +import jdk.internal.PreviewFeature; + +/** + * A case label that marks {@code default} in {@code case null, default}. + * + * @since 17 + */ +@PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) +public interface DefaultCaseLabelTree extends CaseLabelTree {} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/ExpressionTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/ExpressionTree.java index bd6b17c..90b7ae4 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/ExpressionTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ExpressionTree.java @@ -35,4 +35,4 @@ * @author Jonathan Gibbons * @since 1.6 */ -public interface ExpressionTree extends Tree {} +public interface ExpressionTree extends Tree, CaseLabelTree {} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/GuardedPatternTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/GuardedPatternTree.java new file mode 100644 index 0000000..81587bd --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/GuardedPatternTree.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017, 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 com.sun.source.tree; + +import jdk.internal.PreviewFeature; + +/** + * A guard pattern tree. + * + * @since 17 + */ +@PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) +public interface GuardedPatternTree extends PatternTree { + + /** + * The guarded pattern expression. + * @return the guarded pattern + */ + public PatternTree getPattern(); + + /** + * The guard expression. + * @return the guard expression + */ + public ExpressionTree getExpression(); + +} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/ParenthesizedPatternTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/ParenthesizedPatternTree.java new file mode 100644 index 0000000..4c67925 --- /dev/null +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ParenthesizedPatternTree.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2014, 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 com.sun.source.tree; + +import jdk.internal.PreviewFeature; + +/** + * A tree node for a parenthesized pattern. + * + * For example: + *
+ *   ( pattern )
+ * 
+ * + * @jls 14.30.1 Kinds of Patterns + * + * @since 17 + */ +@PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) +public interface ParenthesizedPatternTree extends PatternTree { + /** + * Returns the pattern within the parentheses. + * @return the pattern + */ + PatternTree getPattern(); +} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/PatternTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/PatternTree.java index 283fa20..c8c1b7a 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/PatternTree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/PatternTree.java @@ -31,4 +31,4 @@ * * @since 16 */ -public interface PatternTree extends Tree {} +public interface PatternTree extends Tree, CaseLabelTree {} diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java index 3a6cb09..45be8d3 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java @@ -25,6 +25,8 @@ package com.sun.source.tree; +import jdk.internal.PreviewFeature; + /** * Common interface for all nodes in an abstract syntax tree. * @@ -226,6 +228,30 @@ public enum Kind { */ BINDING_PATTERN(BindingPatternTree.class), + /** + * Used for instances of {@link GuardedPatternTree}. + * + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + GUARDED_PATTERN(GuardedPatternTree.class), + + /** + * Used for instances of {@link ParenthesizedPatternTree}. + * + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + PARENTHESIZED_PATTERN(ParenthesizedPatternTree.class), + + /** + * Used for instances of {@link DefaultCaseLabelTree}. + * + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + DEFAULT_CASE_LABEL(DefaultCaseLabelTree.class), + /** * Used for instances of {@link PrimitiveTypeTree}. */ diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java index cbb6f72..46b022a 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java +++ b/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java @@ -25,6 +25,8 @@ package com.sun.source.tree; +import jdk.internal.PreviewFeature; + /** * A visitor of trees, in the style of the visitor design pattern. * Classes implementing this interface are used to operate @@ -266,6 +268,16 @@ public interface TreeVisitor { */ R visitBindingPattern(BindingPatternTree node, P p); + /** + * Visits a DefaultCaseLabelTree node. + * @param node the node being visited + * @param p a parameter value + * @return a result value + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + R visitDefaultCaseLabel(DefaultCaseLabelTree node, P p); + /** * Visits a MethodTree node. * @param node the node being visited @@ -290,6 +302,26 @@ public interface TreeVisitor { */ R visitNewArray(NewArrayTree node, P p); + /** + * Visits a GuardPatternTree node. + * @param node the node being visited + * @param p a parameter value + * @return a result value + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + R visitGuardedPattern(GuardedPatternTree node, P p); + + /** + * Visits a ParenthesizedPatternTree node. + * @param node the node being visited + * @param p a parameter value + * @return a result value + * @since 17 + */ + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + R visitParenthesizedPattern(ParenthesizedPatternTree node, P p); + /** * Visits a NewClassTree node. * @param node the node being visited diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java index f5834a5..8499273 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java @@ -269,13 +269,17 @@ DocCommentTree newDocCommentTree(List fullBody, * Creates a new {@code ReturnTree} object, to represent a {@code @return} tag * or {@code {@return}} tag. * - * @implSpec This implementation throws {@code UnsupportedOperationException} if - * {@code isInline} is {@code true}, and calls {@link #newReturnTree(List)} otherwise. - * + * @param isInline {@code true} if this instance is as an inline tag, + * and {@code false} otherwise * @param description the description of the return value of a method + * * @return a {@code ReturnTree} object * @throws UnsupportedOperationException if inline {@code {@return}} tags are - * not supported + * not supported + * + * @implSpec This implementation throws {@code UnsupportedOperationException} if + * {@code isInline} is {@code true}, and calls {@link #newReturnTree(List)} otherwise. + * * @since 16 */ default ReturnTree newReturnTree(boolean isInline, List description) { diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java index 0ed59fe..54ce3b1 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2021, 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 @@ -35,22 +35,6 @@ * Inside your method, call super.visitXYZ to visit descendant * nodes. * - *

The default implementation of the visitXYZ methods will determine - * a result as follows: - *

    - *
  • If the node being visited has no children, the result will be {@code null}. - *
  • If the node being visited has one child, the result will be the - * result of calling {@code scan} on that child. The child may be a simple node - * or itself a list of nodes. - *
  • If the node being visited has more than one child, the result will - * be determined by calling {@code scan} each child in turn, and then combining the - * result of each scan after the first with the cumulative result - * so far, as determined by the {@link #reduce} method. Each child may be either - * a simple node of a list of nodes. The default behavior of the {@code reduce} - * method is such that the result of the visitXYZ method will be the result of - * the last child scanned. - *
- * *

Here is an example to count the number of erroneous nodes in a tree: *

  *   class CountErrors extends DocTreeScanner<Integer,Void> {
@@ -65,6 +49,23 @@
  *   }
  * 
* + * @implSpec + *

The default implementation of the visitXYZ methods will determine + * a result as follows: + *

    + *
  • If the node being visited has no children, the result will be {@code null}. + *
  • If the node being visited has one child, the result will be the + * result of calling {@code scan} with that child. The child may be a simple node + * or itself a list of nodes. + *
  • If the node being visited has more than one child, the result will + * be determined by calling {@code scan} with each child in turn, and then combining the + * result of each scan after the first with the cumulative result + * so far, as determined by the {@link #reduce} method. Each child may be either + * a simple node or a list of nodes. The default behavior of the {@code reduce} + * method is such that the result of the visitXYZ method will be the result of + * the last child scanned. + *
+ * * @since 1.8 */ public class DocTreeScanner implements DocTreeVisitor { @@ -128,7 +129,9 @@ public R reduce(R r1, R r2) { ****************************************************************************/ /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -140,7 +143,9 @@ public R visitAttribute(AttributeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -152,7 +157,9 @@ public R visitAuthor(AuthorTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -164,7 +171,9 @@ public R visitComment(CommentTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -176,7 +185,9 @@ public R visitDeprecated(DeprecatedTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -191,7 +202,9 @@ public R visitDocComment(DocCommentTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -203,7 +216,9 @@ public R visitDocRoot(DocRootTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -215,7 +230,9 @@ public R visitDocType(DocTypeTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -227,7 +244,9 @@ public R visitEndElement(EndElementTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -239,7 +258,9 @@ public R visitEntity(EntityTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -251,7 +272,9 @@ public R visitErroneous(ErroneousTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -263,7 +286,9 @@ public R visitHidden(HiddenTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -275,7 +300,9 @@ public R visitIdentifier(IdentifierTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -289,7 +316,9 @@ public R visitIndex(IndexTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -301,7 +330,9 @@ public R visitInheritDoc(InheritDocTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -315,7 +346,9 @@ public R visitLink(LinkTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -327,7 +360,9 @@ public R visitLiteral(LiteralTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -341,7 +376,9 @@ public R visitParam(ParamTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -355,7 +392,9 @@ public R visitProvides(ProvidesTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -367,7 +406,9 @@ public R visitReference(ReferenceTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -379,7 +420,9 @@ public R visitReturn(ReturnTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -391,7 +434,9 @@ public R visitSee(SeeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -403,7 +448,9 @@ public R visitSerial(SerialTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -415,7 +462,9 @@ public R visitSerialData(SerialDataTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -430,7 +479,9 @@ public R visitSerialField(SerialFieldTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -442,7 +493,9 @@ public R visitSince(SinceTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -454,7 +507,9 @@ public R visitStartElement(StartElementTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -467,7 +522,9 @@ public R visitSummary(SummaryTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -480,7 +537,9 @@ public R visitSystemProperty(SystemPropertyTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -492,7 +551,9 @@ public R visitText(TextTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -506,7 +567,9 @@ public R visitThrows(ThrowsTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -518,7 +581,9 @@ public R visitUnknownBlockTag(UnknownBlockTagTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -530,7 +595,9 @@ public R visitUnknownInlineTag(UnknownInlineTagTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -544,7 +611,9 @@ public R visitUses(UsesTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -556,7 +625,9 @@ public R visitValue(ValueTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -568,7 +639,9 @@ public R visitVersion(VersionTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java index 60fd4b2..2c3c070 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java @@ -232,6 +232,7 @@ public abstract void printMessage(Diagnostic.Kind kind, CharSequence msg, * 8.1.4. Character references * in the HTML 5.2 specification.

* + * @param tree the tree containing the entity * @return a string containing the characters */ public abstract String getCharacters(EntityTree tree); diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java index 4fa7fd0..2461ac4 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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,7 +96,9 @@ public final R visit(Iterable nodes, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -108,7 +110,9 @@ public R visitAttribute(AttributeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -120,7 +124,9 @@ public R visitAuthor(AuthorTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -132,7 +138,9 @@ public R visitComment(CommentTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -144,7 +152,9 @@ public R visitDeprecated(DeprecatedTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -156,7 +166,9 @@ public R visitDocComment(DocCommentTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -181,7 +193,9 @@ public R visitDocRoot(DocRootTree node, P p) { public R visitDocType(DocTypeTree node, P p) { return defaultAction(node, p); } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -191,7 +205,9 @@ public R visitDocRoot(DocRootTree node, P p) { public R visitEndElement(EndElementTree node, P p) { return defaultAction(node, p);} /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -203,7 +219,9 @@ public R visitEntity(EntityTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -215,7 +233,9 @@ public R visitErroneous(ErroneousTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -229,7 +249,9 @@ public R visitHidden(HiddenTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -241,7 +263,9 @@ public R visitIdentifier(IdentifierTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -255,7 +279,9 @@ public R visitIndex(IndexTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -267,7 +293,9 @@ public R visitInheritDoc(InheritDocTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -279,7 +307,9 @@ public R visitLink(LinkTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -291,7 +321,9 @@ public R visitLiteral(LiteralTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -303,7 +335,9 @@ public R visitParam(ParamTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -317,7 +351,9 @@ public R visitProvides(ProvidesTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -329,7 +365,9 @@ public R visitReference(ReferenceTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -341,7 +379,9 @@ public R visitReturn(ReturnTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -353,7 +393,9 @@ public R visitSee(SeeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -365,7 +407,9 @@ public R visitSerial(SerialTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -377,7 +421,9 @@ public R visitSerialData(SerialDataTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -389,7 +435,9 @@ public R visitSerialField(SerialFieldTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -401,7 +449,9 @@ public R visitSince(SinceTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -413,7 +463,9 @@ public R visitStartElement(StartElementTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -426,7 +478,9 @@ public R visitSummary(SummaryTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -439,7 +493,9 @@ public R visitSystemProperty(SystemPropertyTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -451,7 +507,9 @@ public R visitText(TextTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -463,7 +521,9 @@ public R visitThrows(ThrowsTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -475,7 +535,9 @@ public R visitUnknownBlockTag(UnknownBlockTagTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -487,7 +549,9 @@ public R visitUnknownInlineTag(UnknownInlineTagTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -501,7 +565,9 @@ public R visitUses(UsesTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -513,7 +579,9 @@ public R visitValue(ValueTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -525,7 +593,9 @@ public R visitVersion(VersionTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java index 03ff696..d2fc692 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -26,6 +26,7 @@ package com.sun.source.util; import com.sun.source.tree.*; +import jdk.internal.PreviewFeature; /** * A simple visitor for tree nodes. @@ -96,7 +97,9 @@ public final R visit(Iterable nodes, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -108,7 +111,9 @@ public R visitCompilationUnit(CompilationUnitTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -120,7 +125,9 @@ public R visitPackage(PackageTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -132,7 +139,9 @@ public R visitImport(ImportTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -144,7 +153,9 @@ public R visitClass(ClassTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -156,7 +167,9 @@ public R visitMethod(MethodTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -168,7 +181,9 @@ public R visitVariable(VariableTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -180,7 +195,9 @@ public R visitEmptyStatement(EmptyStatementTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -192,7 +209,9 @@ public R visitBlock(BlockTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -204,7 +223,9 @@ public R visitDoWhileLoop(DoWhileLoopTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -216,7 +237,9 @@ public R visitWhileLoop(WhileLoopTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -228,7 +251,9 @@ public R visitForLoop(ForLoopTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -240,7 +265,9 @@ public R visitEnhancedForLoop(EnhancedForLoopTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -252,7 +279,9 @@ public R visitLabeledStatement(LabeledStatementTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -264,7 +293,9 @@ public R visitSwitch(SwitchTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -276,7 +307,9 @@ public R visitSwitchExpression(SwitchExpressionTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -288,7 +321,9 @@ public R visitCase(CaseTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -300,7 +335,9 @@ public R visitSynchronized(SynchronizedTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -312,7 +349,9 @@ public R visitTry(TryTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -324,7 +363,9 @@ public R visitCatch(CatchTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -336,7 +377,9 @@ public R visitConditionalExpression(ConditionalExpressionTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -348,7 +391,9 @@ public R visitIf(IfTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -360,7 +405,9 @@ public R visitExpressionStatement(ExpressionStatementTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -372,7 +419,9 @@ public R visitBreak(BreakTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -384,7 +433,9 @@ public R visitContinue(ContinueTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -396,7 +447,9 @@ public R visitReturn(ReturnTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -408,7 +461,9 @@ public R visitThrow(ThrowTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -420,7 +475,9 @@ public R visitAssert(AssertTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -432,7 +489,9 @@ public R visitMethodInvocation(MethodInvocationTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -444,7 +503,9 @@ public R visitNewClass(NewClassTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -456,7 +517,9 @@ public R visitNewArray(NewArrayTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -468,7 +531,9 @@ public R visitLambdaExpression(LambdaExpressionTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -480,7 +545,9 @@ public R visitParenthesized(ParenthesizedTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -492,7 +559,9 @@ public R visitAssignment(AssignmentTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -504,7 +573,9 @@ public R visitCompoundAssignment(CompoundAssignmentTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -516,7 +587,9 @@ public R visitUnary(UnaryTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -528,7 +601,9 @@ public R visitBinary(BinaryTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -540,7 +615,9 @@ public R visitTypeCast(TypeCastTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -552,7 +629,9 @@ public R visitInstanceOf(InstanceOfTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -565,7 +644,25 @@ public R visitBindingPattern(BindingPatternTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + * @since 17 + */ + @Override + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + public R visitDefaultCaseLabel(DefaultCaseLabelTree node, P p) { + return defaultAction(node, p); + } + + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -577,7 +674,9 @@ public R visitArrayAccess(ArrayAccessTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -589,7 +688,41 @@ public R visitMemberSelect(MemberSelectTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + * @since 17 + */ + @Override + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + public R visitParenthesizedPattern(ParenthesizedPatternTree node, P p) { + return defaultAction(node, p); + } + + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + * @since 17 + */ + @Override + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + public R visitGuardedPattern(GuardedPatternTree node, P p) { + return defaultAction(node, p); + } + + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -601,7 +734,9 @@ public R visitMemberReference(MemberReferenceTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -613,7 +748,9 @@ public R visitIdentifier(IdentifierTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -625,7 +762,9 @@ public R visitLiteral(LiteralTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -637,7 +776,9 @@ public R visitPrimitiveType(PrimitiveTypeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -649,7 +790,9 @@ public R visitArrayType(ArrayTypeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -661,7 +804,9 @@ public R visitParameterizedType(ParameterizedTypeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -673,7 +818,9 @@ public R visitUnionType(UnionTypeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -685,7 +832,9 @@ public R visitIntersectionType(IntersectionTypeTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -697,7 +846,9 @@ public R visitTypeParameter(TypeParameterTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -709,7 +860,9 @@ public R visitWildcard(WildcardTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -721,7 +874,9 @@ public R visitModifiers(ModifiersTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -733,7 +888,9 @@ public R visitAnnotation(AnnotationTree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -744,41 +901,108 @@ public R visitAnnotatedType(AnnotatedTypeTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ + @Override public R visitModule(ModuleTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ @Override public R visitExports(ExportsTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ @Override public R visitOpens(OpensTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ @Override public R visitProvides(ProvidesTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ @Override public R visitRequires(RequiresTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ @Override public R visitUses(UsesTree node, P p) { return defaultAction(node, p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ + @Override public R visitErroneous(ErroneousTree node, P p) { return defaultAction(node, p); } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -790,7 +1014,9 @@ public R visitOther(Tree node, P p) { } /** - * {@inheritDoc} This implementation calls {@code defaultAction}. + * {@inheritDoc} + * + * @implSpec This implementation calls {@code defaultAction}. * * @param node {@inheritDoc} * @param p {@inheritDoc} diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/TreePath.java b/src/jdk.compiler/share/classes/com/sun/source/util/TreePath.java index 6b7f0b2..be98551 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/TreePath.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/TreePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2021, 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 @@ -33,7 +33,7 @@ /** * A path of tree nodes, typically used to represent the sequence of ancestor - * nodes of a tree node up to the top level CompilationUnitTree node. + * nodes of a tree node up to the top-level {@code CompilationUnitTree} node. * * @author Jonathan Gibbons * @since 1.6 diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java index a606c6d..f60272d 100644 --- a/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java +++ b/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -26,6 +26,7 @@ package com.sun.source.util; import com.sun.source.tree.*; +import jdk.internal.PreviewFeature; /** * A TreeVisitor that visits all the child tree nodes. @@ -34,22 +35,6 @@ * Inside your method, call super.visitXYZ to visit descendant * nodes. * - *

The default implementation of the visitXYZ methods will determine - * a result as follows: - *

    - *
  • If the node being visited has no children, the result will be {@code null}. - *
  • If the node being visited has one child, the result will be the - * result of calling {@code scan} on that child. The child may be a simple node - * or itself a list of nodes. - *
  • If the node being visited has more than one child, the result will - * be determined by calling {@code scan} each child in turn, and then combining the - * result of each scan after the first with the cumulative result - * so far, as determined by the {@link #reduce} method. Each child may be either - * a simple node of a list of nodes. The default behavior of the {@code reduce} - * method is such that the result of the visitXYZ method will be the result of - * the last child scanned. - *
- * *

Here is an example to count the number of identifier nodes in a tree: *

  *   class CountIdentifiers extends TreeScanner<Integer,Void> {
@@ -64,6 +49,23 @@
  *   }
  * 
* + * @implSpec + *

The default implementation of the visitXYZ methods will determine + * a result as follows: + *

    + *
  • If the node being visited has no children, the result will be {@code null}. + *
  • If the node being visited has one child, the result will be the + * result of calling {@code scan} with that child. The child may be a simple node + * or itself a list of nodes. + *
  • If the node being visited has more than one child, the result will + * be determined by calling {@code scan} with each child in turn, and then combining the + * result of each scan after the first with the cumulative result + * so far, as determined by the {@link #reduce} method. Each child may be either + * a simple node or a list of nodes. The default behavior of the {@code reduce} + * method is such that the result of the visitXYZ method will be the result of + * the last child scanned. + *
+ * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's @@ -135,7 +137,9 @@ public R reduce(R r1, R r2) { ****************************************************************************/ /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -146,11 +150,14 @@ public R visitCompilationUnit(CompilationUnitTree node, P p) { R r = scan(node.getPackage(), p); r = scanAndReduce(node.getImports(), p, r); r = scanAndReduce(node.getTypeDecls(), p, r); + r = scanAndReduce(node.getModule(), p, r); return r; } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -164,7 +171,9 @@ public R visitPackage(PackageTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -176,13 +185,14 @@ public R visitImport(ImportTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} * @return the result of scanning */ - @SuppressWarnings("preview") @Override public R visitClass(ClassTree node, P p) { R r = scan(node.getModifiers(), p); @@ -195,7 +205,9 @@ public R visitClass(ClassTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -215,7 +227,9 @@ public R visitMethod(MethodTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -231,7 +245,9 @@ public R visitVariable(VariableTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -243,7 +259,9 @@ public R visitEmptyStatement(EmptyStatementTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -255,7 +273,9 @@ public R visitBlock(BlockTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -269,7 +289,9 @@ public R visitDoWhileLoop(DoWhileLoopTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -283,7 +305,9 @@ public R visitWhileLoop(WhileLoopTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -299,7 +323,9 @@ public R visitForLoop(ForLoopTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -314,7 +340,9 @@ public R visitEnhancedForLoop(EnhancedForLoopTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -326,7 +354,9 @@ public R visitLabeledStatement(LabeledStatementTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -340,7 +370,9 @@ public R visitSwitch(SwitchTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -354,7 +386,9 @@ public R visitSwitchExpression(SwitchExpressionTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -371,7 +405,9 @@ public R visitCase(CaseTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -385,7 +421,9 @@ public R visitSynchronized(SynchronizedTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -401,7 +439,9 @@ public R visitTry(TryTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -415,7 +455,9 @@ public R visitCatch(CatchTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -430,7 +472,9 @@ public R visitConditionalExpression(ConditionalExpressionTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -445,7 +489,9 @@ public R visitIf(IfTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -457,7 +503,9 @@ public R visitExpressionStatement(ExpressionStatementTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -469,7 +517,9 @@ public R visitBreak(BreakTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -481,7 +531,9 @@ public R visitContinue(ContinueTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -493,7 +545,9 @@ public R visitReturn(ReturnTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -505,7 +559,9 @@ public R visitThrow(ThrowTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -519,7 +575,9 @@ public R visitAssert(AssertTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -534,7 +592,9 @@ public R visitMethodInvocation(MethodInvocationTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -551,7 +611,9 @@ public R visitNewClass(NewClassTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -570,7 +632,9 @@ public R visitNewArray(NewArrayTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -584,7 +648,9 @@ public R visitLambdaExpression(LambdaExpressionTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -596,7 +662,9 @@ public R visitParenthesized(ParenthesizedTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -610,7 +678,9 @@ public R visitAssignment(AssignmentTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -624,7 +694,9 @@ public R visitCompoundAssignment(CompoundAssignmentTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -636,7 +708,9 @@ public R visitUnary(UnaryTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -650,7 +724,9 @@ public R visitBinary(BinaryTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -664,7 +740,9 @@ public R visitTypeCast(TypeCastTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -682,7 +760,9 @@ public R visitInstanceOf(InstanceOfTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -695,7 +775,25 @@ public R visitBindingPattern(BindingPatternTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + * @since 17 + */ + @Override + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + public R visitDefaultCaseLabel(DefaultCaseLabelTree node, P p) { + return null; + } + + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -709,7 +807,9 @@ public R visitArrayAccess(ArrayAccessTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -721,7 +821,42 @@ public R visitMemberSelect(MemberSelectTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + * @since 17 + */ + @Override + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + public R visitParenthesizedPattern(ParenthesizedPatternTree node, P p) { + return scan(node.getPattern(), p); + } + + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + * @since 17 + */ + @Override + @PreviewFeature(feature=PreviewFeature.Feature.SWITCH_PATTERN_MATCHING, reflective=true) + public R visitGuardedPattern(GuardedPatternTree node, P p) { + R r = scan(node.getPattern(), p); + return scanAndReduce(node.getExpression(), p, r); + } + + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -735,7 +870,9 @@ public R visitMemberReference(MemberReferenceTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -747,7 +884,9 @@ public R visitIdentifier(IdentifierTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -759,7 +898,9 @@ public R visitLiteral(LiteralTree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -771,7 +912,9 @@ public R visitPrimitiveType(PrimitiveTypeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -783,7 +926,9 @@ public R visitArrayType(ArrayTypeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -797,7 +942,9 @@ public R visitParameterizedType(ParameterizedTypeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -809,7 +956,9 @@ public R visitUnionType(UnionTypeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -821,7 +970,9 @@ public R visitIntersectionType(IntersectionTypeTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -835,7 +986,9 @@ public R visitTypeParameter(TypeParameterTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -847,7 +1000,9 @@ public R visitWildcard(WildcardTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -859,7 +1014,9 @@ public R visitModifiers(ModifiersTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -873,7 +1030,9 @@ public R visitAnnotation(AnnotationTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -886,6 +1045,15 @@ public R visitAnnotatedType(AnnotatedTypeTree node, P p) { return r; } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ @Override public R visitModule(ModuleTree node, P p) { R r = scan(node.getAnnotations(), p); @@ -894,6 +1062,15 @@ public R visitModule(ModuleTree node, P p) { return r; } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ @Override public R visitExports(ExportsTree node, P p) { R r = scan(node.getPackageName(), p); @@ -901,6 +1078,15 @@ public R visitExports(ExportsTree node, P p) { return r; } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ @Override public R visitOpens(OpensTree node, P p) { R r = scan(node.getPackageName(), p); @@ -908,6 +1094,15 @@ public R visitOpens(OpensTree node, P p) { return r; } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ @Override public R visitProvides(ProvidesTree node, P p) { R r = scan(node.getServiceName(), p); @@ -915,18 +1110,38 @@ public R visitProvides(ProvidesTree node, P p) { return r; } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ @Override public R visitRequires(RequiresTree node, P p) { return scan(node.getModuleName(), p); } + /** + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. + * + * @param node {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of scanning + */ @Override public R visitUses(UsesTree node, P p) { return scan(node.getServiceName(), p); } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -938,7 +1153,9 @@ public R visitOther(Tree node, P p) { } /** - * {@inheritDoc} This implementation returns {@code null}. + * {@inheritDoc} + * + * @implSpec This implementation returns {@code null}. * * @param node {@inheritDoc} * @param p {@inheritDoc} @@ -950,7 +1167,9 @@ public R visitErroneous(ErroneousTree node, P p) { } /** - * {@inheritDoc} This implementation scans the children in left to right order. + * {@inheritDoc} + * + * @implSpec This implementation scans the children in left to right order. * * @param node {@inheritDoc} * @param p {@inheritDoc} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java b/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java index 255e154..ec16e3e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java @@ -53,7 +53,6 @@ public abstract class DocLint implements Plugin { public static final String XMSGS_OPTION = "-Xmsgs"; public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:"; - public static final String XHTML_VERSION_PREFIX = "-XhtmlVersion:"; public static final String XCHECK_PACKAGE = "-XcheckPackage:"; public abstract boolean isValidOption(String opt); @@ -97,7 +96,6 @@ public boolean isValidOption(String s) { // passively accept all "plausible" options return s.equals(XMSGS_OPTION) || s.startsWith(XMSGS_CUSTOM_PREFIX) - || s.startsWith(XHTML_VERSION_PREFIX) || s.startsWith(XCHECK_PACKAGE); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java index 890462a..f383c30 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2021, 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 @@ -151,7 +151,7 @@ public Iterable wrapJavaFileObjects(Iterable VALIDATOR = sym -> { + private static final Predicate VALIDATOR = sym -> { sym.apiComplete(); return sym.kind != Kind.ERR; }; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index 90ff3e1..9dd912b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -244,7 +244,7 @@ String toString(Iterable items, String sep) { void cleanup() { if (compiler != null) compiler.close(); - if (fileManager instanceof BaseFileManager && ((BaseFileManager) fileManager).autoClose) { + if (fileManager instanceof BaseFileManager && ((BaseFileManager) fileManager).autoClose) { try { fileManager.close(); } catch (IOException ignore) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskPool.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskPool.java index f7ba8cf..0c25278 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskPool.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -44,6 +44,7 @@ import javax.tools.DiagnosticListener; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; +import javax.tools.StandardLocation; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; @@ -251,6 +252,9 @@ static class ReusableContext extends Context implements TaskListener { } void clear() { + //when patching modules (esp. java.base), it may be impossible to + //clear the symbols read from the patch path: + polluted |= get(JavaFileManager.class).hasLocation(StandardLocation.PATCH_MODULE_PATH); drop(Arguments.argsKey); drop(DiagnosticListener.class); drop(Log.outKey); @@ -292,9 +296,9 @@ void clear() { @Override @DefinedBy(Api.COMPILER_TREE) public Void scan(Tree tree, Symtab syms) { if (tree instanceof LetExpr) { - LetExpr le = (LetExpr) tree; - scan(le.defs, syms); - scan(le.expr, syms); + LetExpr letExpr = (LetExpr) tree; + scan(letExpr.defs, syms); + scan(letExpr.expr, syms); return null; } else { return super.scan(tree, syms); @@ -356,7 +360,7 @@ void drop(Class c) { */ static class ReusableJavaCompiler extends JavaCompiler { - final static Factory factory = ReusableJavaCompiler::new; + static final Factory factory = ReusableJavaCompiler::new; ReusableJavaCompiler(Context context) { super(context); @@ -383,7 +387,7 @@ protected void checkReusable() { */ static class ReusableLog extends Log { - final static Factory factory = ReusableLog::new; + static final Factory factory = ReusableLog::new; Context context; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java index 1c474b0..c8c5d5e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -166,9 +166,15 @@ public JavacTask getTask(Writer out, if (diagnosticListener != null) context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener)); - if (out == null) + // If out is null and the value is set in the context, we need to do nothing. + if (out == null && context.get(Log.errKey) == null) + // Situation: out is null and the value is not set in the context. context.put(Log.errKey, new PrintWriter(System.err, true)); - else + else if (out instanceof PrintWriter) + // Situation: out is not null and out is a PrintWriter. + context.put(Log.errKey, (PrintWriter)out); + else if (out != null) + // Situation: out is not null and out is not a PrintWriter. context.put(Log.errKey, new PrintWriter(out, true)); if (fileManager == null) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java index 18000a6..eb3308a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -247,9 +247,11 @@ private void init(Context context) { syms = Symtab.instance(context); fileManager = context.get(JavaFileManager.class); JavacTask t = context.get(JavacTask.class); + if (t instanceof JavacTaskImpl) javacTaskImpl = (JavacTaskImpl) t; compiler = com.sun.tools.javac.main.JavaCompiler.instance(context); + } @Override @DefinedBy(Api.COMPILER_TREE) @@ -480,7 +482,7 @@ public TypeMirror getType(DocTreePath path) { new Log.DeferredDiagnosticHandler(log); try { Env env = getAttrContext(path.getTreePath()); - Type t = attr.attribType(((DCReference) tree).qualifierExpression, env); + Type t = attr.attribType(((DCReference)tree).qualifierExpression, env); if (t != null && !t.isErroneous()) { return t; } @@ -579,7 +581,7 @@ private Symbol attributeDocReference(TreePath path, DCReference ref) { Type e = t; // If this is an array type convert to element type while (e instanceof ArrayType) - e = ((ArrayType) e).elemtype; + e = ((ArrayType)e).elemtype; tsym = e.tsym; memberName = (Name) ref.memberName; } @@ -653,12 +655,10 @@ private Symbol attributeParamIdentifier(TreePath path, DCParam paramTag) { return null; } - /** @see com.sun.tools.javadoc.ClassDocImpl#findField */ private VarSymbol findField(ClassSymbol tsym, Name fieldName) { return searchField(tsym, fieldName, new HashSet<>()); } - /** @see com.sun.tools.javadoc.ClassDocImpl#searchField */ private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set searched) { if (searched.contains(tsym)) { return null; @@ -705,7 +705,6 @@ private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set return null; } - /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */ MethodSymbol findConstructor(ClassSymbol tsym, List paramTypes) { for (Symbol sym : tsym.members().getSymbolsByName(names.init)) { if (sym.kind == MTH) { @@ -717,12 +716,10 @@ MethodSymbol findConstructor(ClassSymbol tsym, List paramTypes) { return null; } - /** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */ private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List paramTypes) { return searchMethod(tsym, methodName, paramTypes, new HashSet<>()); } - /** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName, List paramTypes, Set searched) { //### Note that this search is not necessarily what the compiler would do! @@ -804,7 +801,6 @@ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName, return null; } - /** @see com.sun.tools.javadoc.ClassDocImpl */ private boolean hasParameterTypes(MethodSymbol method, List paramTypes) { if (paramTypes == null) return true; @@ -837,7 +833,7 @@ public JavacScope getScope(TreePath path) { public String getDocComment(TreePath path) { CompilationUnitTree t = path.getCompilationUnit(); Tree leaf = path.getLeaf(); - if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) { + if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) { JCCompilationUnit cu = (JCCompilationUnit) t; if (cu.docComments != null) { return cu.docComments.getCommentText((JCTree) leaf); @@ -891,6 +887,7 @@ public boolean isAccessible(Scope scope, TypeElement type) { @Override @DefinedBy(Api.COMPILER_TREE) public boolean isAccessible(Scope scope, Element member, DeclaredType type) { + if (scope instanceof JavacScope && member instanceof Symbol && type instanceof com.sun.tools.javac.code.Type) { @@ -901,6 +898,7 @@ public boolean isAccessible(Scope scope, Element member, DeclaredType type) { return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member, true); } else return false; + } private Env getAttrContext(TreePath path) { @@ -1161,7 +1159,7 @@ public void visitVarDef(JCVariableDecl tree) { static JavaFileObject asJavaFileObject(FileObject fileObject) { JavaFileObject jfo = null; - if (fileObject instanceof JavaFileObject) { + if (fileObject instanceof JavaFileObject) { jfo = (JavaFileObject) fileObject; checkHtmlKind(fileObject, Kind.HTML); return jfo; @@ -1306,7 +1304,7 @@ protected Copier createCopier(TreeMaker maker) { */ @Override @DefinedBy(Api.COMPILER_TREE) public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) { - if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) { + if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) { return ((com.sun.tools.javac.code.Type.ErrorType)errorType).getOriginalType(); } if (errorType instanceof com.sun.tools.javac.code.Type.ClassType && diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/AnnoConstruct.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/AnnoConstruct.java index a7488ea..e9e802f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/AnnoConstruct.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/AnnoConstruct.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -168,7 +168,7 @@ private Attribute.Compound[] unpackContained(Attribute.Compound container) { ListBuffer compounds = new ListBuffer<>(); if (contained0 != null) { for (Attribute a : contained0) - if (a instanceof Attribute.Compound) + if (a instanceof Attribute.Compound) compounds = compounds.append((Attribute.Compound)a); } return compounds.toArray(new Attribute.Compound[compounds.size()]); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Attribute.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Attribute.java index 04cf147..b93105a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Attribute.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Attribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -88,7 +88,7 @@ public Object getValue() { @DefinedBy(Api.LANGUAGE_MODEL) public R accept(AnnotationValueVisitor v, P p) { if (value instanceof String) - return v.visitString((String) value, p); + return v.visitString((String)value, p); if (value instanceof Integer) { int i = (Integer) value; switch (type.getTag()) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java index 3a5ac8c..c74bfe8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java index e6cad52..34fb6d2 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 @@ -359,7 +359,7 @@ public R accept(DirectiveVisitor v, P p) { // TODO: delete? @Override public boolean equals(Object obj) { - if (!(obj instanceof UsesDirective)) { + if (!(obj instanceof UsesDirective)) { return false; } UsesDirective other = (UsesDirective)obj; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java index b614e24..f31ce23 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -176,7 +176,12 @@ public static EnumSet asFlagSet(long flags) { /** Flag for synthesized default constructors of anonymous classes. */ - public static final int ANONCONSTR = 1<<29; + public static final int ANONCONSTR = 1<<29; //non-class members + + /** + * Flag to indicate the super classes of this ClassSymbol has been attributed. + */ + public static final int SUPER_OWNER_ATTRIBUTED = 1<<29; //ClassSymbols /** Flag for class symbols to indicate it has been checked and found * acyclic. @@ -306,7 +311,12 @@ public static EnumSet asFlagSet(long flags) { /** * Flag to indicate the given ModuleSymbol is a system module. */ - public static final long SYSTEM_MODULE = 1L<<53; + public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only + + /** + * Flag to indicate the given ClassSymbol is a value based. + */ + public static final long VALUE_BASED = 1L<<53; //ClassSymbols only /** * Flag to indicate the given symbol has a @Deprecated annotation. @@ -337,7 +347,7 @@ public static EnumSet asFlagSet(long flags) { /** * Flag to indicate the API element in question is for a preview API. */ - public static final long PREVIEW_ESSENTIAL_API = 1L<<58; //any Symbol kind + public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind /** * Flag to indicate the given variable is a match binding variable. @@ -383,6 +393,7 @@ public static EnumSet asFlagSet(long flags) { */ public static final long NON_SEALED = 1L<<63; // ClassSymbols + /** Modifier masks. */ public static final int @@ -412,7 +423,6 @@ public static EnumSet asFlagSet(long flags) { LocalVarFlags = FINAL | PARAMETER, ReceiverParamFlags = PARAMETER; - @SuppressWarnings("preview") public static Set asModifierSet(long flags) { Set modifiers = modifierSets.get(flags); if (modifiers == null) { @@ -512,7 +522,7 @@ public enum Flag { ANONCONSTR_BASED(Flags.ANONCONSTR_BASED), NAME_FILLED(Flags.NAME_FILLED), PREVIEW_API(Flags.PREVIEW_API), - PREVIEW_ESSENTIAL_API(Flags.PREVIEW_ESSENTIAL_API), + PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE), MATCH_BINDING(Flags.MATCH_BINDING), MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER), RECORD(Flags.RECORD), diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java index feb9565..3c43be6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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,9 @@ protected Lint(Context context) { if (source.compareTo(Source.JDK9) >= 0) { values.add(LintCategory.DEP_ANN); } + if (Source.Feature.REDUNDANT_STRICTFP.allowedInSource(source)) { + values.add(LintCategory.STRICTFP); + } values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC); values.add(LintCategory.OPENS); values.add(LintCategory.MODULE); @@ -292,6 +295,11 @@ public enum LintCategory { */ STATIC("static"), + /** + * Warn about unnecessary uses of the strictfp modifier + */ + STRICTFP("strictfp"), + /** * Warn about synchronization attempts on instances of @ValueBased classes. */ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java index 24a83c6..c4653c5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -42,9 +42,15 @@ import javax.tools.JavaFileObject; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; +import static com.sun.tools.javac.code.Flags.RECORD; +import static com.sun.tools.javac.code.Flags.SEALED; +import static com.sun.tools.javac.code.Flags.NON_SEALED; import static com.sun.tools.javac.main.Option.PREVIEW; +import com.sun.tools.javac.util.JCDiagnostic; /** * Helper class to handle preview language features. This class maps certain language features @@ -70,9 +76,11 @@ public class Preview { /** a mapping from classfile numbers to Java SE versions */ private final Map majorVersionToSource; + private final Set sourcesWithPreviewFeatures = new HashSet<>(); private final Lint lint; private final Log log; + private final Source source; private static final Context.Key previewKey = new Context.Key<>(); @@ -90,8 +98,9 @@ public static Preview instance(Context context) { enabled = options.isSet(PREVIEW); log = Log.instance(context); lint = Lint.instance(context); + source = Source.instance(context); this.previewHandler = - new MandatoryWarningHandler(log, lint.isEnabled(LintCategory.PREVIEW), true, "preview", LintCategory.PREVIEW); + new MandatoryWarningHandler(log, source, lint.isEnabled(LintCategory.PREVIEW), true, "preview", LintCategory.PREVIEW); forcePreview = options.isSet("forcePreview"); majorVersionToSource = initMajorVersionToSourceMap(); } @@ -128,6 +137,7 @@ public void warnPreview(DiagnosticPosition pos, Feature feature) { Assert.check(isEnabled()); Assert.check(isPreview(feature)); if (!lint.isSuppressed(LintCategory.PREVIEW)) { + sourcesWithPreviewFeatures.add(log.currentSourceFile()); previewHandler.report(pos, feature.isPlural() ? Warnings.PreviewFeatureUsePlural(feature.nameFragment()) : Warnings.PreviewFeatureUse(feature.nameFragment())); @@ -141,16 +151,25 @@ public void warnPreview(DiagnosticPosition pos, Feature feature) { */ public void warnPreview(JavaFileObject classfile, int majorVersion) { Assert.check(isEnabled()); - if (!lint.isSuppressed(LintCategory.PREVIEW)) { - previewHandler.report(null, + if (lint.isEnabled(LintCategory.PREVIEW)) { + sourcesWithPreviewFeatures.add(log.currentSourceFile()); + log.mandatoryWarning(LintCategory.PREVIEW, null, Warnings.PreviewFeatureUseClassfile(classfile, majorVersionToSource.get(majorVersion).name)); } } + public void markUsesPreview(DiagnosticPosition pos) { + sourcesWithPreviewFeatures.add(log.currentSourceFile()); + } + public void reportPreviewWarning(DiagnosticPosition pos, Warning warnKey) { previewHandler.report(pos, warnKey); } + public boolean usesPreview(JavaFileObject file) { + return sourcesWithPreviewFeatures.contains(file); + } + /** * Are preview features enabled? * @return true, if preview features are enabled. @@ -165,7 +184,9 @@ public boolean isEnabled() { * @return true, if given feature is a preview feature. */ public boolean isPreview(Feature feature) { - if (feature == Feature.SEALED_CLASSES) + if (feature == Feature.CASE_NULL) + return true; + else if(feature == Feature.PATTERN_SWITCH) return true; //Note: this is a backdoor which allows to optionally treat all features as 'preview' (for testing). //When real preview features will be added, this method can be implemented to return 'true' @@ -197,6 +218,17 @@ public Error disabledError(JavaFileObject classfile, int majorVersion) { return Errors.PreviewFeatureDisabledClassfile(classfile, majorVersionToSource.get(majorVersion).name); } + /** + * Check whether the given symbol has been declared using + * a preview language feature. + * + * @param sym Symbol to check + * @return true iff sym has been declared using a preview language feature + */ + public boolean declaredUsingPreviewFeature(Symbol sym) { + return false; + } + /** * Report any deferred diagnostics. */ @@ -208,4 +240,19 @@ public void clear() { previewHandler.clear(); } + public void checkSourceLevel(DiagnosticPosition pos, Feature feature) { + if (isPreview(feature) && !isEnabled()) { + //preview feature without --preview flag, error + log.error(JCDiagnostic.DiagnosticFlag.SOURCE_LEVEL, pos, disabledError(feature)); + } else { + if (!feature.allowedInSource(source)) { + log.error(JCDiagnostic.DiagnosticFlag.SOURCE_LEVEL, pos, + feature.error(source.name)); + } + if (isEnabled() && isPreview(feature)) { + warnPreview(pos, feature); + } + } + } + } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java index 4e8a39b..f19fd65 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -29,6 +29,7 @@ import java.lang.ref.WeakReference; import java.util.*; import java.util.function.BiConsumer; +import java.util.function.Predicate; import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.TypeSymbol; @@ -70,7 +71,7 @@ public final Iterable getSymbols() { /**Returns Symbols that match the given filter. Symbols from outward Scopes are included. */ - public final Iterable getSymbols(Filter sf) { + public final Iterable getSymbols(Predicate sf) { return getSymbols(sf, RECURSIVE); } @@ -84,7 +85,7 @@ public final Iterable getSymbols(LookupKind lookupKind) { /**Returns Symbols that match the given filter. Symbols from outward Scopes are included * iff lookupKind == RECURSIVE. */ - public abstract Iterable getSymbols(Filter sf, LookupKind lookupKind); + public abstract Iterable getSymbols(Predicate sf, LookupKind lookupKind); /**Returns Symbols with the given name. Symbols from outward Scopes are included. */ @@ -95,7 +96,7 @@ public final Iterable getSymbolsByName(Name name) { /**Returns Symbols with the given name that match the given filter. * Symbols from outward Scopes are included. */ - public final Iterable getSymbolsByName(final Name name, final Filter sf) { + public final Iterable getSymbolsByName(final Name name, final Predicate sf) { return getSymbolsByName(name, sf, RECURSIVE); } @@ -109,7 +110,7 @@ public final Iterable getSymbolsByName(Name name, LookupKind lookupKind) /**Returns Symbols with the given name that match the given filter. * Symbols from outward Scopes are included iff lookupKind == RECURSIVE. */ - public abstract Iterable getSymbolsByName(final Name name, final Filter sf, + public abstract Iterable getSymbolsByName(final Name name, final Predicate sf, final LookupKind lookupKind); /** Return the first Symbol from this or outward scopes with the given name. @@ -122,7 +123,7 @@ public final Symbol findFirst(Name name) { /** Return the first Symbol from this or outward scopes with the given name that matches the * given filter. Returns null if none. */ - public Symbol findFirst(Name name, Filter sf) { + public Symbol findFirst(Name name, Predicate sf) { Iterator it = getSymbolsByName(name, sf).iterator(); return it.hasNext() ? it.next() : null; } @@ -130,7 +131,7 @@ public Symbol findFirst(Name name, Filter sf) { /** Returns true iff there are is at least one Symbol in this scope matching the given filter. * Does not inspect outward scopes. */ - public boolean anyMatch(Filter filter) { + public boolean anyMatch(Predicate filter) { return getSymbols(filter, NON_RECURSIVE).iterator().hasNext(); } @@ -160,7 +161,7 @@ public boolean isEmpty() { */ public abstract boolean isStaticallyImported(Symbol byName); - private static final Filter noFilter = null; + private static final Predicate noFilter = null; /** A list of scopes to be notified if items are to be removed from this scope. */ @@ -514,16 +515,16 @@ protected Entry lookup(Name name) { return lookup(name, noFilter); } - protected Entry lookup(Name name, Filter sf) { + protected Entry lookup(Name name, Predicate sf) { Entry e = table[getIndex(name)]; if (e == null || e == sentinel) return sentinel; - while (e.scope != null && (e.sym.name != name || (sf != null && !sf.accepts(e.sym)))) + while (e.scope != null && (e.sym.name != name || (sf != null && !sf.test(e.sym)))) e = e.shadowed; return e; } - public Symbol findFirst(Name name, Filter sf) { + public Symbol findFirst(Name name, Predicate sf) { return lookup(name, sf).sym; } @@ -563,11 +564,11 @@ int getIndex (Name name) { } } - public boolean anyMatch(Filter sf) { + public boolean anyMatch(Predicate sf) { return getSymbols(sf, NON_RECURSIVE).iterator().hasNext(); } - public Iterable getSymbols(final Filter sf, + public Iterable getSymbols(final Predicate sf, final LookupKind lookupKind) { return () -> new Iterator() { private ScopeImpl currScope = ScopeImpl.this; @@ -616,7 +617,7 @@ private void update() { } void skipToNextMatchingEntry() { - while (currEntry != null && sf != null && !sf.accepts(currEntry.sym)) { + while (currEntry != null && sf != null && !sf.test(currEntry.sym)) { currEntry = currEntry.nextSibling; } } @@ -624,7 +625,7 @@ void skipToNextMatchingEntry() { } public Iterable getSymbolsByName(final Name name, - final Filter sf, + final Predicate sf, final LookupKind lookupKind) { return () -> new Iterator() { Entry currentEntry = lookup(name, sf); @@ -729,8 +730,8 @@ public Entry next() { return shadowed; } - public Entry next(Filter sf) { - if (shadowed.sym == null || sf == null || sf.accepts(shadowed.sym)) return shadowed; + public Entry next(Predicate sf) { + if (shadowed.sym == null || sf == null || sf.test(shadowed.sym)) return shadowed; else return shadowed.next(sf); } @@ -752,7 +753,7 @@ public void finalizeScope() { } protected Scope finalizeSingleScope(Scope impScope) { - if (impScope instanceof FilterImportScope && impScope.owner.kind == Kind.TYP && + if (impScope instanceof FilterImportScope && impScope.owner.kind == Kind.TYP && ((FilterImportScope) impScope).isStaticallyImported()) { WriteableScope finalized = WriteableScope.create(impScope.owner); @@ -815,7 +816,7 @@ private Scope appendScope(Scope newScope, Name name) { } @Override - public Iterable getSymbolsByName(Name name, Filter sf, LookupKind lookupKind) { + public Iterable getSymbolsByName(Name name, Predicate sf, LookupKind lookupKind) { Scope[] scopes = name2Scopes.get(name); if (scopes == null) return Collections.emptyList(); @@ -848,16 +849,16 @@ public SingleEntryScope(Symbol owner, Symbol sym, Scope origin) { } @Override - public Iterable getSymbols(Filter sf, LookupKind lookupKind) { - return sf == null || sf.accepts(sym) ? content : Collections.emptyList(); + public Iterable getSymbols(Predicate sf, LookupKind lookupKind) { + return sf == null || sf.test(sym) ? content : Collections.emptyList(); } @Override public Iterable getSymbolsByName(Name name, - Filter sf, + Predicate sf, LookupKind lookupKind) { return sym.name == name && - (sf == null || sf.accepts(sym)) ? content : Collections.emptyList(); + (sf == null || sf.test(sym)) ? content : Collections.emptyList(); } @Override @@ -928,7 +929,7 @@ public FilterImportScope(Types types, } @Override - public Iterable getSymbols(final Filter sf, final LookupKind lookupKind) { + public Iterable getSymbols(final Predicate sf, final LookupKind lookupKind) { if (filterName != null) return getSymbolsByName(filterName, sf, lookupKind); try { @@ -951,7 +952,7 @@ Iterable doLookup(TypeSymbol tsym) { @Override public Iterable getSymbolsByName(final Name name, - final Filter sf, + final Predicate sf, final LookupKind lookupKind) { if (filterName != null && filterName != name) return Collections.emptyList(); @@ -1077,7 +1078,7 @@ public String toString() { } @Override - public Iterable getSymbols(final Filter sf, + public Iterable getSymbols(final Predicate sf, final LookupKind lookupKind) { return () -> Iterators.createCompoundIterator(subScopes, scope -> scope.getSymbols(sf, @@ -1087,7 +1088,7 @@ public Iterable getSymbols(final Filter sf, @Override public Iterable getSymbolsByName(final Name name, - final Filter sf, + final Predicate sf, final LookupKind lookupKind) { return () -> Iterators.createCompoundIterator(subScopes, scope -> scope.getSymbolsByName(name, diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java index c70ce8d..0f9eef3 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -108,7 +108,12 @@ public enum Source { /** * 16, tbd */ - JDK16("16"); + JDK16("16"), + + /** + * 17, tbd + */ + JDK17("17"); private static final Context.Key sourceKey = new Context.Key<>(); @@ -159,6 +164,8 @@ public boolean isSupported() { } public Target requiredTarget() { + + if (this.compareTo(JDK17) >= 0) return Target.JDK1_17; if (this.compareTo(JDK16) >= 0) return Target.JDK1_16; if (this.compareTo(JDK15) >= 0) return Target.JDK1_15; if (this.compareTo(JDK14) >= 0) return Target.JDK1_14; @@ -173,6 +180,7 @@ public Target requiredTarget() { if (this.compareTo(JDK5) >= 0) return Target.JDK1_5; if (this.compareTo(JDK1_4) >= 0) return Target.JDK1_4; return Target.JDK1_1; + } /** @@ -216,7 +224,10 @@ public enum Feature { PATTERN_MATCHING_IN_INSTANCEOF(JDK16, Fragments.FeaturePatternMatchingInstanceof, DiagKind.NORMAL), REIFIABLE_TYPES_INSTANCEOF(JDK16, Fragments.FeatureReifiableTypesInstanceof, DiagKind.PLURAL), RECORDS(JDK16, Fragments.FeatureRecords, DiagKind.PLURAL), - SEALED_CLASSES(JDK16, Fragments.FeatureSealedClasses, DiagKind.PLURAL), + SEALED_CLASSES(JDK17, Fragments.FeatureSealedClasses, DiagKind.PLURAL), + CASE_NULL(JDK17, Fragments.FeatureCaseNull, DiagKind.NORMAL), + PATTERN_SWITCH(JDK17, Fragments.FeaturePatternSwitch, DiagKind.PLURAL), + REDUNDANT_STRICTFP(JDK17), ; enum DiagKind { @@ -279,6 +290,7 @@ public Error error(String sourceName) { } public static SourceVersion toSourceVersion(Source source) { + switch(source) { case JDK1_2: return RELEASE_2; @@ -310,8 +322,12 @@ public static SourceVersion toSourceVersion(Source source) { return RELEASE_15; case JDK16: return RELEASE_16; + case JDK17: + return RELEASE_17; + default: return null; } + } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java index edb0fe1..925e687 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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.util.Set; import java.util.concurrent.Callable; import java.util.function.Supplier; +import java.util.function.Predicate; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -802,7 +803,7 @@ public TypeSymbol(Kind kind, long flags, Name name, Type type, Symbol owner) { } /** form a fully qualified name from a name and an owner */ - static public Name formFullName(Name name, Symbol owner) { + public static Name formFullName(Name name, Symbol owner) { if (owner == null) return name; if (owner.kind != ERR && (owner.kind.matches(KindSelector.VAL_MTH) || @@ -817,12 +818,14 @@ static public Name formFullName(Name name, Symbol owner) { /** form a fully qualified name from a name and an owner, after * converting to flat representation */ - static public Name formFlatName(Name name, Symbol owner) { + + public static Name formFlatName(Name name, Symbol owner) { if (owner == null) return name; if (owner.kind != ERR && (owner.kind.matches(KindSelector.VAL_MTH) || (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) )) return name; + char sep = owner.kind == TYP ? '$' : '.'; Name prefix = owner.flatName(); if (prefix == null || prefix == prefix.table.names.empty) @@ -1460,7 +1463,7 @@ public List getInterfaces() { @DefinedBy(Api.LANGUAGE_MODEL) public Type getSuperclass() { apiComplete(); - if (type instanceof ClassType) { + if (type instanceof ClassType) { ClassType t = (ClassType)type; if (t.supertype_field == null) // FIXME: shouldn't be null t.supertype_field = Type.noType; @@ -1499,7 +1502,6 @@ protected A[] getInheritedAnnotations(Class annoType) @DefinedBy(Api.LANGUAGE_MODEL) - @SuppressWarnings("preview") public ElementKind getKind() { apiComplete(); long flags = flags(); @@ -1548,7 +1550,6 @@ public RecordComponent getRecordComponent(JCVariableDecl var, boolean addIfMissi } @Override @DefinedBy(Api.LANGUAGE_MODEL) - @SuppressWarnings("preview") public List getRecordComponents() { return recordComponents; } @@ -1737,7 +1738,6 @@ public ElementKind getKind() { } else if (isResourceVariable()) { return ElementKind.RESOURCE_VARIABLE; } else if ((flags & MATCH_BINDING) != 0) { - @SuppressWarnings("preview") ElementKind kind = ElementKind.BINDING_VARIABLE; return kind; } else { @@ -1816,7 +1816,7 @@ public R accept(Symbol.Visitor v, P p) { return v.visitVarSymbol(this, p); } - public void clearAnnotationMetadata() { + public void clearAnnotationMetadata() { metadata = null; } @@ -1825,7 +1825,6 @@ public void setName(Name name) { } } - @SuppressWarnings("preview") public static class RecordComponent extends VarSymbol implements RecordComponentElement { public MethodSymbol accessor; public JCTree.JCMethodDecl accessorMeth; @@ -1868,7 +1867,6 @@ public boolean isVarargs() { } @Override @DefinedBy(Api.LANGUAGE_MODEL) - @SuppressWarnings("preview") public ElementKind getKind() { return ElementKind.RECORD_COMPONENT; } @@ -1879,7 +1877,6 @@ public ExecutableElement getAccessor() { } @Override @DefinedBy(Api.LANGUAGE_MODEL) - @SuppressWarnings("preview") public R accept(ElementVisitor v, P p) { return v.visitRecordComponent(this, p); } @@ -2220,10 +2217,10 @@ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean check return implementation(origin, types, checkResult, implementation_filter); } // where - public static final Filter implementation_filter = s -> + public static final Predicate implementation_filter = s -> s.kind == MTH && (s.flags() & SYNTHETIC) == 0; - public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter implFilter) { + public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Predicate implFilter) { MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); if (res != null) return res; @@ -2534,7 +2531,7 @@ public enum AccessCode { this.tag = tag; } - static public AccessCode getFromCode(int code) { + public static AccessCode getFromCode(int code) { for (AccessCode aCodes : AccessCode.values()) { if (aCodes.code == code) { return aCodes; @@ -2576,7 +2573,7 @@ public static interface Completer { /** Dummy completer to be used when the symbol has been completed or * does not need completion. */ - public final static Completer NULL_COMPLETER = new Completer() { + public static final Completer NULL_COMPLETER = new Completer() { public void complete(Symbol sym) { } public boolean isTerminal() { return true; } }; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/SymbolMetadata.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/SymbolMetadata.java index 12afba5..2ab9014 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/SymbolMetadata.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/SymbolMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, 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 @@ -275,7 +275,7 @@ public void removeDeclarationMetadata(Attribute.Compound compound) { for (Attribute.Compound attrCompound : attributes) { if (attrCompound.isSynthesized() && !attrCompound.values.isEmpty()) { Pair val = attrCompound.values.get(0); - if (val.fst.getSimpleName().contentEquals("value") && + if (val.fst.getSimpleName().contentEquals("value") && val.snd instanceof Attribute.Array) { Attribute.Array arr = (Attribute.Array) val.snd; if (arr.values.length != 0 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java index 9105464..72192cc 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -223,7 +223,9 @@ public static Symtab instance(Context context) { public final Type previewFeatureInternalType; public final Type typeDescriptorType; public final Type recordType; + public final Type switchBootstrapsType; public final Type valueBasedType; + public final Type valueBasedInternalType; /** The symbol representing the length field of an array. */ @@ -587,11 +589,13 @@ public boolean hasOuterInstance() { lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory"); stringConcatFactory = enterClass("java.lang.invoke.StringConcatFactory"); functionalInterfaceType = enterClass("java.lang.FunctionalInterface"); - previewFeatureType = enterClass("jdk.internal.PreviewFeature"); + previewFeatureType = enterClass("jdk.internal.javac.PreviewFeature"); previewFeatureInternalType = enterSyntheticAnnotation("jdk.internal.PreviewFeature+Annotation"); typeDescriptorType = enterClass("java.lang.invoke.TypeDescriptor"); recordType = enterClass("java.lang.Record"); + switchBootstrapsType = enterClass("java.lang.runtime.SwitchBootstraps"); valueBasedType = enterClass("jdk.internal.ValueBased"); + valueBasedInternalType = enterSyntheticAnnotation("jdk.internal.ValueBased+Annotation"); synthesizeEmptyInterfaceIfMissing(autoCloseableType); synthesizeEmptyInterfaceIfMissing(cloneableType); @@ -696,6 +700,10 @@ public ClassSymbol getClass(ModuleSymbol msym, Name flatName) { } public PackageSymbol lookupPackage(ModuleSymbol msym, Name flatName) { + return lookupPackage(msym, flatName, false); + } + + private PackageSymbol lookupPackage(ModuleSymbol msym, Name flatName, boolean onlyExisting) { Assert.checkNonNull(msym); if (flatName.isEmpty()) { @@ -718,7 +726,7 @@ public PackageSymbol lookupPackage(ModuleSymbol msym, Name flatName) { pack = getPackage(msym, flatName); - if (pack != null && pack.exists()) + if ((pack != null && pack.exists()) || onlyExisting) return pack; boolean dependsOnUnnamed = msym.requires != null && @@ -792,7 +800,8 @@ public ClassSymbol enterClass(ModuleSymbol msym, Name flatname) { */ public boolean packageExists(ModuleSymbol msym, Name fullname) { Assert.checkNonNull(msym); - return lookupPackage(msym, fullname).exists(); + PackageSymbol pack = lookupPackage(msym, fullname, true); + return pack != null && pack.exists(); } /** Make a package, given its fully qualified name. diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java index e88cc90..7d620c3 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.EnumMap; import java.util.Map; +import java.util.function.Predicate; import javax.lang.model.type.*; @@ -376,7 +377,7 @@ public Type stripMetadata() { return accept(stripMetadata, null); } //where - private final static TypeMapping stripMetadata = new StructuralTypeMapping() { + private static final TypeMapping stripMetadata = new StructuralTypeMapping() { @Override public Type visitClassType(ClassType t, Void aVoid) { return super.visitClassType((ClassType)t.typeNoMetadata(), aVoid); @@ -468,7 +469,7 @@ public String toString() { if (tsym == null || tsym.name == null) { sb.append(""); } else { - sb.append(tsym.name); + sb.append(tsym.name.toString()); } if (moreInfo && hasTag(TYPEVAR)) { sb.append(hashCode()); @@ -645,10 +646,10 @@ public static boolean containsAny(List ts1, List ts2) { return false; } - public static List filter(List ts, Filter tf) { + public static List filter(List ts, Predicate tf) { ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { - if (tf.accepts(t)) { + if (tf.test(t)) { buf.append(t); } } @@ -1365,13 +1366,8 @@ public String toString() { @Override @DefinedBy(Api.LANGUAGE_MODEL) public boolean equals(Object obj) { - if (obj instanceof ArrayType) { - ArrayType that = (ArrayType)obj; - return this == that || - elemtype.equals(that.elemtype); - } - - return false; + return (obj instanceof ArrayType) + && (this == (ArrayType)obj || elemtype.equals(((ArrayType)obj).elemtype)); } @DefinedBy(Api.LANGUAGE_MODEL) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java index ff6e264..46a6202 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -103,7 +103,7 @@ public String toString() { @Override public boolean equals(Object other) { - if (! (other instanceof TypePathEntry)) { + if (! (other instanceof TypePathEntry)) { return false; } TypePathEntry tpe = (TypePathEntry) other; @@ -154,6 +154,10 @@ public int hashCode() { // When read from class file, this holds private int exception_index = Integer.MIN_VALUE; + // The exception start position. + // Corresponding to the start_pc in the exception table. + private int exceptionStartPos = Integer.MIN_VALUE; + // If this type annotation is within a lambda expression, // store a pointer to the lambda expression tree in order // to allow a later translation to the right method. @@ -322,20 +326,22 @@ public boolean hasCatchType() { public int getCatchType() { Assert.check(hasCatchType(), "exception_index does not contain valid catch info"); - return ((-this.exception_index) - 1) & 0xff ; + return (-this.exception_index) - 1; } public int getStartPos() { - Assert.check(hasCatchType(), - "exception_index does not contain valid catch info"); - return ((-this.exception_index) - 1) >> 8 ; + Assert.check(exceptionStartPos >= 0, + "exceptionStartPos does not contain valid start position"); + return this.exceptionStartPos; } public void setCatchInfo(final int catchType, final int startPos) { Assert.check(!hasExceptionIndex(), "exception_index is already set"); Assert.check(catchType >= 0, "Expected a valid catch type"); - this.exception_index = -((catchType | startPos << 8) + 1); + Assert.check(startPos >= 0, "Expected a valid start position"); + this.exception_index = -(catchType + 1); + this.exceptionStartPos = startPos; } /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 152ed40..169e0d6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 @@ -30,7 +30,6 @@ import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; -import com.sun.tools.javac.code.Attribute.Array; import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol; @@ -154,12 +153,12 @@ public List annotationTargets(TypeSymbol tsym) { return null; } - Attribute atValue = atTarget.member(names.value); + Attribute atValue = atTarget.member(names.value); if (!(atValue instanceof Attribute.Array)) { return null; } - List targets = ((Array)atValue).getValue(); + List targets = ((Attribute.Array)atValue).getValue(); if (targets.stream().anyMatch(a -> !(a instanceof Attribute.Enum))) { return null; } @@ -1222,7 +1221,9 @@ public void visitLambda(JCLambda tree) { .methodParameter(tree, i, param.vartype.pos); push(param); try { - separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); + if (!param.declaredUsingVar()) { + separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); + } } finally { pop(); } @@ -1260,7 +1261,7 @@ public void visitVarDef(final JCVariableDecl tree) { final TypeAnnotationPosition pos = TypeAnnotationPosition.localVariable(currentLambda, tree.pos); - if (!tree.isImplicitlyTyped()) { + if (!tree.declaredUsingVar()) { separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); } } else if (tree.sym.getKind() == ElementKind.BINDING_VARIABLE) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java index 380bacb..561ba5d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -35,6 +35,7 @@ import java.util.WeakHashMap; import java.util.function.BiPredicate; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collector; import javax.tools.JavaFileObject; @@ -946,14 +947,17 @@ else if (descSym.overrides(m2, origin, Types.this, false)) { return overridden.toList(); } //where - private Filter bridgeFilter = new Filter() { - public boolean accepts(Symbol t) { + // Use anonymous class instead of lambda expression intentionally, + // because the variable `names` has modifier: final. + private Predicate bridgeFilter = new Predicate() { + public boolean test(Symbol t) { return t.kind == MTH && t.name != names.init && t.name != names.clinit && (t.flags() & SYNTHETIC) == 0; } }; + private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { //a symbol will be completed from a classfile if (a) symbol has //an associated file object with CLASS kind and (b) the symbol has @@ -979,7 +983,7 @@ private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { * Scope filter used to skip methods that should be ignored (such as methods * overridden by j.l.Object) during function interface conversion interface check */ - class DescriptorFilter implements Filter { + class DescriptorFilter implements Predicate { TypeSymbol origin; @@ -988,8 +992,11 @@ class DescriptorFilter implements Filter { } @Override - public boolean accepts(Symbol sym) { + + public boolean test(Symbol sym) { return sym != null && sym.kind == MTH && + + (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT && !overridesObjectMethod(origin, sym) && (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0; @@ -1065,10 +1072,10 @@ private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { * Is t a subtype of s?
* (not defined for Method and ForAll types) */ - final public boolean isSubtype(Type t, Type s) { + public final boolean isSubtype(Type t, Type s) { return isSubtype(t, s, true); } - final public boolean isSubtypeNoCapture(Type t, Type s) { + public final boolean isSubtypeNoCapture(Type t, Type s) { return isSubtype(t, s, false); } public boolean isSubtype(Type t, Type s, boolean capture) { @@ -2941,12 +2948,12 @@ class ImplementationCache { class Entry { final MethodSymbol cachedImpl; - final Filter implFilter; + final Predicate implFilter; final boolean checkResult; final int prevMark; public Entry(MethodSymbol cachedImpl, - Filter scopeFilter, + Predicate scopeFilter, boolean checkResult, int prevMark) { this.cachedImpl = cachedImpl; @@ -2955,14 +2962,14 @@ public Entry(MethodSymbol cachedImpl, this.prevMark = prevMark; } - boolean matches(Filter scopeFilter, boolean checkResult, int mark) { + boolean matches(Predicate scopeFilter, boolean checkResult, int mark) { return this.implFilter == scopeFilter && this.checkResult == checkResult && this.prevMark == mark; } } - MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter) { + MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Predicate implFilter) { SoftReference> ref_cache = _map.get(ms); Map cache = ref_cache != null ? ref_cache.get() : null; if (cache == null) { @@ -2982,7 +2989,7 @@ MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter } } - private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter) { + private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Predicate implFilter) { for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) { t = skipTypeVars(t, false); TypeSymbol c = t.tsym; @@ -3007,8 +3014,13 @@ private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, private ImplementationCache implCache = new ImplementationCache(); - public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter) { + + public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Predicate implFilter) { return origin.type.isErroneous() ? null : implCache.get(ms, origin, checkResult, implFilter); + + + + } // @@ -3028,17 +3040,17 @@ public MembersScope(CompoundScope scope) { this.scope = scope; } - Filter combine(Filter sf) { - return s -> !s.owner.isInterface() && (sf == null || sf.accepts(s)); + Predicate combine(Predicate sf) { + return s -> !s.owner.isInterface() && (sf == null || sf.test(s)); } @Override - public Iterable getSymbols(Filter sf, LookupKind lookupKind) { + public Iterable getSymbols(Predicate sf, LookupKind lookupKind) { return scope.getSymbols(combine(sf), lookupKind); } @Override - public Iterable getSymbolsByName(Name name, Filter sf, LookupKind lookupKind) { + public Iterable getSymbolsByName(Name name, Predicate sf, LookupKind lookupKind) { return scope.getSymbolsByName(name, combine(sf), lookupKind); } @@ -3168,7 +3180,7 @@ class Entry { @Override public boolean equals(Object obj) { - if (obj instanceof Entry) { + if (obj instanceof Entry) { Entry e = (Entry)obj; return e.msym == msym && isSameType(site, e.site); } else { @@ -3198,7 +3210,7 @@ public List interfaceCandidates(Type site, MethodSymbol ms) { CandidatesCache.Entry e = candidatesCache.new Entry(site, ms); List candidates = candidatesCache.get(e); if (candidates == null) { - Filter filter = new MethodFilter(ms, site); + Predicate filter = new MethodFilter(ms, site); List candidates2 = List.nil(); for (Symbol s : membersClosure(site, false).getSymbols(filter)) { if (!site.tsym.isInterface() && !s.owner.isInterface()) { @@ -3231,7 +3243,7 @@ public List prune(List methods) { return methodsMin.toList(); } // where - private class MethodFilter implements Filter { + private class MethodFilter implements Predicate { Symbol msym; Type site; @@ -3241,7 +3253,8 @@ private class MethodFilter implements Filter { this.site = site; } - public boolean accepts(Symbol s) { + @Override + public boolean test(Symbol s) { return s.kind == MTH && s.name == msym.name && (s.flags() & SYNTHETIC) == 0 && @@ -4095,17 +4108,13 @@ List erasedSupertypes(Type t) { return buf.toList(); } - private Type arraySuperType = null; + private Type arraySuperType; private Type arraySuperType() { // initialized lazily to avoid problems during compiler startup if (arraySuperType == null) { - synchronized (this) { - if (arraySuperType == null) { - // JLS 10.8: all arrays implement Cloneable and Serializable. - arraySuperType = makeIntersectionType(List.of(syms.serializableType, - syms.cloneableType), true); - } - } + // JLS 10.8: all arrays implement Cloneable and Serializable. + arraySuperType = makeIntersectionType(List.of(syms.serializableType, + syms.cloneableType), true); } return arraySuperType; } @@ -4342,15 +4351,19 @@ public Type boxedTypeOrType(Type t) { * Return the primitive type corresponding to a boxed type. */ public Type unboxedType(Type t) { - if (t != null && !t.isErroneous()) { - for (int i=0; i implements Type.Visitor { - final public R visit(Type t, S s) { return t.accept(this, s); } + public final R visit(Type t, S s) { return t.accept(this, s); } public R visitClassType(ClassType t, S s) { return visitType(t, s); } public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); } public R visitArrayType(ArrayType t, S s) { return visitType(t, s); } @@ -4948,7 +4962,7 @@ public static abstract class DefaultTypeVisitor implements Type.Visitor implements Symbol.Visitor { - final public R visit(Symbol s, S arg) { return s.accept(this, arg); } + public final R visit(Symbol s, S arg) { return s.accept(this, arg); } public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); } public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); } public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); } @@ -5001,7 +5015,7 @@ public static abstract class TypeRelation extends SimpleVisitor {} * visitor; use Void if no return type is needed. */ public static abstract class UnaryVisitor extends SimpleVisitor { - final public R visit(Type t) { return t.accept(this, null); } + public final R visit(Type t) { return t.accept(this, null); } } /** @@ -5015,7 +5029,7 @@ public static abstract class UnaryVisitor extends SimpleVisitor { * not needed. */ public static class MapVisitor extends DefaultTypeVisitor { - final public Type visit(Type t) { return t.accept(this, null); } + public final Type visit(Type t) { return t.accept(this, null); } public Type visitType(Type t, S s) { return t; } } @@ -5051,7 +5065,7 @@ public RetentionPolicy getRetention(TypeSymbol sym) { Attribute.Compound c = sym.attribute(syms.retentionType.tsym); if (c != null) { Attribute value = c.member(names.value); - if (value != null && value instanceof Attribute.Enum) { + if (value != null && value instanceof Attribute.Enum) { Name levelName = ((Attribute.Enum)value).value.name; if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE; else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java index 711e665..f8dcbd5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java @@ -36,6 +36,7 @@ import com.sun.source.tree.LambdaExpressionTree; import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.VariableTree; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds.Kind; import com.sun.tools.javac.code.Source; @@ -566,14 +567,17 @@ void doAnalysis(RewritingContext rewriting) { log.useSource(rewriting.env.toplevel.getSourceFile()); JCStatement treeToAnalyze = (JCStatement)rewriting.originalTree; + JCTree wrappedTree = null; + if (rewriting.env.info.scope.owner.kind == Kind.TYP) { //add a block to hoist potential dangling variable declarations treeToAnalyze = make.at(Position.NOPOS) .Block(Flags.SYNTHETIC, List.of((JCStatement)rewriting.originalTree)); + wrappedTree = rewriting.originalTree; } //TODO: to further refine the analysis, try all rewriting combinations - deferredAttr.attribSpeculative(treeToAnalyze, rewriting.env, attr.statInfo, new TreeRewriter(rewriting), + deferredAttr.attribSpeculative(treeToAnalyze, rewriting.env, attr.statInfo, new TreeRewriter(rewriting, wrappedTree), () -> rewriting.diagHandler(), AttributionMode.ANALYZER, argumentAttr.withLocalCacheContext()); rewriting.analyzer.process(rewriting.oldTree, rewriting.replacement, rewriting.erroneous); } catch (Throwable ex) { @@ -785,9 +789,11 @@ public JCTree visitModifiers(ModifiersTree node, Void _unused) { class TreeRewriter extends AnalyzerCopier { RewritingContext rewriting; + JCTree wrappedTree; - TreeRewriter(RewritingContext rewriting) { + TreeRewriter(RewritingContext rewriting, JCTree wrappedTree) { this.rewriting = rewriting; + this.wrappedTree = wrappedTree; } @Override @@ -800,5 +806,19 @@ public Z copy(Z tree, Void _unused) { } return newTree; } + + @Override + public JCTree visitVariable(VariableTree node, Void p) { + JCTree result = super.visitVariable(node, p); + if (node == wrappedTree) { + //The current tree is a field and has been wrapped by a block, so it effectivelly + //became local variable. If it has some modifiers (except for final), an error + //would be reported, causing the whole rewrite to fail. Removing the non-final + //modifiers from the variable here: + ((JCVariableDecl) result).mods.flags &= Flags.FINAL; + } + return result; + } + } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java index 8f5056a..31d02eb 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -53,6 +53,7 @@ import static com.sun.tools.javac.code.Kinds.Kind.MDL; import static com.sun.tools.javac.code.Kinds.Kind.MTH; import static com.sun.tools.javac.code.Kinds.Kind.PCK; +import static com.sun.tools.javac.code.Kinds.Kind.TYP; import static com.sun.tools.javac.code.Kinds.Kind.VAR; import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; import static com.sun.tools.javac.code.TypeTag.ARRAY; @@ -369,14 +370,19 @@ private void annotateNow(Symbol toAnnotate, } } - // Note: @Deprecated has no effect on local variables and parameters if (!c.type.isErroneous() && types.isSameType(c.type, syms.previewFeatureType)) { toAnnotate.flags_field |= Flags.PREVIEW_API; - if (isAttributeTrue(c.member(names.essentialAPI))) { - toAnnotate.flags_field |= Flags.PREVIEW_ESSENTIAL_API; + if (isAttributeTrue(c.member(names.reflective))) { + toAnnotate.flags_field |= Flags.PREVIEW_REFLECTIVE; } } + + if (!c.type.isErroneous() + && toAnnotate.kind == TYP + && types.isSameType(c.type, syms.valueBasedType)) { + toAnnotate.flags_field |= Flags.VALUE_BASED; + } } List buf = List.nil(); @@ -404,7 +410,7 @@ private void annotateNow(Symbol toAnnotate, } //where: private boolean isAttributeTrue(Attribute attr) { - if (attr instanceof Attribute.Constant) { + if (attr instanceof Attribute.Constant) { Attribute.Constant v = (Attribute.Constant) attr; if (v.type == syms.booleanType && ((Integer) v.value) != 0) { return true; @@ -447,7 +453,7 @@ public Attribute.TypeCompound attributeTypeAnnotation(JCAnnotation a, Type expec { // The attribute might have been entered if it is Target or Repeatable // Because TreeCopier does not copy type, redo this if type is null - if (a.attribute == null || a.type == null || !(a.attribute instanceof Attribute.TypeCompound)) { + if (a.attribute == null || a.type == null || !(a.attribute instanceof Attribute.TypeCompound)) { // Create a new TypeCompound List> elems = attributeAnnotationValues(a, expectedAnnotationType, env); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java index cabd541..b6fe22d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -36,7 +36,6 @@ import com.sun.tools.javac.comp.DeferredAttr.AttrMode; import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; import com.sun.tools.javac.comp.DeferredAttr.DeferredType; -import com.sun.tools.javac.comp.DeferredAttr.DeferredTypeCompleter; import com.sun.tools.javac.comp.DeferredAttr.LambdaReturnScanner; import com.sun.tools.javac.comp.DeferredAttr.SwitchExpressionScanner; import com.sun.tools.javac.comp.Infer.PartiallyInferredMethodType; @@ -55,7 +54,6 @@ import com.sun.tools.javac.tree.JCTree.JCSwitchExpression; import com.sun.tools.javac.tree.TreeCopier; import com.sun.tools.javac.tree.TreeInfo; -import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.DiagnosticSource; import com.sun.tools.javac.util.JCDiagnostic; @@ -336,7 +334,7 @@ public void visitNewClass(JCNewClass that) { * perform an overload check without the need of calling back to Attr. This extra information * is typically stored in the form of a speculative tree. */ - abstract class ArgumentType extends DeferredType implements DeferredTypeCompleter { + abstract class ArgumentType extends DeferredType { /** The speculative tree carrying type information. */ T speculativeTree; @@ -351,24 +349,18 @@ public ArgumentType(JCExpression tree, Env env, T speculativeTree, } @Override - final DeferredTypeCompleter completer() { - return this; - } - - @Override - final public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { - Assert.check(dt == this); + public final Type complete(ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { if (deferredAttrContext.mode == AttrMode.SPECULATIVE) { Type t = (resultInfo.pt == Type.recoveryType) ? - deferredAttr.basicCompleter.complete(dt, resultInfo, deferredAttrContext) : + super.complete(resultInfo, deferredAttrContext) : overloadCheck(resultInfo, deferredAttrContext); speculativeTypes.put(resultInfo, t); return t; } else { if (!env.info.attributionMode.isSpeculative) { - argumentTypeCache.remove(new UniquePos(dt.tree)); + argumentTypeCache.remove(new UniquePos(tree)); } - return deferredAttr.basicCompleter.complete(dt, resultInfo, deferredAttrContext); + return super.complete(resultInfo, deferredAttrContext); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index a163fa8..d11592f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -27,7 +27,6 @@ import java.util.*; import java.util.function.BiConsumer; -import java.util.stream.Collectors; import javax.lang.model.element.ElementKind; import javax.tools.JavaFileObject; @@ -170,10 +169,10 @@ protected Attr(Context context) { allowLambda = Feature.LAMBDA.allowedInSource(source); allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source); allowStaticInterfaceMethods = Feature.STATIC_INTERFACE_METHODS.allowedInSource(source); - allowReifiableTypesInInstanceof = - Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source) && - (!preview.isPreview(Feature.REIFIABLE_TYPES_INSTANCEOF) || preview.isEnabled()); + allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source); allowRecords = Feature.RECORDS.allowedInSource(source); + allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) && + Feature.PATTERN_SWITCH.allowedInSource(source); sourceName = source.name; useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); @@ -216,6 +215,10 @@ protected Attr(Context context) { */ private final boolean allowRecords; + /** Are patterns in switch allowed + */ + private final boolean allowPatternSwitch; + /** * Switch: warn about use of variable before declaration? * RFE: 6425594 @@ -1581,6 +1584,15 @@ public void visitForeachLoop(JCEnhancedForLoop tree) { elemtype = iterableParams.isEmpty() ? syms.objectType : types.wildUpperBound(iterableParams.head); + + // Check the return type of the method iterator(). + // This is the bare minimum we need to verify to make sure code generation doesn't crash. + Symbol iterSymbol = rs.resolveInternalMethod(tree.pos(), + loopEnv, exprType, names.iterator, List.nil(), List.nil()); + if (types.asSuper(iterSymbol.type.getReturnType(), syms.iteratorType.tsym) == null) { + log.error(tree.pos(), + Errors.ForeachNotApplicableToType(exprType, Fragments.TypeReqArrayOrIterable)); + } } } if (tree.var.isImplicitlyTyped()) { @@ -1696,15 +1708,28 @@ private void handleSwitch(JCTree switchTree, try { boolean enumSwitch = seltype.tsym != null && (seltype.tsym.flags() & Flags.ENUM) != 0; boolean stringSwitch = types.isSameType(seltype, syms.stringType); - if (!enumSwitch && !stringSwitch) - seltype = chk.checkType(selector.pos(), seltype, syms.intType); + boolean errorEnumSwitch = TreeInfo.isErrorEnumSwitch(selector, cases); + boolean patternSwitch; + if (!enumSwitch && !stringSwitch && !errorEnumSwitch && + !types.isAssignable(seltype, syms.intType)) { + preview.checkSourceLevel(selector.pos(), Feature.PATTERN_SWITCH); + patternSwitch = true; + } else { + patternSwitch = cases.stream() + .flatMap(c -> c.labels.stream()) + .anyMatch(l -> l.isPattern()); + } // Attribute all cases and // check that there are no duplicate case labels or default clauses. Set labels = new HashSet<>(); // The set of case labels. - boolean hasDefault = false; // Is there a default label? + List coveredTypes = List.nil(); + boolean hasDefault = false; // Is there a default label? + boolean hasTotalPattern = false; // Is there a total pattern? + boolean hasNullPattern = false; // Is there a null pattern? CaseTree.CaseKind caseKind = null; boolean wasError = false; + MatchBindings prevBindings = null; for (List l = cases; l.nonEmpty(); l = l.tail) { JCCase c = l.head; if (caseKind == null) { @@ -1714,40 +1739,106 @@ private void handleSwitch(JCTree switchTree, Errors.SwitchMixingCaseTypes); wasError = true; } - if (c.getExpressions().nonEmpty()) { - for (JCExpression pat : c.getExpressions()) { - if (TreeInfo.isNull(pat)) { - log.error(pat.pos(), - Errors.SwitchNullNotAllowed); + MatchBindings currentBindings = prevBindings; + boolean wasTotalPattern = hasTotalPattern; + for (JCCaseLabel pat : c.labels) { + if (pat.isExpression()) { + JCExpression expr = (JCExpression) pat; + if (TreeInfo.isNull(expr)) { + preview.checkSourceLevel(expr.pos(), Feature.CASE_NULL); + if (hasNullPattern) { + log.error(pat.pos(), Errors.DuplicateCaseLabel); + } else if (wasTotalPattern) { + log.error(pat.pos(), Errors.PatternDominated); + } + hasNullPattern = true; + attribExpr(expr, switchEnv, seltype); + matchBindings = new MatchBindings(matchBindings.bindingsWhenTrue, matchBindings.bindingsWhenFalse, true); } else if (enumSwitch) { - Symbol sym = enumConstant(pat, seltype); + Symbol sym = enumConstant(expr, seltype); if (sym == null) { - log.error(pat.pos(), Errors.EnumLabelMustBeUnqualifiedEnum); + log.error(expr.pos(), Errors.EnumLabelMustBeUnqualifiedEnum); } else if (!labels.add(sym)) { - log.error(c.pos(), Errors.DuplicateCaseLabel); + log.error(pat.pos(), Errors.DuplicateCaseLabel); + } else { + checkCaseLabelDominated(pat.pos(), coveredTypes, sym.type); + } + } else if (errorEnumSwitch) { + //error recovery: the selector is erroneous, and all the case labels + //are identifiers. This could be an enum switch - don't report resolve + //error for the case label: + Resolve.LogResolveHelper prevResolveHelper = rs.basicLogResolveHelper; + try { + rs.basicLogResolveHelper = rs.silentLogResolveHelper; + attribExpr(pat, switchEnv, seltype); + } finally { + rs.basicLogResolveHelper = prevResolveHelper; } } else { - Type pattype = attribExpr(pat, switchEnv, seltype); + ResultInfo valTypInfo = new ResultInfo(KindSelector.VAL_TYP, + !seltype.hasTag(ERROR) ? seltype + : Type.noType); + Type pattype = attribTree(expr, switchEnv, valTypInfo); if (!pattype.hasTag(ERROR)) { if (pattype.constValue() == null) { - log.error(pat.pos(), - (stringSwitch ? Errors.StringConstReq : Errors.ConstExprReq)); + Symbol s = TreeInfo.symbol(expr); + if (s != null && s.kind == TYP && allowPatternSwitch) { + log.error(expr.pos(), + Errors.PatternExpected); + } else { + log.error(expr.pos(), + (stringSwitch ? Errors.StringConstReq : Errors.ConstExprReq)); + } + } else if (!stringSwitch && !types.isAssignable(seltype, syms.intType)) { + log.error(pat.pos(), Errors.ConstantLabelNotCompatible(pattype, seltype)); } else if (!labels.add(pattype.constValue())) { log.error(c.pos(), Errors.DuplicateCaseLabel); + } else { + checkCaseLabelDominated(pat.pos(), coveredTypes, types.boxedTypeOrType(pattype)); } } } + } else if (pat.hasTag(DEFAULTCASELABEL)) { + if (hasDefault) { + log.error(pat.pos(), Errors.DuplicateDefaultLabel); + } else if (hasTotalPattern) { + log.error(pat.pos(), Errors.TotalPatternAndDefault); + } + hasDefault = true; + matchBindings = MatchBindingsComputer.EMPTY; + } else { + //binding pattern + attribExpr(pat, switchEnv); + TreeInfo.PatternPrimaryType primary = TreeInfo.primaryPatternType((JCPattern) pat); + Type primaryType = primary.type(); + if (!primaryType.hasTag(TYPEVAR)) { + primaryType = chk.checkClassOrArrayType(pat.pos(), primaryType); + } + checkCastablePattern(pat.pos(), seltype, primaryType); + Type patternType = types.erasure(primaryType); + boolean isTotal = primary.unconditional() && + !patternType.isErroneous() && + types.isSubtype(types.erasure(seltype), patternType); + if (isTotal) { + if (hasTotalPattern) { + log.error(pat.pos(), Errors.DuplicateTotalPattern); + } else if (hasDefault) { + log.error(pat.pos(), Errors.TotalPatternAndDefault); + } + hasTotalPattern = true; + } + checkCaseLabelDominated(pat.pos(), coveredTypes, patternType); + if (primary.unconditional() && !patternType.isErroneous()) { + coveredTypes = coveredTypes.prepend(patternType); + } } - } else if (hasDefault) { - log.error(c.pos(), Errors.DuplicateDefaultLabel); - } else { - hasDefault = true; + currentBindings = matchBindingsComputer.switchCase(pat, currentBindings, matchBindings); } if (c == breakTree && resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) throw new BreakAttr(env, null); Env caseEnv = - switchEnv.dup(c, env.info.dup(switchEnv.info.scope.dup())); + bindingEnv(switchEnv, c, currentBindings.bindingsWhenTrue); try { attribCase.accept(c, caseEnv); } catch (BreakAttr ba) { @@ -1756,6 +1847,23 @@ private void handleSwitch(JCTree switchTree, caseEnv.info.scope.leave(); } addVars(c.stats, switchEnv.info.scope); + + c.completesNormally = flow.aliveAfter(caseEnv, c, make); + + prevBindings = c.caseKind == CaseTree.CaseKind.STATEMENT && c.completesNormally ? currentBindings + : null; + } + if (patternSwitch) { + chk.checkSwitchCaseStructure(cases); + } + if (switchTree.hasTag(SWITCH)) { + ((JCSwitch) switchTree).hasTotalPattern = hasDefault || hasTotalPattern; + ((JCSwitch) switchTree).patternSwitch = patternSwitch; + } else if (switchTree.hasTag(SWITCH_EXPRESSION)) { + ((JCSwitchExpression) switchTree).hasTotalPattern = hasDefault || hasTotalPattern; + ((JCSwitchExpression) switchTree).patternSwitch = patternSwitch; + } else { + Assert.error(switchTree.getTag().name()); } } finally { switchEnv.info.scope.leave(); @@ -1770,6 +1878,14 @@ private static void addVars(List stats, WriteableScope switchScope) switchScope.enter(((JCVariableDecl) stat).sym); } } + private void checkCaseLabelDominated(DiagnosticPosition pos, + List coveredTypes, Type patternType) { + for (Type existing : coveredTypes) { + if (types.isSubtype(patternType, existing)) { + log.error(pos, Errors.PatternDominated); + } + } + } // where /** Return the selected enumeration constant symbol, or null. */ private Symbol enumConstant(JCTree tree, Type enumType) { @@ -1799,14 +1915,7 @@ public void visitSynchronized(JCSynchronized tree) { } // where private boolean isValueBased(Type t) { - if (t != null && t.tsym != null) { - for (Attribute.Compound a: t.tsym.getDeclarationAttributes()) { - if (a.type.tsym == syms.valueBasedType.tsym) { - return true; - } - } - } - return false; + return t != null && t.tsym != null && (t.tsym.flags() & VALUE_BASED) != 0; } @@ -2006,7 +2115,7 @@ private boolean isBooleanOrNumeric(Env env, JCExpression tree) { } //where boolean primitiveOrBoxed(Type t) { - return (!t.hasTag(TYPEVAR) && types.unboxedTypeOrType(t).isPrimitive()); + return (!t.hasTag(TYPEVAR) && !t.isErroneous() && types.unboxedTypeOrType(t).isPrimitive()); } TreeTranslator removeClassParams = new TreeTranslator() { @@ -2100,7 +2209,7 @@ Type condType(List positions, List condTypes) { .collect(List.collector())); } - final static TypeTag[] primitiveTags = new TypeTag[]{ + static final TypeTag[] primitiveTags = new TypeTag[]{ BYTE, CHAR, SHORT, @@ -2112,7 +2221,11 @@ Type condType(List positions, List condTypes) { }; Env bindingEnv(Env env, List bindings) { - Env env1 = env.dup(env.tree, env.info.dup(env.info.scope.dup())); + return bindingEnv(env, env.tree, bindings); + } + + Env bindingEnv(Env env, JCTree newTree, List bindings) { + Env env1 = env.dup(newTree, env.info.dup(env.info.scope.dup())); bindings.forEach(env1.info.scope::enter); return env1; } @@ -2454,6 +2567,7 @@ public void visitApply(JCMethodInvocation tree) { } else if (tree.meth.hasTag(SELECT)) { log.error(tree.meth.pos(), Errors.IllegalQualNotIcls(site.tsym)); + attribExpr(((JCFieldAccess) tree.meth).selected, localEnv, site); } // if we're calling a java.lang.Enum constructor, @@ -2479,6 +2593,8 @@ public void visitApply(JCMethodInvocation tree) { Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes); checkId(tree.meth, site, sym, localEnv, new ResultInfo(kind, mpt)); + } else if (site.hasTag(ERROR) && tree.meth.hasTag(SELECT)) { + attribExpr(((JCFieldAccess) tree.meth).selected, localEnv, site); } // Otherwise, `site' is an error type and we do nothing result = tree.type = syms.voidType; @@ -3934,7 +4050,7 @@ public void visitParens(JCParens tree) { Type owntype = attribTree(tree.expr, env, resultInfo); result = check(tree, owntype, pkind(), resultInfo); Symbol sym = TreeInfo.symbol(tree); - if (sym != null && sym.kind.matches(KindSelector.TYP_PCK)) + if (sym != null && sym.kind.matches(KindSelector.TYP_PCK) && sym.kind != Kind.ERR) log.error(tree.pos(), Errors.IllegalParenthesizedExpression); } @@ -4179,21 +4295,19 @@ public void visitTypeTest(JCInstanceOf tree) { tree.expr.pos(), attribExpr(tree.expr, env)); Type clazztype; JCTree typeTree; - if (tree.pattern.getTag() == BINDINGPATTERN) { + if (tree.pattern.getTag() == BINDINGPATTERN || + tree.pattern.getTag() == PARENTHESIZEDPATTERN) { attribTree(tree.pattern, env, unknownExprInfo); clazztype = tree.pattern.type; if (types.isSubtype(exprtype, clazztype) && !exprtype.isErroneous() && !clazztype.isErroneous()) { - log.error(tree.pos(), Errors.InstanceofPatternNoSubtype(clazztype, exprtype)); - } - JCBindingPattern pattern = (JCBindingPattern) tree.pattern; - typeTree = pattern.var.vartype; - if (!clazztype.hasTag(TYPEVAR)) { - clazztype = chk.checkClassOrArrayType(pattern.var.vartype.pos(), clazztype); + log.error(tree.pos(), Errors.InstanceofPatternNoSubtype(exprtype, clazztype)); } + typeTree = TreeInfo.primaryPatternTree((JCPattern) tree.pattern).var.vartype; } else { clazztype = attribType(tree.pattern, env); typeTree = tree.pattern; + chk.validate(typeTree, env, false); } if (!clazztype.hasTag(TYPEVAR)) { clazztype = chk.checkClassOrArrayType(typeTree.pos(), clazztype); @@ -4201,19 +4315,7 @@ public void visitTypeTest(JCInstanceOf tree) { if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) { boolean valid = false; if (allowReifiableTypesInInstanceof) { - if (preview.isPreview(Feature.REIFIABLE_TYPES_INSTANCEOF)) { - preview.warnPreview(tree.expr.pos(), Feature.REIFIABLE_TYPES_INSTANCEOF); - } - Warner warner = new Warner(); - if (!types.isCastable(exprtype, clazztype, warner)) { - chk.basicHandler.report(tree.expr.pos(), - diags.fragment(Fragments.InconvertibleTypes(exprtype, clazztype))); - } else if (warner.hasLint(LintCategory.UNCHECKED)) { - log.error(tree.expr.pos(), - Errors.InstanceofReifiableNotSafe(exprtype, clazztype)); - } else { - valid = true; - } + valid = checkCastablePattern(tree.expr.pos(), exprtype, clazztype); } else { log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), Feature.REIFIABLE_TYPES_INSTANCEOF.error(this.sourceName)); @@ -4223,11 +4325,27 @@ public void visitTypeTest(JCInstanceOf tree) { clazztype = types.createErrorType(clazztype); } } - chk.validate(typeTree, env, false); chk.checkCastable(tree.expr.pos(), exprtype, clazztype); result = check(tree, syms.booleanType, KindSelector.VAL, resultInfo); } + private boolean checkCastablePattern(DiagnosticPosition pos, + Type exprType, + Type pattType) { + Warner warner = new Warner(); + if (!types.isCastable(exprType, pattType, warner)) { + chk.basicHandler.report(pos, + diags.fragment(Fragments.InconvertibleTypes(exprType, pattType))); + return false; + } else if (warner.hasLint(LintCategory.UNCHECKED)) { + log.error(pos, + Errors.InstanceofReifiableNotSafe(exprType, pattType)); + return false; + } else { + return true; + } + } + public void visitBindingPattern(JCBindingPattern tree) { ResultInfo varInfo = new ResultInfo(KindSelector.TYP, resultInfo.pt, resultInfo.checkContext); tree.type = tree.var.type = attribTree(tree.var.vartype, env, varInfo); @@ -4240,10 +4358,31 @@ public void visitBindingPattern(JCBindingPattern tree) { annotate.annotateLater(tree.var.mods.annotations, env, v, tree.pos()); annotate.queueScanTreeAndTypeAnnotate(tree.var.vartype, env, v, tree.var.pos()); annotate.flush(); + chk.validate(tree.var.vartype, env, true); result = tree.type; matchBindings = new MatchBindings(List.of(v), List.nil()); } + @Override + public void visitParenthesizedPattern(JCParenthesizedPattern tree) { + attribExpr(tree.pattern, env); + result = tree.type = tree.pattern.type; + } + + @Override + public void visitGuardPattern(JCGuardPattern tree) { + attribExpr(tree.patt, env); + MatchBindings afterPattern = matchBindings; + Env bodyEnv = bindingEnv(env, matchBindings.bindingsWhenTrue); + try { + attribExpr(tree.expr, bodyEnv, syms.booleanType); + } finally { + bodyEnv.info.scope.leave(); + } + result = tree.type = tree.patt.type; + matchBindings = matchBindingsComputer.guardedPattern(tree, afterPattern, matchBindings); + } + public void visitIndexed(JCArrayAccess tree) { Type owntype = types.createErrorType(tree.type); Type atype = attribExpr(tree.indexed, env); @@ -4715,11 +4854,13 @@ else if (ownOuter != null && ownOuter.hasTag(CLASS) && site != ownOuter) { chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym); chk.checkSunAPI(tree.pos(), sym); chk.checkProfile(tree.pos(), sym); - chk.checkPreview(tree.pos(), sym); - } + + chk.checkPreview(tree.pos() , env.info.scope.owner, sym); + } Env enclosing; if (owntype.isErroneous() && (sym.kind == MTH || sym.kind == VAR) && ((enclosing = enter.getEnv(sym.enclClass())) == null || enclosing.toplevel != env.toplevel)) { log.error(tree.pos(), Errors.TypeError(sym)); + } // If symbol is a variable, check that its type and @@ -5309,12 +5450,15 @@ public void attribClass(DiagnosticPosition pos, ClassSymbol c) { * @param c The class symbol whose definition will be attributed. */ void attribClass(ClassSymbol c) throws CompletionFailure { + + // Check for cycles in the inheritance graph, which can arise from // ill-formed class files. chk.checkNonCyclic(null, c.type); Type st = types.supertype(c.type); - if ((c.flags_field & Flags.COMPOUND) == 0) { + if ((c.flags_field & Flags.COMPOUND) == 0 && + (c.flags_field & Flags.SUPER_OWNER_ATTRIBUTED) == 0) { // First, attribute superclass. if (st.hasTag(CLASS)) attribClass((ClassSymbol)st.tsym); @@ -5322,6 +5466,8 @@ void attribClass(ClassSymbol c) throws CompletionFailure { // Next attribute owner, if it is a class. if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS)) attribClass((ClassSymbol)c.owner); + + c.flags_field |= Flags.SUPER_OWNER_ATTRIBUTED; } // The previous operations might have attributed the current class @@ -5413,16 +5559,18 @@ void attribClass(ClassSymbol c) throws CompletionFailure { log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local)); } - for (ClassSymbol supertypeSym : sealedSupers) { - if (!supertypeSym.permitted.contains(c.type.tsym)) { - log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym)); + if (!c.type.isCompound()) { + for (ClassSymbol supertypeSym : sealedSupers) { + if (!supertypeSym.permitted.contains(c.type.tsym)) { + log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym)); + } + } + if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) { + log.error(TreeInfo.diagnosticPositionFor(c, env.tree), + c.isInterface() ? + Errors.NonSealedOrSealedExpected : + Errors.NonSealedSealedOrFinalExpected); } - } - if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) { - log.error(TreeInfo.diagnosticPositionFor(c, env.tree), - c.isInterface() ? - Errors.NonSealedOrSealedExpected : - Errors.NonSealedSealedOrFinalExpected); } } @@ -5614,7 +5762,7 @@ private void attribClassBody(Env env, ClassSymbol c) { && isSerializable(c.type) && (c.flags() & (Flags.ENUM | Flags.INTERFACE)) == 0 && !c.isAnonymous()) { - checkSerialVersionUID(tree, c); + checkSerialVersionUID(tree, c, env); } if (allowTypeAnnos) { // Correctly organize the positions of the type annotations @@ -5647,7 +5795,7 @@ boolean isSerializable(Type t) { } /** Check that an appropriate serialVersionUID member is defined. */ - private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) { + private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c, Env env) { // check for presence of serialVersionUID VarSymbol svuid = null; @@ -5664,6 +5812,13 @@ private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) { return; } + // Check if @SuppressWarnings("serial") is an annotation of serialVersionUID. + // See JDK-8231622 for more information. + Lint lint = env.info.lint.augment(svuid); + if (lint.isSuppressed(LintCategory.SERIAL)) { + return; + } + // check that it is static final if ((svuid.flags() & (STATIC | FINAL)) != (STATIC | FINAL)) @@ -5724,8 +5879,7 @@ public void visitTypeParameter(JCTypeParameter tree) { public void visitMethodDef(JCMethodDecl tree) { if (tree.recvparam != null && !tree.recvparam.vartype.type.isErroneous()) { - checkForDeclarationAnnotations(tree.recvparam.mods.annotations, - tree.recvparam.vartype.type.tsym); + checkForDeclarationAnnotations(tree.recvparam.mods.annotations, tree.recvparam.sym); } if (tree.restype != null && tree.restype.type != null) { validateAnnotatedType(tree.restype, tree.restype.type); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java index 8fd0950..039bfdf 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index a6f4b5f..5d8b8d6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -26,12 +26,14 @@ package com.sun.tools.javac.comp; import java.util.*; +import java.util.function.Predicate; import java.util.function.Supplier; import javax.lang.model.element.NestingKind; import javax.tools.JavaFileManager; import javax.lang.model.element.ElementKind; +import com.sun.source.tree.CaseTree; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Directive.ExportsDirective; @@ -148,21 +150,21 @@ protected Check(Context context) { boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED); boolean enforceMandatoryWarnings = true; - deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated, + deprecationHandler = new MandatoryWarningHandler(log, null, verboseDeprecated, enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION); - removalHandler = new MandatoryWarningHandler(log, verboseRemoval, + removalHandler = new MandatoryWarningHandler(log, null, verboseRemoval, enforceMandatoryWarnings, "removal", LintCategory.REMOVAL); - uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked, + uncheckedHandler = new MandatoryWarningHandler(log, null, verboseUnchecked, enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED); - sunApiHandler = new MandatoryWarningHandler(log, false, + sunApiHandler = new MandatoryWarningHandler(log, null, false, enforceMandatoryWarnings, "sunapi", null); deferredLintHandler = DeferredLintHandler.instance(context); allowRecords = Feature.RECORDS.allowedInSource(source); - allowSealed = (!preview.isPreview(Feature.SEALED_CLASSES) || preview.isEnabled()) && - Feature.SEALED_CLASSES.allowedInSource(source); + + allowSealed = Feature.SEALED_CLASSES.allowedInSource(source); } @@ -241,21 +243,22 @@ void warnDeprecated(DiagnosticPosition pos, Symbol sym) { } } - /** Warn about deprecated symbol. + /** Log a preview warning. * @param pos Position to be used for error reporting. - * @param sym The deprecated symbol. + * @param msg A Warning describing the problem. */ - void warnPreview(DiagnosticPosition pos, Symbol sym) { - warnPreview(pos, Warnings.IsPreview(sym)); + public void warnPreviewAPI(DiagnosticPosition pos, Warning warnKey) { + if (!lint.isSuppressed(LintCategory.PREVIEW)) + preview.reportPreviewWarning(pos, warnKey); } /** Log a preview warning. * @param pos Position to be used for error reporting. * @param msg A Warning describing the problem. */ - public void warnPreview(DiagnosticPosition pos, Warning warnKey) { + public void warnDeclaredUsingPreview(DiagnosticPosition pos, Symbol sym) { if (!lint.isSuppressed(LintCategory.PREVIEW)) - preview.reportPreviewWarning(pos, warnKey); + preview.reportPreviewWarning(pos, Warnings.DeclaredUsingPreview(kindName(sym), sym)); } /** Warn about unchecked operation. @@ -1226,6 +1229,9 @@ else if ((sym.owner.flags_field & INTERFACE) != 0) } else { mask = MethodFlags; } + if ((flags & STRICTFP) != 0) { + warnOnExplicitStrictfp(pos); + } // Imply STRICTFP if owner has STRICTFP set. if (((flags|implicit) & Flags.ABSTRACT) == 0 || ((flags) & Flags.DEFAULT) != 0) @@ -1270,6 +1276,9 @@ else if ((sym.owner.flags_field & INTERFACE) != 0) mask &= ~ABSTRACT; implicit |= FINAL; } + if ((flags & STRICTFP) != 0) { + warnOnExplicitStrictfp(pos); + } // Imply STRICTFP if owner has STRICTFP set. implicit |= sym.owner.flags_field & STRICTFP; break; @@ -1356,6 +1365,19 @@ else if ((sym.kind == TYP || return flags & (mask | ~ExtendedStandardFlags) | implicit; } + private void warnOnExplicitStrictfp(DiagnosticPosition pos) { + DiagnosticPosition prevLintPos = deferredLintHandler.setPos(pos); + try { + deferredLintHandler.report(() -> { + if (lint.isEnabled(LintCategory.STRICTFP)) { + log.warning(LintCategory.STRICTFP, + pos, Warnings.Strictfp); } + }); + } finally { + deferredLintHandler.setPos(prevLintPos); + } + } + /** Determine if this enum should be implicitly final. * @@ -1378,7 +1400,7 @@ public void visitTree(JCTree tree) { /* no-op */ } @Override public void visitVarDef(JCVariableDecl tree) { if ((tree.mods.flags & ENUM) != 0) { - if (tree.init instanceof JCNewClass && + if (tree.init instanceof JCNewClass && ((JCNewClass) tree.init).def != null) { specialized = true; } @@ -2198,7 +2220,7 @@ void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) { } } - private Filter equalsHasCodeFilter = s -> MethodSymbol.implementation_filter.accepts(s) && + private Predicate equalsHasCodeFilter = s -> MethodSymbol.implementation_filter.test(s) && (s.flags() & BAD_OVERRIDE) == 0; public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos, @@ -2280,8 +2302,8 @@ public void checkModuleName (JCModuleDecl tree) { private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) { ClashFilter cf = new ClashFilter(origin.type); - return (cf.accepts(s1) && - cf.accepts(s2) && + return (cf.test(s1) && + cf.test(s2) && types.hasSameArgs(s1.erasure(types), s2.erasure(types))); } @@ -2314,7 +2336,7 @@ void checkNonCyclicDecl(JCClassDecl tree) { class CycleChecker extends TreeScanner { - List seenClasses = List.nil(); + Set seenClasses = new HashSet<>(); boolean errorFound = false; boolean partialCheck = false; @@ -2333,7 +2355,7 @@ private void checkSymbol(DiagnosticPosition pos, Symbol sym) { } else if (sym.kind == TYP) { checkClass(pos, sym, List.nil()); } - } else { + } else if (sym == null || sym.kind != PCK) { //not completed yet partialCheck = true; } @@ -2382,7 +2404,7 @@ void checkClass(DiagnosticPosition pos, Symbol c, List supertypes) { noteCyclic(pos, (ClassSymbol)c); } else if (!c.type.isErroneous()) { try { - seenClasses = seenClasses.prepend(c); + seenClasses.add(c); if (c.type.hasTag(CLASS)) { if (supertypes.nonEmpty()) { scan(supertypes); @@ -2405,7 +2427,7 @@ void checkClass(DiagnosticPosition pos, Symbol c, List supertypes) { } } } finally { - seenClasses = seenClasses.tail; + seenClasses.remove(c); } } } @@ -2661,7 +2683,7 @@ void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { } //where - private class ClashFilter implements Filter { + private class ClashFilter implements Predicate { Type site; @@ -2674,7 +2696,8 @@ boolean shouldSkip(Symbol s) { s.owner == site.tsym; } - public boolean accepts(Symbol s) { + @Override + public boolean test(Symbol s) { return s.kind == MTH && (s.flags() & SYNTHETIC) == 0 && !shouldSkip(s) && @@ -2728,7 +2751,7 @@ void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) { } //where - private class DefaultMethodClashFilter implements Filter { + private class DefaultMethodClashFilter implements Predicate { Type site; @@ -2736,7 +2759,8 @@ private class DefaultMethodClashFilter implements Filter { this.site = site; } - public boolean accepts(Symbol s) { + @Override + public boolean test(Symbol s) { return s.kind == MTH && (s.flags() & DEFAULT) != 0 && s.isInheritedIn(site.tsym, types) && @@ -3263,7 +3287,7 @@ private void validateTarget(TypeSymbol container, TypeSymbol contained, Diagnost } else { containedTargets = new HashSet<>(); for (Attribute app : containedTarget.values) { - if (!(app instanceof Attribute.Enum)) { + if (!(app instanceof Attribute.Enum)) { continue; // recovery } Attribute.Enum e = (Attribute.Enum)app; @@ -3410,7 +3434,6 @@ boolean annotationApplicable(JCAnnotation a, Symbol s) { return targets.isPresent() && !targets.get().isEmpty(); } - @SuppressWarnings("preview") Optional> getApplicableTargets(JCAnnotation a, Symbol s) { Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); Name[] targets; @@ -3423,7 +3446,7 @@ Optional> getApplicableTargets(JCAnnotation a, Symbol s) { targets = new Name[arr.values.length]; for (int i=0; i warnPreviewAPI(pos, Warnings.IsPreview(s))); + } } else { - deferredLintHandler.report(() -> warnPreview(pos, s)); + deferredLintHandler.report(() -> warnPreviewAPI(pos, Warnings.IsPreviewReflective(s))); + } + } + if (preview.declaredUsingPreviewFeature(s)) { + if (preview.isEnabled()) { + //for preview disabled do presumably so not need to do anything? + //If "s" is compiled from source, then there was an error for it already; + //if "s" is from classfile, there already was an error for the classfile. + preview.markUsesPreview(pos); + deferredLintHandler.report(() -> warnDeclaredUsingPreview(pos, s)); } } } @@ -3876,7 +3913,7 @@ void checkImportsUnique(JCCompilationUnit toplevel) { private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar, Scope staticallyImportedSoFar, Scope topLevelScope, Symbol sym, boolean staticImport) { - Filter duplicates = candidate -> candidate != sym && !candidate.type.isErroneous(); + Predicate duplicates = candidate -> candidate != sym && !candidate.type.isErroneous(); Symbol ordinaryClashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates); Symbol staticClashing = null; if (ordinaryClashing == null && !staticImport) { @@ -4331,4 +4368,66 @@ void checkModuleRequires(final DiagnosticPosition pos, final RequiresDirective r } } + /** + * Verify the case labels conform to the constraints. Checks constraints related + * combinations of patterns and other labels. + * + * @param cases the cases that should be checked. + */ + void checkSwitchCaseStructure(List cases) { + boolean wasConstant = false; // Seen a constant in the same case label + boolean wasDefault = false; // Seen a default in the same case label + boolean wasNullPattern = false; // Seen a null pattern in the same case label, + //or fall through from a null pattern + boolean wasPattern = false; // Seen a pattern in the same case label + //or fall through from a pattern + boolean wasTypePattern = false; // Seen a pattern in the same case label + //or fall through from a type pattern + boolean wasNonEmptyFallThrough = false; + for (List l = cases; l.nonEmpty(); l = l.tail) { + JCCase c = l.head; + for (JCCaseLabel pat : c.labels) { + if (pat.isExpression()) { + JCExpression expr = (JCExpression) pat; + if (TreeInfo.isNull(expr)) { + if (wasPattern && !wasTypePattern && !wasNonEmptyFallThrough) { + log.error(pat.pos(), Errors.FlowsThroughFromPattern); + } + wasNullPattern = true; + } else { + if (wasPattern && !wasNonEmptyFallThrough) { + log.error(pat.pos(), Errors.FlowsThroughFromPattern); + } + wasConstant = true; + } + } else if (pat.hasTag(DEFAULTCASELABEL)) { + if (wasPattern && !wasNonEmptyFallThrough) { + log.error(pat.pos(), Errors.FlowsThroughFromPattern); + } + wasDefault = true; + } else { + boolean isTypePattern = pat.hasTag(BINDINGPATTERN); + if (wasPattern || wasConstant || wasDefault || + (wasNullPattern && (!isTypePattern || wasNonEmptyFallThrough))) { + log.error(pat.pos(), Errors.FlowsThroughToPattern); + } + wasPattern = true; + wasTypePattern = isTypePattern; + } + } + + boolean completesNormally = c.caseKind == CaseTree.CaseKind.STATEMENT ? c.completesNormally + : false; + + if (c.stats.nonEmpty()) { + wasConstant = false; + wasDefault = false; + wasNullPattern &= completesNormally; + wasPattern &= completesNormally; + wasTypePattern &= completesNormally; + } + + wasNonEmptyFallThrough = c.stats.nonEmpty() && completesNormally; + } + } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java index e85a75e..d46694b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -41,6 +41,7 @@ * This code and its internal interfaces are subject to change or * deletion without notice. */ +@SuppressWarnings("strictfp") strictfp class ConstFold { protected static final Context.Key constFoldKey = new Context.Key<>(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 069e88b..5b42ed2 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, 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 @@ -59,6 +59,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import java.util.function.Predicate; import java.util.function.Supplier; import com.sun.source.tree.MemberReferenceTree; @@ -308,8 +309,21 @@ JCTree speculativeTree(DeferredAttrContext deferredAttrContext) { return e != null ? e.speculativeTree : stuckTree; } - DeferredTypeCompleter completer() { - return basicCompleter; + public Type complete(ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { + switch (deferredAttrContext.mode) { + case SPECULATIVE: + //Note: if a symbol is imported twice we might do two identical + //speculative rounds... + Assert.check(mode == null || mode == AttrMode.SPECULATIVE); + JCTree speculativeTree = attribSpeculative(tree, env, resultInfo); + speculativeCache.put(speculativeTree, resultInfo); + return speculativeTree.type; + case CHECK: + Assert.check(mode != null); + return attr.attribTree(tree, env, resultInfo); + } + Assert.error(); + return null; } /** @@ -329,21 +343,23 @@ Type check(ResultInfo resultInfo) { } else { deferredStuckPolicy = new CheckStuckPolicy(resultInfo, this); } - return check(resultInfo, deferredStuckPolicy, completer()); + return check(resultInfo, deferredStuckPolicy); } - private Type check(ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy, - DeferredTypeCompleter deferredTypeCompleter) { + private Type check(ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy) { DeferredAttrContext deferredAttrContext = resultInfo.checkContext.deferredAttrContext(); Assert.check(deferredAttrContext != emptyDeferredAttrContext); if (deferredStuckPolicy.isStuck()) { - notPertinentToApplicability.add(deferredAttrContext.msym); deferredAttrContext.addDeferredAttrNode(this, resultInfo, deferredStuckPolicy); + if (deferredAttrContext.mode == AttrMode.SPECULATIVE) { + notPertinentToApplicability.add(deferredAttrContext.msym); + mode = AttrMode.SPECULATIVE; + } return Type.noType; } else { try { - return deferredTypeCompleter.complete(this, resultInfo, deferredAttrContext); + return complete(resultInfo, deferredAttrContext); } finally { mode = deferredAttrContext.mode; } @@ -351,44 +367,6 @@ private Type check(ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolic } } - /** - * A completer for deferred types. Defines an entry point for type-checking - * a deferred type. - */ - interface DeferredTypeCompleter { - /** - * Entry point for type-checking a deferred type. Depending on the - * circumstances, type-checking could amount to full attribution - * or partial structural check (aka potential applicability). - */ - Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext); - } - - - /** - * A basic completer for deferred types. This completer type-checks a deferred type - * using attribution; depending on the attribution mode, this could be either standard - * or speculative attribution. - */ - DeferredTypeCompleter basicCompleter = new DeferredTypeCompleter() { - public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { - switch (deferredAttrContext.mode) { - case SPECULATIVE: - //Note: if a symbol is imported twice we might do two identical - //speculative rounds... - Assert.check(dt.mode == null || dt.mode == AttrMode.SPECULATIVE); - JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo); - dt.speculativeCache.put(speculativeTree, resultInfo); - return speculativeTree.type; - case CHECK: - Assert.check(dt.mode != null); - return attr.attribTree(dt.tree, dt.env, resultInfo); - } - Assert.error(); - return null; - } - }; - /** * Policy for detecting stuck expressions. Different criteria might cause * an expression to be judged as stuck, depending on whether the check @@ -786,7 +764,7 @@ boolean process(final DeferredAttrContext deferredAttrContext) { switch (deferredAttrContext.mode) { case SPECULATIVE: if (deferredStuckPolicy.isStuck()) { - dt.check(resultInfo, dummyStuckPolicy, new StructuralStuckChecker()); + new StructuralStuckChecker().check(dt, resultInfo, deferredAttrContext); return true; } else { Assert.error("Cannot get here"); @@ -818,7 +796,7 @@ public DeferredAttrContext deferredAttrContext() { "attribution shouldn't be happening here"); ResultInfo instResultInfo = resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt)); - dt.check(instResultInfo, dummyStuckPolicy, basicCompleter); + dt.check(instResultInfo, dummyStuckPolicy); return true; } default: @@ -829,19 +807,18 @@ public DeferredAttrContext deferredAttrContext() { /** * Structural checker for stuck expressions */ - class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter { + class StructuralStuckChecker extends TreeScanner { ResultInfo resultInfo; InferenceContext inferenceContext; Env env; - public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { + public void check(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { this.resultInfo = resultInfo; this.inferenceContext = deferredAttrContext.inferenceContext; this.env = dt.env; dt.tree.accept(this); dt.speculativeCache.put(stuckTree, resultInfo); - return Type.noType; } @Override @@ -931,6 +908,11 @@ public void visitConditional(JCTree.JCConditional tree) { scan(tree.falsepart); } + @Override + public void visitSwitchExpression(JCSwitchExpression tree) { + scan(tree.cases); + } + @Override public void visitReference(JCMemberReference tree) { Assert.checkNonNull(tree.getOverloadKind()); @@ -1126,7 +1108,7 @@ private List map(List ts, List pts) { */ abstract static class FilterScanner extends com.sun.tools.javac.tree.TreeScanner { - final Filter treeFilter; + final Predicate treeFilter; FilterScanner(final Set validTags) { this.treeFilter = t -> validTags.contains(t.getTag()); @@ -1135,7 +1117,7 @@ abstract static class FilterScanner extends com.sun.tools.javac.tree.TreeScanner @Override public void scan(JCTree tree) { if (tree != null) { - if (treeFilter.accepts(tree)) { + if (treeFilter.test(tree)) { super.scan(tree); } else { skip(tree); @@ -1156,7 +1138,7 @@ void skip(JCTree tree) {} static class PolyScanner extends FilterScanner { PolyScanner() { - super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE)); + super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE, SWITCH_EXPRESSION)); } } @@ -1241,6 +1223,7 @@ public void visitLambda(JCLambda tree) { freeArgVars.nonEmpty()) { stuckVars.addAll(freeArgVars); depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType())); + depVars.addAll(inferenceContext.freeVarsIn(descType.getThrownTypes())); } scanLambdaBody(tree, descType.getReturnType()); } @@ -1262,6 +1245,7 @@ public void visitReference(JCMemberReference tree) { tree.getOverloadKind() != JCMemberReference.OverloadKind.UNOVERLOADED) { stuckVars.addAll(freeArgVars); depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType())); + depVars.addAll(inferenceContext.freeVarsIn(descType.getThrownTypes())); } } @@ -1292,6 +1276,24 @@ public void visitReturn(JCReturn tree) { lambdaScanner.scan(lambda.body); } } + + @Override + public void visitSwitchExpression(JCSwitchExpression expr) { + SwitchExpressionScanner switchScanner = new SwitchExpressionScanner() { + @Override + public void visitYield(JCYield tree) { + Type prevPt = CheckStuckPolicy.this.pt; + try { + CheckStuckPolicy.this.pt = pt; + CheckStuckPolicy.this.scan(tree.value); + } finally { + CheckStuckPolicy.this.pt = prevPt; + } + } + }; + switchScanner.scan(expr.cases); + } + } /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java index 0b5a44b..9ab397f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java @@ -370,7 +370,11 @@ public void visitTopLevel(JCCompilationUnit tree) { JCPackageDecl pd = tree.getPackage(); if (pd != null) { tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid)); + PackageAttributer.attrib(pd.pid, tree.packge); + + setPackageSymbols.scan(pd); + if ( pd.annotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS || tree.docComments != null) { @@ -437,6 +441,31 @@ public void visitTopLevel(JCCompilationUnit tree) { log.useSource(prev); result = null; } + //where: + //set package Symbols to the package expression: + private final TreeScanner setPackageSymbols = new TreeScanner() { + Symbol currentPackage; + + @Override + public void visitIdent(JCIdent tree) { + tree.sym = currentPackage; + tree.type = currentPackage.type; + } + + @Override + public void visitSelect(JCFieldAccess tree) { + tree.sym = currentPackage; + tree.type = currentPackage.type; + currentPackage = currentPackage.owner; + super.visitSelect(tree); + } + + @Override + public void visitPackageDef(JCPackageDecl tree) { + currentPackage = tree.packge; + scan(tree.pid); + } + }; private static class PackageAttributer extends TreeScanner { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index fe93d58..a93ad3a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -30,8 +30,12 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Set; + import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + + import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Scope.WriteableScope; @@ -39,21 +43,24 @@ import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Warnings; import com.sun.tools.javac.tree.*; +import com.sun.tools.javac.tree.TreeInfo.PatternPrimaryType; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.Error; import com.sun.tools.javac.util.JCDiagnostic.Warning; -import com.sun.tools.javac.code.Kinds.Kind; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.Kind.*; +import com.sun.tools.javac.code.Type.TypeVar; import static com.sun.tools.javac.code.TypeTag.BOOLEAN; import static com.sun.tools.javac.code.TypeTag.VOID; +import com.sun.tools.javac.resources.CompilerProperties.Fragments; import static com.sun.tools.javac.tree.JCTree.Tag.*; +import com.sun.tools.javac.util.JCDiagnostic.Fragment; /** This pass implements dataflow analysis for Java programs though * different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that @@ -678,19 +685,19 @@ public void visitSwitch(JCSwitch tree) { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); scan(tree.selector); - boolean hasDefault = false; + boolean exhaustiveSwitch = tree.patternSwitch || + tree.cases.stream() + .flatMap(c -> c.labels.stream()) + .anyMatch(l -> TreeInfo.isNull(l)); + Set constants = exhaustiveSwitch ? new HashSet<>() : null; for (List l = tree.cases; l.nonEmpty(); l = l.tail) { alive = Liveness.ALIVE; JCCase c = l.head; - if (c.pats.isEmpty()) - hasDefault = true; - else { - for (JCExpression pat : c.pats) { - scan(pat); - } + for (JCCaseLabel pat : c.labels) { + scan(pat); + handleConstantCaseLabel(constants, pat); } scanStats(c.stats); - c.completesNormally = alive != Liveness.DEAD; if (alive != Liveness.DEAD && c.caseKind == JCCase.RULE) { scanSyntheticBreak(make, tree); alive = Liveness.DEAD; @@ -703,7 +710,12 @@ public void visitSwitch(JCSwitch tree) { l.tail.head.pos(), Warnings.PossibleFallThroughIntoCase); } - if (!hasDefault) { + if (!tree.hasTotalPattern && exhaustiveSwitch && + !TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) && + (constants == null || !isExhaustive(tree.selector.type, constants))) { + log.error(tree, Errors.NotExhaustiveStatement); + } + if (!tree.hasTotalPattern) { alive = Liveness.ALIVE; } alive = alive.or(resolveBreaks(tree, prevPendingExits)); @@ -714,33 +726,14 @@ public void visitSwitchExpression(JCSwitchExpression tree) { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); scan(tree.selector); - Set constants = null; - TypeSymbol selectorSym = tree.selector.type.tsym; - if ((selectorSym.flags() & ENUM) != 0) { - constants = new HashSet<>(); - Filter enumConstantFilter = - s -> (s.flags() & ENUM) != 0 && s.kind == Kind.VAR; - for (Symbol s : selectorSym.members().getSymbols(enumConstantFilter)) { - constants.add(s.name); - } - } - boolean hasDefault = false; + Set constants = new HashSet<>(); Liveness prevAlive = alive; for (List l = tree.cases; l.nonEmpty(); l = l.tail) { alive = Liveness.ALIVE; JCCase c = l.head; - if (c.pats.isEmpty()) - hasDefault = true; - else { - for (JCExpression pat : c.pats) { - scan(pat); - if (constants != null) { - if (pat.hasTag(IDENT)) - constants.remove(((JCIdent) pat).name); - if (pat.type != null) - constants.remove(pat.type.constValue()); - } - } + for (JCCaseLabel pat : c.labels) { + scan(pat); + handleConstantCaseLabel(constants, pat); } scanStats(c.stats); if (alive == Liveness.ALIVE) { @@ -752,20 +745,97 @@ public void visitSwitchExpression(JCSwitchExpression tree) { Errors.SwitchExpressionCompletesNormally); } } - c.completesNormally = alive != Liveness.DEAD; } - if ((constants == null || !constants.isEmpty()) && !hasDefault) { + if (!tree.hasTotalPattern && !TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) && + !isExhaustive(tree.selector.type, constants)) { log.error(tree, Errors.NotExhaustive); } alive = prevAlive; alive = alive.or(resolveYields(tree, prevPendingExits)); } + private void handleConstantCaseLabel(Set constants, JCCaseLabel pat) { + if (constants != null) { + if (pat.isExpression()) { + JCExpression expr = (JCExpression) pat; + if (expr.hasTag(IDENT) && ((JCIdent) expr).sym.isEnum()) + constants.add(((JCIdent) expr).sym); + } else if (pat.isPattern()) { + PatternPrimaryType patternType = TreeInfo.primaryPatternType((JCPattern) pat); + + if (patternType.unconditional()) { + constants.add(patternType.type().tsym); + } + } + } + } + + private void transitiveCovers(Set covered) { + List todo = List.from(covered); + while (todo.nonEmpty()) { + Symbol sym = todo.head; + todo = todo.tail; + switch (sym.kind) { + case VAR: { + Iterable constants = sym.owner + .members() + .getSymbols(s -> s.isEnum() && + s.kind == VAR); + boolean hasAll = StreamSupport.stream(constants.spliterator(), false) + .allMatch(covered::contains); + + if (hasAll && covered.add(sym.owner)) { + todo = todo.prepend(sym.owner); + } + } + break; + + case TYP: { + for (Type sup : types.directSupertypes(sym.type)) { + if (sup.tsym.kind == TYP && sup.tsym.isAbstract() && sup.tsym.isSealed()) { + boolean hasAll = ((ClassSymbol) sup.tsym).permitted + .stream() + .allMatch(covered::contains); + + if (hasAll && covered.add(sup.tsym)) { + todo = todo.prepend(sup.tsym); + } + } + } + } + break; + } + } + } + + private boolean isExhaustive(Type seltype, Set covered) { + transitiveCovers(covered); + boolean isExhaustive = false; + switch (seltype.getTag()) { + case CLASS: { + if (seltype.isCompound()) { + if (seltype.isIntersection()) { + isExhaustive = ((Type.IntersectionClassType) seltype).getComponents().stream().anyMatch(t -> isExhaustive(t, covered)); + } + isExhaustive = false; + } + isExhaustive = covered.contains(seltype.tsym); + } + break; + case TYPEVAR: + isExhaustive = isExhaustive(((TypeVar) seltype).getUpperBound(), covered); + break; + default: + isExhaustive = false; + } + return isExhaustive; + } + public void visitTry(JCTry tree) { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); for (JCTree resource : tree.resources) { - if (resource instanceof JCVariableDecl) { + if (resource instanceof JCVariableDecl) { JCVariableDecl vdecl = (JCVariableDecl) resource; visitVarDef(vdecl); } else if (resource instanceof JCExpression) { @@ -959,7 +1029,7 @@ void errorUncaught() { for (PendingExit exit = pendingExits.next(); exit != null; exit = pendingExits.next()) { - if (exit instanceof ThrownPendingExit) { + if (exit instanceof ThrownPendingExit) { ThrownPendingExit thrownExit = (ThrownPendingExit) exit; if (classDef != null && classDef.pos == exit.tree.pos) { @@ -1217,7 +1287,7 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases scan(selector); for (List l = cases; l.nonEmpty(); l = l.tail) { JCCase c = l.head; - scan(c.pats); + scan(c.labels); scan(c.stats); } if (tree.hasTag(SWITCH_EXPRESSION)) { @@ -1550,6 +1620,10 @@ class SnippetAliveAnalyzer extends AliveAnalyzer { public void visitClassDef(JCClassDecl tree) { //skip } + @Override + public void visitLambda(JCLambda tree) { + //skip + } public boolean isAlive() { return super.alive != Liveness.DEAD; } @@ -2382,52 +2456,58 @@ public void visitLabelled(JCLabeledStatement tree) { } public void visitSwitch(JCSwitch tree) { - handleSwitch(tree, tree.selector, tree.cases); + handleSwitch(tree, tree.selector, tree.cases, tree.hasTotalPattern); } public void visitSwitchExpression(JCSwitchExpression tree) { - handleSwitch(tree, tree.selector, tree.cases); + handleSwitch(tree, tree.selector, tree.cases, tree.hasTotalPattern); } - private void handleSwitch(JCTree tree, JCExpression selector, List cases) { + private void handleSwitch(JCTree tree, JCExpression selector, + List cases, boolean hasTotalPattern) { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); int nextadrPrev = nextadr; scanExpr(selector); final Bits initsSwitch = new Bits(inits); final Bits uninitsSwitch = new Bits(uninits); - boolean hasDefault = false; for (List l = cases; l.nonEmpty(); l = l.tail) { inits.assign(initsSwitch); uninits.assign(uninits.andSet(uninitsSwitch)); JCCase c = l.head; - if (c.pats.isEmpty()) { - hasDefault = true; - } else { - for (JCExpression pat : c.pats) { - scanExpr(pat); + for (JCCaseLabel pat : c.labels) { + scan(pat); + if (inits.isReset()) { + inits.assign(initsWhenTrue); + uninits.assign(uninitsWhenTrue); } } - if (hasDefault) { - inits.assign(initsSwitch); - uninits.assign(uninits.andSet(uninitsSwitch)); + if (l.head.stats.isEmpty() && + l.tail.nonEmpty() && + l.tail.head.labels.size() == 1 && + l.tail.head.labels.head.isExpression() && + TreeInfo.isNull(l.tail.head.labels.head)) { + //handling: + //case Integer i: + //case null: + //joining these two cases together - processing Integer i pattern, + //but statements from case null: + l = l.tail; + c = l.head; } scan(c.stats); if (c.completesNormally && c.caseKind == JCCase.RULE) { scanSyntheticBreak(make, tree); } addVars(c.stats, initsSwitch, uninitsSwitch); - if (!hasDefault) { - inits.assign(initsSwitch); - uninits.assign(uninits.andSet(uninitsSwitch)); - } // Warn about fall-through if lint switch fallthrough enabled. } - if (!hasDefault) { + if (!hasTotalPattern) { if (tree.hasTag(SWITCH_EXPRESSION)) { markDead(); } else { - inits.andSet(initsSwitch); + inits.assign(initsSwitch); + uninits.assign(uninits.andSet(uninitsSwitch)); } } if (tree.hasTag(SWITCH_EXPRESSION)) { @@ -2524,7 +2604,7 @@ public void visitTry(JCTry tree) { // versus finally! while (exits.nonEmpty()) { PendingExit exit = exits.next(); - if (exit instanceof AssignPendingExit) { + if (exit instanceof AssignPendingExit) { ((AssignPendingExit) exit).exit_inits.orSet(inits); ((AssignPendingExit) exit).exit_uninits.andSet(uninits); } @@ -2885,6 +2965,7 @@ void checkEffectivelyFinal(DiagnosticPosition pos, VarSymbol sym) { } break; } + case GUARDPATTERN: case LAMBDA: if ((sym.flags() & (EFFECTIVELY_FINAL | FINAL)) == 0) { reportEffectivelyFinalError(pos, sym); @@ -2908,6 +2989,7 @@ void letInit(JCTree tree) { reportInnerClsNeedsFinalError(tree, sym); break; } + case GUARDPATTERN: case LAMBDA: reportEffectivelyFinalError(tree, sym); } @@ -2916,8 +2998,21 @@ void letInit(JCTree tree) { } void reportEffectivelyFinalError(DiagnosticPosition pos, Symbol sym) { - String subKey = currentTree.hasTag(LAMBDA) ? - "lambda" : "inner.cls"; + Fragment subKey = null; + switch (currentTree.getTag()) { + case LAMBDA: + subKey = Fragments.Lambda; + break; + + case GUARDPATTERN: + subKey = Fragments.Guard; + break; + case CLASSDEF: + subKey = Fragments.InnerCls; + break; + default: + throw new AssertionError("Unexpected tree kind: " + currentTree.getTag()); + } log.error(pos, Errors.CantRefNonEffectivelyFinalVar(sym, diags.fragment(subKey))); } @@ -2953,6 +3048,18 @@ public void visitLambda(JCLambda tree) { } } + @Override + public void visitGuardPattern(JCGuardPattern tree) { + scan(tree.patt); + JCTree prevTree = currentTree; + try { + currentTree = tree; + scan(tree.expr); + } finally { + currentTree = prevTree; + } + } + @Override public void visitIdent(JCIdent tree) { if (tree.sym != null && tree.sym.kind == VAR) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java index 013a1b9..821071d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -68,6 +68,7 @@ import java.util.Set; import java.util.function.BiFunction; import java.util.function.BiPredicate; +import java.util.function.Predicate; import static com.sun.tools.javac.code.TypeTag.*; @@ -1229,7 +1230,7 @@ boolean apply(Warner warn) { /** an incorporation cache keeps track of all executed incorporation-related operations */ Map incorporationCache = new HashMap<>(); - protected static class BoundFilter implements Filter { + protected static class BoundFilter implements Predicate { InferenceContext inferenceContext; @@ -1238,7 +1239,7 @@ public BoundFilter(InferenceContext inferenceContext) { } @Override - public boolean accepts(Type t) { + public boolean test(Type t) { return !t.isErroneous() && !inferenceContext.free(t) && !t.hasTag(BOT); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java index 00c37a8..94d9506 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -33,6 +33,7 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import java.util.function.Predicate; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.ArrayType; @@ -50,7 +51,6 @@ import com.sun.tools.javac.comp.Infer.InferenceStep; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.Assert; -import com.sun.tools.javac.util.Filter; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Warner; @@ -147,11 +147,11 @@ final List boundedVars() { /* Returns the corresponding inference variables. */ - private List filterVars(Filter fu) { + private List filterVars(Predicate fu) { ListBuffer res = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; - if (fu.accepts(uv)) { + if (fu.test(uv)) { res.append(uv.qtype); } } 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 4a6ae3a..f0bb72f 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2021, 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 @@ -197,7 +197,7 @@ public int hashCode() { @Override public boolean equals(Object o) { - if (!(o instanceof DedupedLambda)) { + if (!(o instanceof DedupedLambda)) { return false; } DedupedLambda that = (DedupedLambda) o; @@ -1558,12 +1558,9 @@ public void visitSelect(JCFieldAccess tree) { @Override public void visitVarDef(JCVariableDecl tree) { TranslationContext context = context(); - LambdaTranslationContext ltc = (context != null && context instanceof LambdaTranslationContext)? - (LambdaTranslationContext)context : - null; - if (ltc != null) { + if (context != null && context instanceof LambdaTranslationContext) { if (frameStack.head.tree.hasTag(LAMBDA)) { - ltc.addSymbol(tree.sym, LOCAL_VAR); + ((LambdaTranslationContext)context).addSymbol(tree.sym, LOCAL_VAR); } // Check for type variables (including as type arguments). // If they occur within class nested in a lambda, mark for erasure @@ -2068,12 +2065,30 @@ public Symbol baseSymbol() { }; break; case LOCAL_VAR: - ret = new VarSymbol(sym.flags() & FINAL, sym.name, sym.type, translatedSym); + ret = new VarSymbol(sym.flags() & FINAL, sym.name, sym.type, translatedSym) { + @Override + public Symbol baseSymbol() { + //keep mapping with original symbol + return sym; + } + }; ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; + // If sym.data == ElementKind.EXCEPTION_PARAMETER, + // set ret.data = ElementKind.EXCEPTION_PARAMETER too. + // Because method com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions and + // com.sun.tools.javac.jvm.Code.fillLocalVarPosition would use it. + // See JDK-8257740 for more information. + if (((VarSymbol) sym).isExceptionParameter()) { + ((VarSymbol) ret).setData(ElementKind.EXCEPTION_PARAMETER); + } break; case PARAM: ret = new VarSymbol((sym.flags() & FINAL) | PARAMETER, sym.name, types.erasure(sym.type), translatedSym); ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; + // Set ret.data. Same as case LOCAL_VAR above. + if (((VarSymbol) sym).isExceptionParameter()) { + ((VarSymbol) ret).setData(ElementKind.EXCEPTION_PARAMETER); + } break; default: Assert.error(skind.name()); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index 53b3e16..003a1b9 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -92,11 +92,8 @@ public static Lower instance(Context context) { private DiagnosticPosition make_pos; private final ConstFold cfolder; private final Target target; - private final Source source; private final TypeEnvs typeEnvs; private final Name dollarAssertionsDisabled; - private final Name classDollar; - private final Name dollarCloseResource; private final Types types; private final Repair repair; private final boolean debugLower; @@ -115,14 +112,9 @@ protected Lower(Context context) { make = TreeMaker.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); - source = Source.instance(context); typeEnvs = TypeEnvs.instance(context); dollarAssertionsDisabled = names. fromString(target.syntheticNameChar() + "assertionsDisabled"); - classDollar = names. - fromString("class" + target.syntheticNameChar()); - dollarCloseResource = names. - fromString(target.syntheticNameChar() + "closeResource"); types = Types.instance(context); repair = Repair.instance(context); @@ -1218,7 +1210,7 @@ JCExpression access(Symbol sym, JCExpression tree, JCExpression enclOp, boolean //sym is a local variable - check the lambda translation map to //see if sym has been translated to something else in the current //scope (by LambdaToMethod) - Symbol translatedSym = lambdaTranslationMap.get(sym); + Symbol translatedSym = lambdaTranslationMap.get(sym.baseSymbol()); if (translatedSym != null) { tree = make.at(tree.pos).Ident(translatedSym); } @@ -3605,18 +3597,25 @@ public void visitReturn(JCReturn tree) { } public void visitSwitch(JCSwitch tree) { - handleSwitch(tree, tree.selector, tree.cases); + List cases = tree.patternSwitch ? addDefaultIfNeeded(tree.cases) : tree.cases; + handleSwitch(tree, tree.selector, cases); } @Override public void visitSwitchExpression(JCSwitchExpression tree) { - if (tree.cases.stream().noneMatch(c -> c.pats.isEmpty())) { + List cases = addDefaultIfNeeded(tree.cases); + handleSwitch(tree, tree.selector, cases); + } + + private List addDefaultIfNeeded(List cases) { + if (cases.stream().flatMap(c -> c.labels.stream()).noneMatch(p -> p.hasTag(Tag.DEFAULTCASELABEL))) { JCThrow thr = make.Throw(makeNewClass(syms.incompatibleClassChangeErrorType, List.nil())); - JCCase c = make.Case(JCCase.STATEMENT, List.nil(), List.of(thr), null); - tree.cases = tree.cases.append(c); + JCCase c = make.Case(JCCase.STATEMENT, List.of(make.DefaultCaseLabel()), List.of(thr), null); + cases = cases.prepend(c); } - handleSwitch(tree, tree.selector, tree.cases); + + return cases; } private void handleSwitch(JCTree tree, JCExpression selector, List cases) { @@ -3624,7 +3623,7 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases ListBuffer convertedCases = new ListBuffer<>(); for (JCCase c : cases) { - switch (c.pats.size()) { + switch (c.labels.size()) { case 0: //default case 1: //single label convertedCases.append(c); @@ -3635,7 +3634,7 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases //case C1: //case C2: //case C3: ... - List patterns = c.pats; + List patterns = c.labels; while (patterns.tail.nonEmpty()) { convertedCases.append(make_at(c.pos()).Case(JCCase.STATEMENT, List.of(patterns.head), @@ -3643,7 +3642,7 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases null)); patterns = patterns.tail; } - c.pats = patterns; + c.labels = patterns; convertedCases.append(c); break; } @@ -3651,7 +3650,7 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases for (JCCase c : convertedCases) { if (c.caseKind == JCCase.RULE && c.completesNormally) { - JCBreak b = make_at(c.pos()).Break(null); + JCBreak b = make.at(TreeInfo.endPos(c.stats.last())).Break(null); b.target = tree; c.stats = c.stats.append(b); } @@ -3664,9 +3663,8 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases (selector.type.tsym.flags() & ENUM) != 0; boolean stringSwitch = selsuper != null && types.isSameType(selector.type, syms.stringType); - Type target = enumSwitch ? selector.type : - (stringSwitch? syms.stringType : syms.intType); - selector = translate(selector, target); + boolean boxedSwitch = !enumSwitch && !stringSwitch && !selector.type.isPrimitive(); + selector = translate(selector, selector.type); cases = translateCases(cases); if (tree.hasTag(SWITCH)) { ((JCSwitch) tree).selector = selector; @@ -3681,6 +3679,10 @@ private void handleSwitch(JCTree tree, JCExpression selector, List cases result = visitEnumSwitch(tree, selector, cases); } else if (stringSwitch) { result = visitStringSwitch(tree, selector, cases); + } else if (boxedSwitch) { + //An switch over boxed primitive. Pattern matching switches are already translated + //by TransPatterns, so all non-primitive types are only boxed primitives: + result = visitBoxedPrimitiveSwitch(tree, selector, cases); } else { result = tree; } @@ -3694,14 +3696,42 @@ public JCTree visitEnumSwitch(JCTree tree, JCExpression selector, List c names.ordinal, selector.type, List.nil()); - JCArrayAccess newSelector = make.Indexed(map.mapVar, - make.App(make.Select(selector, - ordinalMethod))); + JCExpression newSelector; + + if (cases.stream().anyMatch(c -> TreeInfo.isNull(c.labels.head))) { + //for enum switches with case null, do: + //switch ($selector != null ? $mapVar[$selector.ordinal()] : -1) {...} + //replacing case null with case -1: + VarSymbol dollar_s = new VarSymbol(FINAL|SYNTHETIC, + names.fromString("s" + tree.pos + this.target.syntheticNameChar()), + selector.type, + currentMethodSym); + JCStatement var = make.at(tree.pos()).VarDef(dollar_s, selector).setType(dollar_s.type); + newSelector = make.Indexed(map.mapVar, + make.App(make.Select(make.Ident(dollar_s), + ordinalMethod))); + newSelector = + make.LetExpr(List.of(var), + make.Conditional(makeBinary(NE, make.Ident(dollar_s), makeNull()), + newSelector, + makeLit(syms.intType, -1)) + .setType(newSelector.type)) + .setType(newSelector.type); + } else { + newSelector = make.Indexed(map.mapVar, + make.App(make.Select(selector, + ordinalMethod))); + } ListBuffer newCases = new ListBuffer<>(); for (JCCase c : cases) { - if (c.pats.nonEmpty()) { - VarSymbol label = (VarSymbol)TreeInfo.symbol(c.pats.head); - JCLiteral pat = map.forConstant(label); + if (c.labels.head.isExpression()) { + JCExpression pat; + if (TreeInfo.isNull(c.labels.head)) { + pat = makeLit(syms.intType, -1); + } else { + VarSymbol label = (VarSymbol)TreeInfo.symbol((JCExpression) c.labels.head); + pat = map.forConstant(label); + } newCases.append(make.Case(JCCase.STATEMENT, List.of(pat), c.stats, null)); } else { newCases.append(c); @@ -3778,23 +3808,30 @@ public JCTree visitStringSwitch(JCTree tree, JCExpression selector, List Map> hashToString = new LinkedHashMap<>(alternatives + 1, 1.0f); int casePosition = 0; + JCCase nullCase = null; + int nullCaseLabel = -1; for(JCCase oneCase : caseList) { - if (oneCase.pats.nonEmpty()) { // pats is empty for a "default" case - JCExpression expression = oneCase.pats.head; - String labelExpr = (String) expression.type.constValue(); - Integer mapping = caseLabelToPosition.put(labelExpr, casePosition); - Assert.checkNull(mapping); - int hashCode = labelExpr.hashCode(); - - Set stringSet = hashToString.get(hashCode); - if (stringSet == null) { - stringSet = new LinkedHashSet<>(1, 1.0f); - stringSet.add(labelExpr); - hashToString.put(hashCode, stringSet); + if (oneCase.labels.head.isExpression()) { + if (TreeInfo.isNull(oneCase.labels.head)) { + nullCase = oneCase; + nullCaseLabel = casePosition; } else { - boolean added = stringSet.add(labelExpr); - Assert.check(added); + JCExpression expression = (JCExpression) oneCase.labels.head; + String labelExpr = (String) expression.type.constValue(); + Integer mapping = caseLabelToPosition.put(labelExpr, casePosition); + Assert.checkNull(mapping); + int hashCode = labelExpr.hashCode(); + + Set stringSet = hashToString.get(hashCode); + if (stringSet == null) { + stringSet = new LinkedHashSet<>(1, 1.0f); + stringSet.add(labelExpr); + hashToString.put(hashCode, stringSet); + } else { + boolean added = stringSet.add(labelExpr); + Assert.check(added); + } } } casePosition++; @@ -3869,7 +3906,14 @@ public JCTree visitStringSwitch(JCTree tree, JCExpression selector, List } switch1.cases = caseBuffer.toList(); - stmtList.append(switch1); + + if (nullCase != null) { + stmtList.append(make.If(makeBinary(NE, make.Ident(dollar_s), makeNull()), switch1, make.Exec(make.Assign(make.Ident(dollar_tmp), + make.Literal(nullCaseLabel)). + setType(dollar_tmp.type))).setType(syms.intType)); + } else { + stmtList.append(switch1); + } // Make isomorphic switch tree replacing string labels // with corresponding integer ones from the label to @@ -3877,16 +3921,18 @@ public JCTree visitStringSwitch(JCTree tree, JCExpression selector, List ListBuffer lb = new ListBuffer<>(); for(JCCase oneCase : caseList ) { - boolean isDefault = (oneCase.pats.isEmpty()); - JCExpression caseExpr; + boolean isDefault = !oneCase.labels.head.isExpression(); + JCCaseLabel caseExpr; if (isDefault) caseExpr = null; - else { - caseExpr = make.Literal(caseLabelToPosition.get((String)TreeInfo.skipParens(oneCase.pats.head). + else if (oneCase == nullCase) { + caseExpr = make.Literal(nullCaseLabel); + } else { + caseExpr = make.Literal(caseLabelToPosition.get((String)TreeInfo.skipParens((JCExpression) oneCase.labels.head). type.constValue())); } - lb.append(make.Case(JCCase.STATEMENT, caseExpr == null ? List.nil() : List.of(caseExpr), + lb.append(make.Case(JCCase.STATEMENT, caseExpr == null ? List.of(make.DefaultCaseLabel()) : List.of(caseExpr), oneCase.stats, null)); } @@ -3898,7 +3944,9 @@ public JCTree visitStringSwitch(JCTree tree, JCExpression selector, List stmtList.append(switch2); - return make.Block(0L, stmtList.toList()); + JCBlock res = make.Block(0L, stmtList.toList()); + res.endpos = TreeInfo.endPos(tree); + return res; } else { JCSwitchExpression switch2 = make.SwitchExpression(make.Ident(dollar_tmp), lb.toList()); @@ -3918,6 +3966,70 @@ public JCTree visitStringSwitch(JCTree tree, JCExpression selector, List } } + private JCTree visitBoxedPrimitiveSwitch(JCTree tree, JCExpression selector, List cases) { + JCExpression newSelector; + + if (cases.stream().anyMatch(c -> TreeInfo.isNull(c.labels.head))) { + //a switch over a boxed primitive, with a null case. Pick two constants that are + //not used by any branch in the case (c1 and c2), close to other constants that are + //used in the switch. Then do: + //switch ($selector != null ? $selector != c1 ? $selector : c2 : c1) {...} + //replacing case null with case c1 + Set constants = new LinkedHashSet<>(); + JCCase nullCase = null; + + for (JCCase c : cases) { + if (TreeInfo.isNull(c.labels.head)) { + nullCase = c; + } else if (!c.labels.head.hasTag(DEFAULTCASELABEL)) { + constants.add((int) c.labels.head.type.constValue()); + } + } + + Assert.checkNonNull(nullCase); + + int nullValue = constants.isEmpty() ? 0 : constants.iterator().next(); + + while (constants.contains(nullValue)) nullValue++; + + constants.add(nullValue); + nullCase.labels.head = makeLit(syms.intType, nullValue); + + int replacementValue = nullValue; + + while (constants.contains(replacementValue)) replacementValue++; + + VarSymbol dollar_s = new VarSymbol(FINAL|SYNTHETIC, + names.fromString("s" + tree.pos + this.target.syntheticNameChar()), + selector.type, + currentMethodSym); + JCStatement var = make.at(tree.pos()).VarDef(dollar_s, selector).setType(dollar_s.type); + JCExpression nullValueReplacement = + make.Conditional(makeBinary(NE, + unbox(make.Ident(dollar_s), syms.intType), + makeLit(syms.intType, nullValue)), + unbox(make.Ident(dollar_s), syms.intType), + makeLit(syms.intType, replacementValue)) + .setType(syms.intType); + JCExpression nullCheck = + make.Conditional(makeBinary(NE, make.Ident(dollar_s), makeNull()), + nullValueReplacement, + makeLit(syms.intType, nullValue)) + .setType(syms.intType); + newSelector = make.LetExpr(List.of(var), nullCheck).setType(syms.intType); + } else { + newSelector = unbox(selector, syms.intType); + } + + if (tree.hasTag(SWITCH)) { + ((JCSwitch) tree).selector = newSelector; + } else { + ((JCSwitchExpression) tree).selector = newSelector; + } + + return tree; + } + @Override public void visitBreak(JCBreak tree) { result = tree; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java index 9b38944..32e4ac6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java @@ -29,6 +29,7 @@ import com.sun.tools.javac.code.Symbol.BindingSymbol; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCGuardPattern; import com.sun.tools.javac.tree.JCTree.Tag; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; @@ -96,13 +97,7 @@ public MatchBindings unary(JCTree tree, MatchBindings bindings) { public MatchBindings binary(JCTree tree, MatchBindings lhsBindings, MatchBindings rhsBindings) { switch (tree.getTag()) { case AND: { - // e.T = union(x.T, y.T) - // e.F = intersection(x.F, y.F) (error recovery) - List bindingsWhenTrue = - union(tree.pos(), lhsBindings.bindingsWhenTrue, rhsBindings.bindingsWhenTrue); - List bindingsWhenFalse = //error recovery - intersection(tree.pos(), lhsBindings.bindingsWhenFalse, rhsBindings.bindingsWhenFalse); - return new MatchBindings(bindingsWhenTrue, bindingsWhenFalse); + return andOperation(tree.pos(), lhsBindings, rhsBindings); } case OR: { // e.T = intersection(x.T, y.T) (error recovery) @@ -117,9 +112,37 @@ public MatchBindings binary(JCTree tree, MatchBindings lhsBindings, MatchBinding return EMPTY; } + public MatchBindings guardedPattern(JCGuardPattern tree, MatchBindings patternBindings, MatchBindings guardBindings) { + return andOperation(tree.pos(), patternBindings, guardBindings); + } + + public MatchBindings andOperation(DiagnosticPosition pos, MatchBindings lhsBindings, MatchBindings rhsBindings) { + // e.T = union(x.T, y.T) + // e.F = intersection(x.F, y.F) (error recovery) + List bindingsWhenTrue = + union(pos, lhsBindings.bindingsWhenTrue, rhsBindings.bindingsWhenTrue); + List bindingsWhenFalse = //error recovery + intersection(pos, lhsBindings.bindingsWhenFalse, rhsBindings.bindingsWhenFalse); + return new MatchBindings(bindingsWhenTrue, bindingsWhenFalse); + } + + public MatchBindings switchCase(JCTree tree, MatchBindings prevBindings, MatchBindings currentBindings) { + if (prevBindings == null) + return currentBindings; + if (prevBindings.nullPattern) { + return currentBindings; + } + if (currentBindings.nullPattern) { + return prevBindings; + } + return new MatchBindings(intersection(tree.pos(), prevBindings.bindingsWhenTrue, currentBindings.bindingsWhenTrue), + intersection(tree.pos(), prevBindings.bindingsWhenFalse, currentBindings.bindingsWhenFalse)); + } + public MatchBindings finishBindings(JCTree tree, MatchBindings matchBindings) { switch (tree.getTag()) { case NOT: case AND: case OR: case BINDINGPATTERN: + case PARENTHESIZEDPATTERN: case GUARDPATTERN: case PARENS: case TYPETEST: case CONDEXPR: //error recovery: return matchBindings; @@ -132,10 +155,16 @@ public static class MatchBindings { public final List bindingsWhenTrue; public final List bindingsWhenFalse; + public final boolean nullPattern; public MatchBindings(List bindingsWhenTrue, List bindingsWhenFalse) { + this(bindingsWhenTrue, bindingsWhenFalse, false); + } + + public MatchBindings(List bindingsWhenTrue, List bindingsWhenFalse, boolean nullPattern) { this.bindingsWhenTrue = bindingsWhenTrue; this.bindingsWhenFalse = bindingsWhenFalse; + this.nullPattern = nullPattern; } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java index e9aeeaa..f459d05 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -47,9 +47,13 @@ import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.TypeTag.FORALL; import static com.sun.tools.javac.code.TypeTag.TYPEVAR; + import static com.sun.tools.javac.code.TypeTag.VOID; import com.sun.tools.javac.model.LazyTreeLoader; import static com.sun.tools.javac.tree.JCTree.Tag.VARDEF; + + + /** Resolves field, method and constructor header, and constructs corresponding Symbols. * *

This is NOT part of any supported API. diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java index 4bb9e7d..417f1ff 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 @@ -1200,6 +1200,7 @@ public void visitProvides(JCProvides tree) { public void visitRequires(JCRequires tree) { if (tree.directive != null && allModules().contains(tree.directive.module)) { chk.checkDeprecated(tree.moduleName.pos(), msym, tree.directive.module); + chk.checkPreview(tree.moduleName.pos(), msym, tree.directive.module); chk.checkModuleRequires(tree.moduleName.pos(), tree.directive); msym.directives = msym.directives.prepend(tree.directive); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Repair.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Repair.java index d4b2e47..0c95b78 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Repair.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Repair.java @@ -39,6 +39,7 @@ import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.jvm.PoolWriter; +import com.sun.tools.javac.main.Option; import com.sun.tools.javac.parser.Tokens; import com.sun.tools.javac.resources.CompilerProperties; import com.sun.tools.javac.tree.JCTree; @@ -71,6 +72,7 @@ import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.MissingPlatformError; import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.util.Options; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; @@ -121,9 +123,11 @@ public static Repair instance(Context context) { private Name fixedTopLevelName; private Symbol runtimeExceptionDefaultConstructor = null; private Symbol runtimeExceptionConstructor = null; + private Context context; private Repair(Context context) { context.put(repairKey, this); + this.context = context; syms = Symtab.instance(context); rs = Resolve.instance(context); enter = Enter.instance(context); @@ -413,7 +417,7 @@ public void visitCase(JCCase tree) { l.head = translate(l.head); if (!hasError && l.head != null && (l.head.type == null || (l.head.type.tsym.flags() & Flags.ENUM) == 0 - && l.head.type.constValue() == null)) { + && (l.head.type.constValue() == null && !isSourceVersionSupportSwitchPattern()))) { LOGGER.warning("Repair.visitCase tree [" + tree + "] has wrong expression type [" + l.head.type + "]."); //NOI18N hasError = true; if (err == null && errMessage == null) @@ -458,6 +462,11 @@ private JCStatement generateErrStat(DiagnosticPosition pos, String msg) { return generateErrStat(make, pos, msg); } + private boolean isSourceVersionSupportSwitchPattern(){ + Options options = Options.instance(context); + String sourceVersion = options.get(Option.SOURCE); + return sourceVersion.compareTo(Source.JDK17.name) >= 0; + } JCStatement generateErrStat(TreeMaker make, DiagnosticPosition pos, String msg) { make.at(pos); ClassType ctype = (ClassType)syms.runtimeExceptionType; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index 1bb5d0d..fa9e236 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -69,6 +69,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import javax.lang.model.element.ElementVisitor; @@ -145,8 +146,7 @@ protected Resolve(Context context) { Target target = Target.instance(context); allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source); allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source); - allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) && - Feature.SWITCH_EXPRESSION.allowedInSource(source); + allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source); checkVarargsAccessAfterResolution = Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source); polymorphicSignatureScope = WriteableScope.create(syms.noSymbol); @@ -387,9 +387,14 @@ boolean isAccessible(Env env, Type t) { } boolean isAccessible(Env env, Type t, boolean checkInner) { - return (t.hasTag(ARRAY)) - ? isAccessible(env, types.cvarUpperBound(types.elemtype(t))) - : isAccessible(env, t.tsym, checkInner); + if (t.hasTag(ARRAY)) { + return isAccessible(env, types.cvarUpperBound(types.elemtype(t))); + } else if (t.isUnion()) { + return StreamSupport.stream(((UnionClassType) t).getAlternativeTypes().spliterator(), false) + .allMatch(alternative -> isAccessible(env, alternative.tsym, checkInner)); + } else { + return isAccessible(env, t.tsym, checkInner); + } } /** Is symbol accessible as a member of given type in given environment? @@ -1484,30 +1489,24 @@ Symbol findVar(Env env, Name name) { boolean staticOnly = false; while (env1.outer != null && env1.enclClass.sym != null) { Symbol sym = null; - if (isStatic(env1)) staticOnly = true; for (Symbol s : env1.info.scope.getSymbolsByName(name)) { if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) { sym = s; + if (staticOnly) { + return new StaticError(sym); + } break; } } + if (isStatic(env1)) staticOnly = true; if (sym == null) { sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym); } if (sym.exists()) { if (staticOnly && - (sym.flags() & STATIC) == 0 && - sym.kind == VAR && - // if it is a field - (sym.owner.kind == TYP || - // or it is a local variable but it is not declared inside of the static local type - // then error - allowRecords && - (sym.owner.kind == MTH) && - env1 != env && - !isInnerClassOfMethod(sym.owner, env.tree.hasTag(CLASSDEF) ? - ((JCClassDecl)env.tree).sym : - env.enclClass.sym))) + sym.kind == VAR && + sym.owner.kind == TYP && + (sym.flags() & STATIC) == 0) return new StaticError(sym); else return sym; @@ -1595,7 +1594,7 @@ Symbol selectBest(Env env, case ABSENT_MTH: return new InapplicableSymbolError(currentResolutionContext); case HIDDEN: - if (bestSoFar instanceof AccessError) { + if (bestSoFar instanceof AccessError) { // Add the JCDiagnostic of previous AccessError to the currentResolutionContext // and construct InapplicableSymbolsError. // Intentionally fallthrough. @@ -1794,7 +1793,7 @@ Symbol findMethodInScope(Env env, return bestSoFar; } //where - class LookupFilter implements Filter { + class LookupFilter implements Predicate { boolean abstractOk; @@ -1802,7 +1801,8 @@ class LookupFilter implements Filter { this.abstractOk = abstractOk; } - public boolean accepts(Symbol s) { + @Override + public boolean test(Symbol s) { long flags = s.flags(); return s.kind == MTH && (flags & SYNTHETIC) == 0 && @@ -2310,35 +2310,22 @@ Symbol findGlobalType(Env env, Scope scope, Name name, RecoveryLoad return bestSoFar; } - Symbol findTypeVar(Env currentEnv, Env originalEnv, Name name, boolean staticOnly) { - for (Symbol sym : currentEnv.info.scope.getSymbolsByName(name)) { + Symbol findTypeVar(Env env, Name name, boolean staticOnly) { + for (Symbol sym : env.info.scope.getSymbolsByName(name)) { if (sym.kind == TYP) { - if (staticOnly && - sym.type.hasTag(TYPEVAR) && - ((sym.owner.kind == TYP) || - // are we trying to access a TypeVar defined in a method from a local static type: interface, enum or record? - allowRecords && - (sym.owner.kind == MTH && - currentEnv != originalEnv && - !isInnerClassOfMethod(sym.owner, originalEnv.tree.hasTag(CLASSDEF) ? - ((JCClassDecl)originalEnv.tree).sym : - originalEnv.enclClass.sym)))) { + if (sym.type.hasTag(TYPEVAR) && + (staticOnly || (isStatic(env) && sym.owner.kind == TYP))) + // if staticOnly is set, it means that we have recursed through a static declaration, + // so type variable symbols should not be accessible. If staticOnly is unset, but + // we are in a static declaration (field or method), we should not allow type-variables + // defined in the enclosing class to "leak" into this context. return new StaticError(sym); - } return sym; } } return typeNotFound; } - boolean isInnerClassOfMethod(Symbol msym, Symbol csym) { - while (csym.owner != msym) { - if (csym.isStatic()) return false; - csym = csym.owner.enclClass(); - } - return (csym.owner == msym && !csym.isStatic()); - } - /** Find an unqualified type symbol. * @param env The current environment. * @param name The type's name. @@ -2350,9 +2337,9 @@ Symbol findType(Env env, Name name) { Symbol sym; boolean staticOnly = false; for (Env env1 = env; env1.outer != null; env1 = env1.outer) { - if (isStatic(env1)) staticOnly = true; // First, look for a type variable and the first member type - final Symbol tyvar = findTypeVar(env1, env, name, staticOnly); + final Symbol tyvar = findTypeVar(env1, name, staticOnly); + if (isStatic(env1)) staticOnly = true; sym = findImmediateMemberType(env1, env1.enclClass.sym.type, name, env1.enclClass.sym); @@ -2633,6 +2620,15 @@ public List getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name } }; + LogResolveHelper silentLogResolveHelper = new LogResolveHelper() { + public boolean resolveDiagnosticNeeded(Type site, List argtypes, List typeargtypes) { + return false; + } + public List getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List argtypes) { + return argtypes; + } + }; + LogResolveHelper methodLogResolveHelper = new LogResolveHelper() { public boolean resolveDiagnosticNeeded(Type site, List argtypes, List typeargtypes) { return !site.isErroneous() && @@ -2902,7 +2898,7 @@ Symbol findConstructor(DiagnosticPosition pos, Env env, typeargtypes, allowBoxing, useVarargs); chk.checkDeprecated(pos, env.info.scope.owner, sym); - chk.checkPreview(pos, sym); + chk.checkPreview(pos, env.info.scope.owner, sym); return sym; } @@ -2967,7 +2963,7 @@ private Symbol findDiamond(DiagnosticPosition pos, boolean useVarargs) { Symbol sym = findDiamond(env, site, argtypes, typeargtypes, allowBoxing, useVarargs); chk.checkDeprecated(pos, env.info.scope.owner, sym); - chk.checkPreview(pos, sym); + chk.checkPreview(pos, env.info.scope.owner, sym); return sym; } @@ -3425,7 +3421,7 @@ abstract class LookupHelper { */ final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { return phase.ordinal() > maxPhase.ordinal() || - !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS; + !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS || sym.kind == STATICERR; } /** @@ -3790,7 +3786,7 @@ private List pruneInterfaces(Type t) { for (Type t1 : types.interfaces(t)) { boolean shouldAdd = true; for (Type t2 : types.directSupertypes(t)) { - if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) { + if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) { shouldAdd = false; } } @@ -4061,8 +4057,10 @@ JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, if (location == null) { location = site.tsym; } + if (location != null && !location.name.isEmpty()) { - if (location.kind == PCK && !site.tsym.exists()) { + if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) { + return diags.create(dkind, log.currentSource(), pos, "doesnt.exist", location); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java index 8e6d0e6..d194025 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -25,14 +25,21 @@ package com.sun.tools.javac.comp; +import com.sun.source.tree.CaseTree; +import com.sun.tools.javac.code.BoundKind; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Kinds; +import com.sun.tools.javac.code.Kinds.Kind; +import com.sun.tools.javac.code.Preview; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.BindingSymbol; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; +import com.sun.tools.javac.code.Symbol.DynamicVarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Types; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCConditional; @@ -43,33 +50,52 @@ import com.sun.tools.javac.tree.JCTree.JCInstanceOf; import com.sun.tools.javac.tree.JCTree.JCLabeledStatement; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCSwitch; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCBindingPattern; import com.sun.tools.javac.tree.JCTree.JCWhileLoop; import com.sun.tools.javac.tree.JCTree.Tag; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; -import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Options; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import com.sun.tools.javac.code.Symbol.MethodSymbol; +import com.sun.tools.javac.code.Type.ClassType; +import com.sun.tools.javac.code.Type.MethodType; +import com.sun.tools.javac.code.Type.WildcardType; +import com.sun.tools.javac.code.TypeTag; import static com.sun.tools.javac.code.TypeTag.BOT; +import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCBreak; +import com.sun.tools.javac.tree.JCTree.JCCase; +import com.sun.tools.javac.tree.JCTree.JCCaseLabel; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCContinue; import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCGuardPattern; import com.sun.tools.javac.tree.JCTree.JCLambda; +import com.sun.tools.javac.tree.JCTree.JCParenthesizedPattern; +import com.sun.tools.javac.tree.JCTree.JCPattern; import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCSwitchExpression; import com.sun.tools.javac.tree.JCTree.LetExpr; +import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.List; -import java.util.HashMap; +import java.util.Iterator; /** * This pass translates pattern-matching constructs, such as instanceof . @@ -86,13 +112,15 @@ public static TransPatterns instance(Context context) { } private final Symtab syms; + private final Attr attr; + private final Resolve rs; private final Types types; private final Operators operators; - private final Log log; - private final ConstFold constFold; private final Names names; private final Target target; + private final Preview preview; private TreeMaker make; + private Env env; BindingContext bindingContext = new BindingContext() { @Override @@ -105,6 +133,11 @@ VarSymbol getBindingFor(BindingSymbol varSymbol) { return null; } + @Override + List bindingVars(int diagPos) { + return List.nil(); + } + @Override JCStatement decorateStatement(JCStatement stat) { return stat; @@ -131,58 +164,362 @@ boolean tryPrepend(BindingSymbol binding, JCVariableDecl var) { boolean debugTransPatterns; + private ClassSymbol currentClass = null; private MethodSymbol currentMethodSym = null; + private VarSymbol currentValue = null; protected TransPatterns(Context context) { context.put(transPatternsKey, this); syms = Symtab.instance(context); + attr = Attr.instance(context); + rs = Resolve.instance(context); make = TreeMaker.instance(context); types = Types.instance(context); operators = Operators.instance(context); - log = Log.instance(context); - constFold = ConstFold.instance(context); names = Names.instance(context); target = Target.instance(context); + preview = Preview.instance(context); debugTransPatterns = Options.instance(context).isSet("debug.patterns"); } @Override public void visitTypeTest(JCInstanceOf tree) { - if (tree.pattern.hasTag(Tag.BINDINGPATTERN)) { - //E instanceof T N + if (tree.pattern instanceof JCPattern) { + //E instanceof $pattern //=> - //(let T' N$temp = E; N$temp instanceof T && (N = (T) N$temp == (T) N$temp)) - JCBindingPattern patt = (JCBindingPattern)tree.pattern; - VarSymbol pattSym = patt.var.sym; + //(let T' N$temp = E; N$temp instanceof typeof($pattern) && ) + //note the pattern desugaring performs binding variable assignments Type tempType = tree.expr.type.hasTag(BOT) ? syms.objectType : tree.expr.type; - VarSymbol temp = new VarSymbol(pattSym.flags() | Flags.SYNTHETIC, - names.fromString(pattSym.name.toString() + target.syntheticNameChar() + "temp"), - tempType, - patt.var.sym.owner); - JCExpression translatedExpr = translate(tree.expr); - Type castTargetType = types.boxedTypeOrType(pattSym.erasure(types)); - - result = makeTypeTest(make.Ident(temp), make.Type(castTargetType)); - - VarSymbol bindingVar = bindingContext.bindingDeclared((BindingSymbol) patt.var.sym); - if (bindingVar != null) { //TODO: cannot be null here? - JCAssign fakeInit = (JCAssign)make.at(tree.pos).Assign( - make.Ident(bindingVar), convert(make.Ident(temp), castTargetType)).setType(bindingVar.erasure(types)); - LetExpr nestedLE = make.LetExpr(List.of(make.Exec(fakeInit)), - make.Literal(true)); - nestedLE.needsCond = true; - nestedLE.setType(syms.booleanType); - result = makeBinary(Tag.AND, (JCExpression)result, nestedLE); + VarSymbol prevCurrentValue = currentValue; + bindingContext = new BasicBindingContext(); + try { + JCExpression translatedExpr = translate(tree.expr); + Symbol exprSym = TreeInfo.symbol(translatedExpr); + + if (exprSym != null && + exprSym.kind == Kind.VAR && + exprSym.owner.kind.matches(Kinds.KindSelector.VAL_MTH)) { + currentValue = (VarSymbol) exprSym; + } else { + currentValue = new VarSymbol(Flags.FINAL | Flags.SYNTHETIC, + names.fromString("patt" + tree.pos + target.syntheticNameChar() + "temp"), + tempType, + currentMethodSym); + } + + Type principalType = principalType((JCPattern) tree.pattern); + JCExpression resultExpression= + makeBinary(Tag.AND, + makeTypeTest(make.Ident(currentValue), make.Type(principalType)), + (JCExpression) this.translate(tree.pattern)); + if (currentValue != exprSym) { + resultExpression = + make.at(tree.pos).LetExpr(make.VarDef(currentValue, translatedExpr), + resultExpression).setType(syms.booleanType); + ((LetExpr) resultExpression).needsCond = true; + } + result = bindingContext.decorateExpression(resultExpression); + } finally { + currentValue = prevCurrentValue; + bindingContext.pop(); } - result = make.at(tree.pos).LetExpr(make.VarDef(temp, translatedExpr), (JCExpression)result).setType(syms.booleanType); - ((LetExpr) result).needsCond = true; } else { super.visitTypeTest(tree); } } + @Override + public void visitBindingPattern(JCBindingPattern tree) { + //it is assumed the primary type has already been checked: + BindingSymbol binding = (BindingSymbol) tree.var.sym; + Type castTargetType = principalType(tree); + VarSymbol bindingVar = bindingContext.bindingDeclared(binding); + + if (bindingVar != null) { + JCAssign fakeInit = (JCAssign)make.at(TreeInfo.getStartPos(tree)).Assign( + make.Ident(bindingVar), convert(make.Ident(currentValue), castTargetType)).setType(bindingVar.erasure(types)); + LetExpr nestedLE = make.LetExpr(List.of(make.Exec(fakeInit)), + make.Literal(true)); + nestedLE.needsCond = true; + nestedLE.setType(syms.booleanType); + result = nestedLE; + } else { + result = make.Literal(true); + } + } + + @Override + public void visitParenthesizedPattern(JCParenthesizedPattern tree) { + result = translate(tree.pattern); + } + + @Override + public void visitGuardPattern(JCGuardPattern tree) { + JCExpression pattern = (JCExpression) this.translate(tree.patt); + JCExpression guard = translate(tree.expr); + result = makeBinary(Tag.AND, pattern, guard); + } + + @Override + public void visitSwitch(JCSwitch tree) { + handleSwitch(tree, tree.selector, tree.cases, tree.hasTotalPattern, tree.patternSwitch); + } + + @Override + public void visitSwitchExpression(JCSwitchExpression tree) { + handleSwitch(tree, tree.selector, tree.cases, tree.hasTotalPattern, tree.patternSwitch); + } + + private void handleSwitch(JCTree tree, + JCExpression selector, + List cases, + boolean hasTotalPattern, + boolean patternSwitch) { + Type seltype = selector.type; + + if (patternSwitch) { + Assert.check(preview.isEnabled()); + Assert.check(preview.usesPreview(env.toplevel.sourcefile)); + + //rewrite pattern matching switches: + //switch ($obj) { + // case $constant: $stats$ + // case $pattern1: $stats$ + // case $pattern2, null: $stats$ + // case $pattern3: $stats$ + //} + //=> + //int $idx = 0; + //$RESTART: switch (invokeDynamic typeSwitch($constant, typeof($pattern1), typeof($pattern2), typeof($pattern3))($obj, $idx)) { + // case 0: + // if (!()) { $idx = 1; continue $RESTART; } + // $stats$ + // case 1: + // if (!()) { $idx = 2; continue $RESTART; } + // $stats$ + // case 2, -1: + // if (!()) { $idx = 3; continue $RESTART; } + // $stats$ + // case 3: + // if (!()) { $idx = 4; continue $RESTART; } + // $stats$ + //} + //notes: + //-pattern desugaring performs assignment to the binding variables + //-the selector is evaluated only once and stored in a temporary variable + //-typeSwitch bootstrap method can restart matching at specified index. The bootstrap will + // categorize the input, and return the case index whose type or constant matches the input. + // The bootstrap does not evaluate guards, which are injected at the beginning of the case's + // statement list, and if the guard fails, the switch is "continued" and matching is + // restarted from the next index. + //-case null is always desugared to case -1, as the typeSwitch bootstrap method will + // return -1 when the input is null + // + //note the selector is evaluated only once and stored in a temporary variable + ListBuffer newCases = new ListBuffer<>(); + for (List c = cases; c.nonEmpty(); c = c.tail) { + if (c.head.stats.isEmpty() && c.tail.nonEmpty()) { + c.tail.head.labels = c.tail.head.labels.prependList(c.head.labels); + } else { + newCases.add(c.head); + } + } + cases = newCases.toList(); + ListBuffer statements = new ListBuffer<>(); + VarSymbol temp = new VarSymbol(Flags.SYNTHETIC, + names.fromString("selector" + tree.pos + target.syntheticNameChar() + "temp"), + seltype, + currentMethodSym); + boolean hasNullCase = cases.stream() + .flatMap(c -> c.labels.stream()) + .anyMatch(p -> p.isExpression() && + TreeInfo.isNull((JCExpression) p)); + + JCCase lastCase = cases.last(); + + if (hasTotalPattern && !hasNullCase) { + JCCase last = lastCase; + if (last.labels.stream().noneMatch(l -> l.hasTag(Tag.DEFAULTCASELABEL))) { + last.labels = last.labels.prepend(makeLit(syms.botType, null)); + hasNullCase = true; + } + } + selector = translate(selector); + statements.append(make.at(tree.pos).VarDef(temp, !hasNullCase ? attr.makeNullCheck(selector) + : selector)); + VarSymbol index = new VarSymbol(Flags.SYNTHETIC, + names.fromString(tree.pos + target.syntheticNameChar() + "index"), + syms.intType, + currentMethodSym); + statements.append(make.at(tree.pos).VarDef(index, makeLit(syms.intType, 0))); + + List staticArgTypes = List.of(syms.methodHandleLookupType, + syms.stringType, + syms.methodTypeType, + types.makeArrayType(new ClassType(syms.classType.getEnclosingType(), + List.of(new WildcardType(syms.objectType, BoundKind.UNBOUND, + syms.boundClass)), + syms.classType.tsym))); + LoadableConstant[] staticArgValues = + cases.stream() + .flatMap(c -> c.labels.stream()) + .map(l -> toLoadableConstant(l, seltype)) + .filter(c -> c != null) + .toArray(s -> new LoadableConstant[s]); + + boolean enumSelector = seltype.tsym.isEnum(); + Name bootstrapName = enumSelector ? names.enumSwitch : names.typeSwitch; + Symbol bsm = rs.resolveInternalMethod(tree.pos(), env, syms.switchBootstrapsType, + bootstrapName, staticArgTypes, List.nil()); + + MethodType indyType = new MethodType( + List.of(enumSelector ? seltype : syms.objectType, syms.intType), + syms.intType, + List.nil(), + syms.methodClass + ); + DynamicMethodSymbol dynSym = new DynamicMethodSymbol(bootstrapName, + syms.noSymbol, + ((MethodSymbol)bsm).asHandle(), + indyType, + staticArgValues); + + JCFieldAccess qualifier = make.Select(make.QualIdent(bsm.owner), dynSym.name); + qualifier.sym = dynSym; + qualifier.type = syms.intType; + selector = make.Apply(List.nil(), + qualifier, + List.of(make.Ident(temp), make.Ident(index))) + .setType(syms.intType); + + int i = 0; + boolean previousCompletesNormally = false; + boolean hasDefault = false; + + for (JCCase c : cases) { + List clearedPatterns = c.labels; + boolean hasJoinedNull = + c.labels.size() > 1 && c.labels.stream().anyMatch(l -> l.isNullPattern()); + if (hasJoinedNull) { + clearedPatterns = c.labels.stream() + .filter(l -> !l.isNullPattern()) + .collect(List.collector()); + } + if (clearedPatterns.size() == 1 && clearedPatterns.head.isPattern() && !previousCompletesNormally) { + JCCaseLabel p = clearedPatterns.head; + bindingContext = new BasicBindingContext(); + VarSymbol prevCurrentValue = currentValue; + try { + currentValue = temp; + JCExpression test = (JCExpression) this.translate(p); + c.stats = translate(c.stats); + JCContinue continueSwitch = make.at(clearedPatterns.head.pos()).Continue(null); + continueSwitch.target = tree; + c.stats = c.stats.prepend(make.If(makeUnary(Tag.NOT, test).setType(syms.booleanType), + make.Block(0, List.of(make.Exec(make.Assign(make.Ident(index), + makeLit(syms.intType, i + 1)) + .setType(syms.intType)), + continueSwitch)), + null)); + c.stats = c.stats.prependList(bindingContext.bindingVars(c.pos)); + } finally { + currentValue = prevCurrentValue; + bindingContext.pop(); + } + } else { + c.stats = translate(c.stats); + } + ListBuffer translatedLabels = new ListBuffer<>(); + for (JCCaseLabel p : c.labels) { + if (p.hasTag(Tag.DEFAULTCASELABEL)) { + translatedLabels.add(p); + hasDefault = true; + } else if (hasTotalPattern && !hasDefault && + c == lastCase && p.isPattern()) { + //If the switch has total pattern, the last case will contain it. + //Convert the total pattern to default: + translatedLabels.add(make.DefaultCaseLabel()); + } else { + int value; + if (p.isNullPattern()) { + value = -1; + } else { + value = i++; + } + translatedLabels.add(make.Literal(value)); + } + } + c.labels = translatedLabels.toList(); + if (c.caseKind == CaseTree.CaseKind.STATEMENT) { + previousCompletesNormally = c.completesNormally; + } else { + previousCompletesNormally = false; + JCBreak brk = make.at(TreeInfo.endPos(c.stats.last())).Break(null); + brk.target = tree; + c.stats = c.stats.append(brk); + } + } + + if (tree.hasTag(Tag.SWITCH)) { + ((JCSwitch) tree).selector = selector; + ((JCSwitch) tree).cases = cases; + statements.append((JCSwitch) tree); + result = make.Block(0, statements.toList()); + } else { + ((JCSwitchExpression) tree).selector = selector; + ((JCSwitchExpression) tree).cases = cases; + LetExpr r = (LetExpr) make.LetExpr(statements.toList(), (JCSwitchExpression) tree) + .setType(tree.type); + + r.needsCond = true; + result = r; + } + return ; + } + if (tree.hasTag(Tag.SWITCH)) { + super.visitSwitch((JCSwitch) tree); + } else { + super.visitSwitchExpression((JCSwitchExpression) tree); + } + } + + private Type principalType(JCPattern p) { + return types.boxedTypeOrType(types.erasure(TreeInfo.primaryPatternType(p).type())); + } + + private LoadableConstant toLoadableConstant(JCCaseLabel l, Type selector) { + if (l.isPattern()) { + Type principalType = principalType((JCPattern) l); + if (types.isSubtype(selector, principalType)) { + return (LoadableConstant) selector; + } else { + return (LoadableConstant) principalType; + } + } else if (l.isExpression() && !TreeInfo.isNull((JCExpression) l)) { + if ((l.type.tsym.flags_field & Flags.ENUM) != 0) { + return LoadableConstant.String(((JCIdent) l).name.toString()); + } else { + Assert.checkNonNull(l.type.constValue()); + LoadableConstant loadableConstant= null; + switch (l.type.getTag()) { + case BYTE: CHAR: + SHORT: INT: + loadableConstant = LoadableConstant.Int((Integer) l.type.constValue()); + break; + case CLASS: + loadableConstant = LoadableConstant.String((String) l.type.constValue()); + break; + default: throw new AssertionError(); + }; + return loadableConstant; + } + } else { + return null; + } + } + @Override public void visitBinary(JCBinary tree) { bindingContext = new BasicBindingContext(); @@ -297,7 +634,15 @@ boolean tryPrepend(BindingSymbol binding, JCVariableDecl var) { return true; } }; + MethodSymbol oldMethodSym = currentMethodSym; try { + if (currentMethodSym == null) { + // Block is a static or instance initializer. + currentMethodSym = + new MethodSymbol(tree.flags | Flags.BLOCK, + names.empty, null, + currentClass); + } for (List l = tree.stats; l.nonEmpty(); l = l.tail) { statements.append(translate(l.head)); } @@ -305,6 +650,7 @@ boolean tryPrepend(BindingSymbol binding, JCVariableDecl var) { tree.stats = statements.toList(); result = tree; } finally { + currentMethodSym = oldMethodSym; bindingContext.pop(); } } @@ -320,13 +666,45 @@ public void visitLambda(JCLambda tree) { } } + @Override + public void visitClassDef(JCClassDecl tree) { + ClassSymbol prevCurrentClass = currentClass; + try { + currentClass = tree.sym; + super.visitClassDef(tree); + } finally { + currentClass = prevCurrentClass; + } + } + + public void visitVarDef(JCVariableDecl tree) { + MethodSymbol prevMethodSym = currentMethodSym; + try { + tree.mods = translate(tree.mods); + tree.vartype = translate(tree.vartype); + if (currentMethodSym == null) { + // A class or instance field initializer. + currentMethodSym = + new MethodSymbol((tree.mods.flags&Flags.STATIC) | Flags.BLOCK, + names.empty, null, + currentClass); + } + if (tree.init != null) tree.init = translate(tree.init); + result = tree; + } finally { + currentMethodSym = prevMethodSym; + } + } + public JCTree translateTopLevelClass(Env env, JCTree cdef, TreeMaker make) { try { this.make = make; + this.env = env; translate(cdef); } finally { // note that recursive invocations of this method fail hard this.make = null; + this.env = null; } return cdef; @@ -355,6 +733,17 @@ JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) { return tree; } + /** Make an attributed unary expression. + * @param optag The operators tree tag. + * @param arg The operator's argument. + */ + JCTree.JCUnary makeUnary(JCTree.Tag optag, JCExpression arg) { + JCTree.JCUnary tree = make.Unary(optag, arg); + tree.operator = operators.resolveUnary(tree, optag, arg.type); + tree.type = tree.operator.type.getReturnType(); + return tree; + } + JCExpression convert(JCExpression expr, Type target) { JCExpression result = make.at(expr.pos()).TypeCast(make.Type(target), expr); result.type = target; @@ -364,6 +753,7 @@ JCExpression convert(JCExpression expr, Type target) { abstract class BindingContext { abstract VarSymbol bindingDeclared(BindingSymbol varSymbol); abstract VarSymbol getBindingFor(BindingSymbol varSymbol); + abstract List bindingVars(int diagPos); abstract JCStatement decorateStatement(JCStatement stat); abstract JCExpression decorateExpression(JCExpression expr); abstract BindingContext pop(); @@ -376,14 +766,14 @@ class BasicBindingContext extends BindingContext { public BasicBindingContext() { this.parent = bindingContext; - this.hoistedVarMap = new HashMap<>(); + this.hoistedVarMap = new LinkedHashMap<>(); } @Override VarSymbol bindingDeclared(BindingSymbol varSymbol) { VarSymbol res = parent.bindingDeclared(varSymbol); if (res == null) { - res = new VarSymbol(varSymbol.flags(), varSymbol.name, varSymbol.type, varSymbol.owner); + res = new VarSymbol(varSymbol.flags(), varSymbol.name, varSymbol.type, currentMethodSym); res.setTypeAttributes(varSymbol.getRawTypeAttributes()); hoistedVarMap.put(varSymbol, res); } @@ -402,9 +792,22 @@ VarSymbol getBindingFor(BindingSymbol varSymbol) { .map(e -> e.getValue()).orElse(null); } + @Override + List bindingVars(int diagPos) { + if (hoistedVarMap.isEmpty()) return List.nil(); + ListBuffer stats = new ListBuffer<>(); + for (Entry e : hoistedVarMap.entrySet()) { + JCVariableDecl decl = makeHoistedVarDecl(diagPos, e.getValue()); + if (!e.getKey().isPreserved() || + !parent.tryPrepend(e.getKey(), decl)) { + stats.add(decl); + } + } + return stats.toList(); + } + @Override JCStatement decorateStatement(JCStatement stat) { - if (hoistedVarMap.isEmpty()) return stat; //if (E instanceof T N) { // //use N //} @@ -415,17 +818,9 @@ JCStatement decorateStatement(JCStatement stat) { // //use N // } //} - ListBuffer stats = new ListBuffer<>(); - for (Entry e : hoistedVarMap.entrySet()) { - JCVariableDecl decl = makeHoistedVarDecl(stat.pos, e.getValue()); - if (!e.getKey().isPreserved() || - !parent.tryPrepend(e.getKey(), decl)) { - stats.add(decl); - } - } + List stats = bindingVars(stat.pos); if (stats.nonEmpty()) { - stats.add(stat); - stat = make.at(stat.pos).Block(0, stats.toList()); + stat = make.at(stat.pos).Block(0, stats.append(stat)); } return stat; } @@ -464,4 +859,14 @@ VarSymbol bindingDeclared(BindingSymbol varSymbol) { } } + + /** Make an attributed tree representing a literal. This will be an + * Ident node in the case of boolean literals, a Literal node in all + * other cases. + * @param type The literal's type. + * @param value The literal's value. + */ + JCExpression makeLit(Type type, Object value) { + return make.Literal(type.getTag(), value).setType(type.constType(value)); + } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java index 594a80d..7d83f4b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -25,15 +25,11 @@ package com.sun.tools.javac.comp; -import java.util.*; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.code.Type.IntersectionClassType; -import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError; -import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; @@ -567,7 +563,7 @@ public void visitSwitch(JCSwitch tree) { } public void visitCase(JCCase tree) { - tree.pats = translate(tree.pats, null); + tree.labels = translate(tree.labels, null); tree.stats = translate(tree.stats); result = tree; } @@ -588,6 +584,19 @@ public void visitSwitchExpression(JCSwitchExpression tree) { result = retype(tree, tree.type, pt); } + @Override + public void visitParenthesizedPattern(JCParenthesizedPattern tree) { + tree.pattern = translate(tree.pattern, null); + result = tree; + } + + @Override + public void visitGuardPattern(JCGuardPattern tree) { + tree.patt = translate(tree.patt, null); + tree.expr = translate(tree.expr, syms.booleanType); + result = tree; + } + public void visitSynchronized(JCSynchronized tree) { tree.lock = translate(tree.lock, erasure(tree.lock.type)); tree.body = translate(tree.body); @@ -772,7 +781,7 @@ public void visitTypeCast(JCTypeCast tree) { JCTypeCast typeCast = newExpression.hasTag(Tag.TYPECAST) ? (JCTypeCast) newExpression : null; - tree.expr = typeCast != null && types.isSameType(typeCast.type, originalTarget) + tree.expr = typeCast != null && types.isSameType(typeCast.type, tree.type) ? typeCast.expr : newExpression; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java index 971abe6..52efdcb 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java @@ -45,6 +45,7 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCConditional; import com.sun.tools.javac.tree.JCTree.JCContinue; +import com.sun.tools.javac.tree.JCTree.JCDefaultCaseLabel; import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop; import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; import com.sun.tools.javac.tree.JCTree.JCErroneous; @@ -284,7 +285,12 @@ public void visitYield(JCYield tree) { @Override public void visitCase(JCCase tree) { JCCase that = (JCCase) parameter; - result = scan(tree.pats, that.pats) && scan(tree.stats, that.stats); + result = scan(tree.labels, that.labels) && scan(tree.stats, that.stats); + } + + @Override + public void visitDefaultCaseLabel(JCDefaultCaseLabel tree) { + result = true; } @Override diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java index 189eac6..8517f50 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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,7 +96,7 @@ public class TypeEnter implements Completer { /** A switch to determine whether we check for package/class conflicts */ - final static boolean checkClash = true; + static final boolean checkClash = true; private final Names names; private final Enter enter; @@ -115,10 +115,14 @@ public class TypeEnter implements Completer { private final Lint lint; private final TypeEnvs typeEnvs; private final Dependencies dependencies; + private final DeferredCompletionFailureHandler dcfh; private final JavacMessages messages; private final boolean ignoreNoLang; + private final Preview preview; + + public static TypeEnter instance(Context context) { TypeEnter instance = context.get(typeEnterKey); if (instance == null) @@ -145,6 +149,7 @@ protected TypeEnter(Context context) { lint = Lint.instance(context); typeEnvs = TypeEnvs.instance(context); dependencies = Dependencies.instance(context); + preview = Preview.instance(context); Source source = Source.instance(context); allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source); allowDeprecationOnImport = Feature.DEPRECATION_ON_IMPORT.allowedInSource(source); @@ -1589,7 +1594,7 @@ private void handleDeprecatedAnnotations(List annotations, Symbol setFlagIfAttributeTrue(a, sym, names.forRemoval, DEPRECATED_REMOVAL); } else if (a.annotationType.type == syms.previewFeatureType) { sym.flags_field |= Flags.PREVIEW_API; - setFlagIfAttributeTrue(a, sym, names.essentialAPI, PREVIEW_ESSENTIAL_API); + setFlagIfAttributeTrue(a, sym, names.reflective, Flags.PREVIEW_REFLECTIVE); } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java index 20f7a48..fab7b10 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java index 4491988..8abcf3d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -122,7 +122,7 @@ public int compare(Path f1, Path f2) { REVERSE { @Override public int compare(Path f1, Path f2) { - return -f1.getFileName().compareTo(f2.getFileName()); + return f2.getFileName().compareTo(f1.getFileName()); } } } @@ -956,17 +956,16 @@ public Iterable getJavaFileObjectsFromFiles( } @Override @DefinedBy(Api.COMPILER) - public Iterable getJavaFileObjectsFromPaths( - Collection paths) - { + public Iterable getJavaFileObjectsFromPaths(Collection paths) { ArrayList result; - if (paths instanceof Collection) - result = new ArrayList<>(((Collection)paths).size()); - else + if (paths != null) { + result = new ArrayList<>(paths.size()); + for (Path p: paths) + result.add(PathFileObject.forSimplePath(this, + fsInfo.getCanonicalFile(p), p)); + } else { result = new ArrayList<>(); - for (Path p: paths) - result.add(PathFileObject.forSimplePath(this, - fsInfo.getCanonicalFile(p), p)); + } return result; } @@ -1099,7 +1098,7 @@ public int compareTo(PathAndContainer other) { @Override public boolean equals(Object o) { - if (o == null || !(o instanceof PathAndContainer)) { + if (o == null || !(o instanceof PathAndContainer)) { return false; } PathAndContainer that = (PathAndContainer) o; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java index 58c98f5..c7588a6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java index eae721f..8df4d80 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java index 75fdcf1..73eb62a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java index 1e9fa52..561c010 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/CRTable.java @@ -322,11 +322,16 @@ public void visitSwitchExpression(JCSwitchExpression tree) { public void visitCase(JCCase tree) { SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); - sr.mergeWith(csp(tree.pats)); + sr.mergeWith(csp(tree.labels)); sr.mergeWith(csp(tree.stats)); result = sr; } + @Override + public void visitDefaultCaseLabel(JCTree.JCDefaultCaseLabel that) { + result = null; + } + public void visitSynchronized(JCSynchronized tree) { SourceRange sr = new SourceRange(startPos(tree), endPos(tree)); sr.mergeWith(csp(tree.lock)); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java index 9cf48da..ced8f84 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java @@ -64,45 +64,45 @@ * deletion without notice. */ public class ClassFile { - public final static int JAVA_MAGIC = 0xCAFEBABE; + public static final int JAVA_MAGIC = 0xCAFEBABE; // see Target - public final static int CONSTANT_Utf8 = 1; - public final static int CONSTANT_Unicode = 2; - public final static int CONSTANT_Integer = 3; - public final static int CONSTANT_Float = 4; - public final static int CONSTANT_Long = 5; - public final static int CONSTANT_Double = 6; - public final static int CONSTANT_Class = 7; - public final static int CONSTANT_String = 8; - public final static int CONSTANT_Fieldref = 9; - public final static int CONSTANT_Methodref = 10; - public final static int CONSTANT_InterfaceMethodref = 11; - public final static int CONSTANT_NameandType = 12; - public final static int CONSTANT_MethodHandle = 15; - public final static int CONSTANT_MethodType = 16; - public final static int CONSTANT_Dynamic = 17; - public final static int CONSTANT_InvokeDynamic = 18; - public final static int CONSTANT_Module = 19; - public final static int CONSTANT_Package = 20; - - public final static int REF_getField = 1; - public final static int REF_getStatic = 2; - public final static int REF_putField = 3; - public final static int REF_putStatic = 4; - public final static int REF_invokeVirtual = 5; - public final static int REF_invokeStatic = 6; - public final static int REF_invokeSpecial = 7; - public final static int REF_newInvokeSpecial = 8; - public final static int REF_invokeInterface = 9; - - public final static int MAX_PARAMETERS = 0xff; - public final static int MAX_DIMENSIONS = 0xff; - public final static int MAX_CODE = 0xffff; - public final static int MAX_LOCALS = 0xffff; - public final static int MAX_STACK = 0xffff; - - public final static int PREVIEW_MINOR_VERSION = 0xffff; + public static final int CONSTANT_Utf8 = 1; + public static final int CONSTANT_Unicode = 2; + public static final int CONSTANT_Integer = 3; + public static final int CONSTANT_Float = 4; + public static final int CONSTANT_Long = 5; + public static final int CONSTANT_Double = 6; + public static final int CONSTANT_Class = 7; + public static final int CONSTANT_String = 8; + public static final int CONSTANT_Fieldref = 9; + public static final int CONSTANT_Methodref = 10; + public static final int CONSTANT_InterfaceMethodref = 11; + public static final int CONSTANT_NameandType = 12; + public static final int CONSTANT_MethodHandle = 15; + public static final int CONSTANT_MethodType = 16; + public static final int CONSTANT_Dynamic = 17; + public static final int CONSTANT_InvokeDynamic = 18; + public static final int CONSTANT_Module = 19; + public static final int CONSTANT_Package = 20; + + public static final int REF_getField = 1; + public static final int REF_getStatic = 2; + public static final int REF_putField = 3; + public static final int REF_putStatic = 4; + public static final int REF_invokeVirtual = 5; + public static final int REF_invokeStatic = 6; + public static final int REF_invokeSpecial = 7; + public static final int REF_newInvokeSpecial = 8; + public static final int REF_invokeInterface = 9; + + public static final int MAX_PARAMETERS = 0xff; + public static final int MAX_DIMENSIONS = 0xff; + public static final int MAX_CODE = 0xffff; + public static final int MAX_LOCALS = 0xffff; + public static final int MAX_STACK = 0xffff; + + public static final int PREVIEW_MINOR_VERSION = 0xffff; public enum Version { V45_3(45, 3), // base level for all attributes @@ -117,7 +117,8 @@ public enum Version { V57(57, 0), // JDK 13 V58(58, 0), // JDK 14 V59(59, 0), // JDK 15 - V60(60, 0); // JDK 16 + V60(60, 0), // JDK 16 + V61(61, 0); // JDK 17 Version(int major, int minor) { this.major = major; this.minor = minor; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 8da145b..22bb3db 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -196,6 +196,11 @@ public class ClassReader { */ int[] parameterNameIndices; + /** + * A table to hold the access flags of the method parameters. + */ + int[] parameterAccessFlags; + /** * A table to hold annotations for method parameters. */ @@ -276,8 +281,7 @@ protected ClassReader(Context context) { preview = Preview.instance(context); allowModules = Feature.MODULES.allowedInSource(source); allowRecords = Feature.RECORDS.allowedInSource(source); - allowSealedTypes = (!preview.isPreview(Feature.SEALED_CLASSES) || preview.isEnabled()) && - Feature.SEALED_CLASSES.allowedInSource(source); + allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source); saveParameterNames = options.isSet(PARAMETERS); @@ -570,9 +574,13 @@ Type classSigToType() { public Type getEnclosingType() { if (!completed) { completed = true; + try { - tsym.complete(); + tsym.apiComplete(); } catch (CompletionFailure cf) {} + + + Type enclosingType = tsym.type.getEnclosingType(); if (enclosingType != Type.noType) { List typeArgs = @@ -1066,6 +1074,7 @@ protected void read(Symbol sym, int attrlen) { sawMethodParameters = true; int numEntries = nextByte(); parameterNameIndices = new int[numEntries]; + parameterAccessFlags = new int[numEntries]; haveParameterNameIndices = true; int index = 0; for (int i = 0; i < numEntries; i++) { @@ -1074,7 +1083,9 @@ protected void read(Symbol sym, int attrlen) { if ((flags & (Flags.MANDATED | Flags.SYNTHETIC)) != 0) { continue; } - parameterNameIndices[index++] = nameIndex; + parameterNameIndices[index] = nameIndex; + parameterAccessFlags[index] = flags; + index++; } } bp = newbp; @@ -1454,7 +1465,10 @@ else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) { } } else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) { sym.flags_field |= PREVIEW_API; - setFlagIfAttributeTrue(proxy, sym, names.essentialAPI, PREVIEW_ESSENTIAL_API); + setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE); + } else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) { + Assert.check(sym.kind == TYP); + sym.flags_field |= VALUE_BASED; } else { if (proxy.type.tsym == syms.annotationTargetType.tsym) { target = proxy; @@ -1465,7 +1479,9 @@ else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) { setFlagIfAttributeTrue(proxy, sym, names.forRemoval, DEPRECATED_REMOVAL); } else if (proxy.type.tsym == syms.previewFeatureType.tsym) { sym.flags_field |= PREVIEW_API; - setFlagIfAttributeTrue(proxy, sym, names.essentialAPI, PREVIEW_ESSENTIAL_API); + setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE); + } else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) { + sym.flags_field |= VALUE_BASED; } proxies.append(proxy); } @@ -1475,7 +1491,7 @@ else if (proxy.type.tsym.flatName() == syms.profileType.tsym.flatName()) { //where: private void setFlagIfAttributeTrue(CompoundAnnotationProxy proxy, Symbol sym, Name attribute, long flag) { for (Pair v : proxy.values) { - if (v.fst == attribute && v.snd instanceof Attribute.Constant) { + if (v.fst == attribute && v.snd instanceof Attribute.Constant) { Attribute.Constant c = (Attribute.Constant)v.snd; if (c.type == syms.booleanType && ((Integer)c.value) != 0) { sym.flags_field |= flag; @@ -1530,9 +1546,6 @@ void attachAnnotationDefault(final Symbol sym) { } Type readTypeOrClassSymbol(int i) { - // support preliminary jsr175-format class files - if (poolReader.hasTag(i, CONSTANT_Class)) - return poolReader.getClass(i).type; return readTypeToProxy(i); } Type readTypeToProxy(int i) { @@ -2145,7 +2158,7 @@ public void run() { if (attr.type.tsym == syms.deprecatedType.tsym) { sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION); Attribute forRemoval = attr.member(names.forRemoval); - if (forRemoval instanceof Attribute.Constant) { + if (forRemoval instanceof Attribute.Constant) { Attribute.Constant c = (Attribute.Constant) forRemoval; if (c.type == syms.booleanType && ((Integer) c.value) != 0) { sym.flags_field |= DEPRECATED_REMOVAL; @@ -2400,6 +2413,7 @@ void setParameters(MethodSymbol sym, Type jvmType) { sym.params = params.toList(); parameterAnnotations = null; parameterNameIndices = null; + parameterAccessFlags = null; } @@ -2409,6 +2423,10 @@ void setParameters(MethodSymbol sym, Type jvmType) { private VarSymbol parameter(int index, Type t, MethodSymbol owner, Set exclude) { long flags = PARAMETER; Name argName; + if (parameterAccessFlags != null && index < parameterAccessFlags.length + && parameterAccessFlags[index] != 0) { + flags |= parameterAccessFlags[index]; + } if (parameterNameIndices != null && index < parameterNameIndices.length && parameterNameIndices[index] != 0) { argName = optPoolEntry(parameterNameIndices[index], poolReader::getName, names.empty); @@ -2559,10 +2577,23 @@ void readClass(ClassSymbol c) { for (int i = 0; i < fieldCount; i++) enterMember(c, readField()); Assert.check(methodCount == nextChar()); for (int i = 0; i < methodCount; i++) enterMember(c, readMethod()); - + if (c.isRecord()) { + for (RecordComponent rc: c.getRecordComponents()) { + rc.accessor = lookupMethod(c, rc.name, List.nil()); + } + } typevars = typevars.leave(); } + private MethodSymbol lookupMethod(TypeSymbol tsym, Name name, List argtypes) { + for (Symbol s : tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) { + if (types.isSameTypes(s.type.getParameterTypes(), argtypes)) { + return (MethodSymbol) s; + } + } + return null; + } + /** Read inner class info. For each inner/outer pair allocate a * member class. */ @@ -2830,8 +2861,7 @@ public Modifier getAccessLevel() { public boolean equals(Object other) { if (this == other) return true; - - if (!(other instanceof SourceFileObject)) + if (!(other instanceof SourceFileObject)) return false; SourceFileObject o = (SourceFileObject) other; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index d774866..424455f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -40,6 +40,7 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.RetentionPolicy; import com.sun.tools.javac.code.Directive.*; +import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Types.SignatureGenerator.InvalidSignatureException; @@ -234,7 +235,7 @@ public static String flagNames(long flags) { return sbuf.toString(); } //where - private final static String[] flagName = { + private static final String[] flagName = { "PUBLIC", "PRIVATE", "PROTECTED", "STATIC", "FINAL", "SUPER", "VOLATILE", "TRANSIENT", "NATIVE", "INTERFACE", "ABSTRACT", "STRICTFP"}; @@ -1682,7 +1683,7 @@ public void writeClassFile(OutputStream out, ClassSymbol c) acount += writeExtraAttributes(c); poolbuf.appendInt(JAVA_MAGIC); - if (preview.isEnabled()) { + if (preview.isEnabled() && preview.usesPreview(c.sourcefile)) { poolbuf.appendChar(ClassFile.PREVIEW_MINOR_VERSION); } else { poolbuf.appendChar(target.minorVersion); @@ -1747,6 +1748,10 @@ protected int writeExtraAttributes(Symbol sym) { int adjustFlags(final long flags) { int result = (int)flags; + // Elide strictfp bit in class files + if (target.obsoleteAccStrict()) + result &= ~STRICTFP; + if ((flags & BRIDGE) != 0) result |= ACC_BRIDGE; if ((flags & VARARGS) != 0) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java index cf7d2d8..7d1f0ea 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java @@ -2246,7 +2246,7 @@ public static String mnem(int opcode) { } private static class Mneumonics { - private final static String[] mnem = new String[ByteCodeCount]; + private static final String[] mnem = new String[ByteCodeCount]; static { mnem[nop] = "nop"; mnem[aconst_null] = "aconst_null"; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java index 8d55a5d..5a43351 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -25,6 +25,9 @@ package com.sun.tools.javac.jvm; +import java.util.HashMap; +import java.util.Map; + import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant; import com.sun.tools.javac.tree.TreeInfo.PosKind; import com.sun.tools.javac.util.*; @@ -127,6 +130,7 @@ protected Gen(Context context) { // ignore cldc because we cannot have both stackmap formats this.stackMap = StackMapFormat.JSR202; annotate = Annotate.instance(context); + qualifiedSymbolCache = new HashMap<>(); } /** Switches @@ -168,6 +172,12 @@ protected Gen(Context context) { List stackBeforeSwitchExpression; LocalItem switchResult; + /** Cache the symbol to reflect the qualifying type. + * key: corresponding type + * value: qualified symbol + */ + Map qualifiedSymbolCache; + /** Generate code to load an integer constant. * @param n The integer to be loaded. */ @@ -230,8 +240,11 @@ Symbol binaryQualifier(Symbol sym, Type site) { sym.owner != syms.arrayClass) return sym; // array clone can be qualified by the array type in later targets - Symbol qualifier = new ClassSymbol(Flags.PUBLIC, site.tsym.name, - site, syms.noSymbol); + Symbol qualifier; + if ((qualifier = qualifiedSymbolCache.get(site)) == null) { + qualifier = new ClassSymbol(Flags.PUBLIC, site.tsym.name, site, syms.noSymbol); + qualifiedSymbolCache.put(site, qualifier); + } return sym.clone(qualifier); } @@ -1181,7 +1194,7 @@ public void visitLabelled(JCLabeledStatement tree) { } public void visitSwitch(JCSwitch tree) { - handleSwitch(tree, tree.selector, tree.cases); + handleSwitch(tree, tree.selector, tree.cases, tree.patternSwitch); } @Override @@ -1226,7 +1239,7 @@ private void doHandleSwitchExpression(JCSwitchExpression tree) { } int prevLetExprStart = code.setLetExprStackPos(code.state.stacksize); try { - handleSwitch(tree, tree.selector, tree.cases); + handleSwitch(tree, tree.selector, tree.cases, tree.patternSwitch); } finally { code.setLetExprStackPos(prevLetExprStart); } @@ -1256,9 +1269,11 @@ public void visitLambda(JCLambda tree) { return hasTry[0]; } - private void handleSwitch(JCTree swtch, JCExpression selector, List cases) { + private void handleSwitch(JCTree swtch, JCExpression selector, List cases, + boolean patternSwitch) { int limit = code.nextreg; Assert.check(!selector.type.hasTag(CLASS)); + int switchStart = patternSwitch ? code.entryPoint() : -1; int startpcCrt = genCrt ? code.curCP() : 0; Assert.check(code.isStatementStart()); Item sel = genExpr(selector, syms.intType); @@ -1288,9 +1303,9 @@ private void handleSwitch(JCTree swtch, JCExpression selector, List case List l = cases; for (int i = 0; i < labels.length; i++) { - if (l.head.pats.nonEmpty()) { - Assert.check(l.head.pats.size() == 1); - int val = ((Number)l.head.pats.head.type.constValue()).intValue(); + if (l.head.labels.head.isExpression()) { + Assert.check(l.head.labels.size() == 1); + int val = ((Number)((JCExpression) l.head.labels.head).type.constValue()).intValue(); labels[i] = val; if (val < lo) lo = val; if (hi < val) hi = val; @@ -1362,6 +1377,11 @@ private void handleSwitch(JCTree swtch, JCExpression selector, List case genStats(c.stats, switchEnv, CRT_FLOW_TARGET); } + if (switchEnv.info.cont != null) { + Assert.check(patternSwitch); + code.resolve(switchEnv.info.cont, switchStart); + } + // Resolve all breaks. Chain exit = switchEnv.info.exit; if (exit != null) { @@ -2421,6 +2441,7 @@ public boolean genClass(Env env, JCClassDecl cdef) { toplevel = null; endPosTable = null; nerrs = 0; + qualifiedSymbolCache.clear(); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java index 8191edf..5ea327e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/JNIWriter.java @@ -137,7 +137,7 @@ static boolean isFinal(Symbol s) { static boolean isNative(Symbol s) { return hasFlag(s, Flags.NATIVE); } - static private boolean hasFlag(Symbol m, int flag) { + private static boolean hasFlag(Symbol m, int flag) { return (m.flags() & flag) != 0; } @@ -417,7 +417,7 @@ String encodeMethod(Symbol msym, ClassSymbol clazz, result.append(encode(msym.getSimpleName(), EncoderType.JNI)); if (isOverloaded) { TypeSignature typeSig = new TypeSignature(types); - StringBuilder sig = typeSig.getParameterSignature(msym.type); + StringBuilder sig = typeSig.getParameterSignature(msym.type, true); result.append("__").append(encode(sig, EncoderType.JNI)); } return result.toString(); @@ -542,23 +542,23 @@ public TypeSignature(Types types) { this.types = types; } - StringBuilder getParameterSignature(Type mType) + StringBuilder getParameterSignature(Type mType, boolean useFlatname) throws SignatureException { StringBuilder result = new StringBuilder(); for (Type pType : mType.getParameterTypes()) { - result.append(getJvmSignature(pType)); + result.append(getJvmSignature(pType, useFlatname)); } return result; } StringBuilder getReturnSignature(Type mType) throws SignatureException { - return getJvmSignature(mType.getReturnType()); + return getJvmSignature(mType.getReturnType(), false); } StringBuilder getSignature(Type mType) throws SignatureException { StringBuilder sb = new StringBuilder(); - sb.append("(").append(getParameterSignature(mType)).append(")"); + sb.append("(").append(getParameterSignature(mType, false)).append(")"); sb.append(getReturnSignature(mType)); return sb; } @@ -567,6 +567,12 @@ StringBuilder getSignature(Type mType) throws SignatureException { * Returns jvm internal signature. */ static class JvmTypeVisitor extends JNIWriter.SimpleTypeVisitor { + private final boolean useFlatname; + + JvmTypeVisitor(boolean useFlatname) { + super(); + this.useFlatname = useFlatname; + } @Override public Type visitClassType(Type.ClassType t, StringBuilder s) { @@ -589,7 +595,8 @@ public Type visitType(Type t, StringBuilder s) { return t.accept(this, s); } private void setDeclaredType(Type t, StringBuilder s) { - String classname = t.tsym.getQualifiedName().toString(); + String classname = useFlatname ? t.tsym.flatName().toString() + : t.tsym.getQualifiedName().toString(); classname = classname.replace('.', '/'); s.append("L").append(classname).append(";"); } @@ -611,10 +618,10 @@ private String getJvmPrimitiveSignature(Type t) { } } - StringBuilder getJvmSignature(Type type) { + StringBuilder getJvmSignature(Type type, boolean useFlatname) { Type t = types.erasure(type); StringBuilder sig = new StringBuilder(); - JvmTypeVisitor jv = new JvmTypeVisitor(); + JvmTypeVisitor jv = new JvmTypeVisitor(useFlatname); jv.visitType(t, sig); return sig; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java index 337150f..6575fa0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java index 9e81788..18de4d6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/PoolWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java index d98408e..f280809 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -82,7 +82,10 @@ public enum Target { JDK1_15("15", 59, 0), /** JDK 16. */ - JDK1_16("16", 60, 0); + JDK1_16("16", 60, 0), + + /** JDK 17. */ + JDK1_17("17", 61, 0); private static final Context.Key targetKey = new Context.Key<>(); @@ -191,4 +194,10 @@ public boolean hasVirtualPrivateInvoke() { public boolean hasSealedClasses() { return compareTo(JDK1_15) >= 0; } + + /** Is the ACC_STRICT bit redundant and obsolete + */ + public boolean obsoleteAccStrict() { + return compareTo(JDK1_17) >= 0; + } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/Main.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/Main.java index 9d81927..05b5527 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/Main.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/launcher/Main.java @@ -135,7 +135,7 @@ public static void main(String... args) throws Throwable { System.exit(1); } catch (InvocationTargetException e) { // leave VM to handle the stacktrace, in the standard manner - throw e.getTargetException(); + throw e.getCause(); } } @@ -342,12 +342,16 @@ private List getJavacOpts(String... runtimeArgs) throws Fault { } break; default: + if (opt.startsWith("-agentlib:jdwp=") || opt.startsWith("-Xrunjdwp:")) { + javacOpts.add("-g"); + } // ignore all other runtime args } } // add implicit options javacOpts.add("-proc:none"); + javacOpts.add("-Xdiags:verbose"); return javacOpts; } @@ -422,7 +426,7 @@ private void execute(String mainClassName, String[] appArgs, Context context) } catch (InvocationTargetException e) { // remove stack frames for source launcher int invocationFrames = e.getStackTrace().length; - Throwable target = e.getTargetException(); + Throwable target = e.getCause(); StackTraceElement[] targetTrace = target.getStackTrace(); target.setStackTrace(Arrays.copyOfRange(targetTrace, 0, targetTrace.length - invocationFrames)); throw e; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java index 009ceb1..209d9ba 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -447,6 +447,7 @@ public boolean validate() { } } + if (!checkDirectory(Option.D)) { return false; } @@ -546,7 +547,7 @@ public boolean validate() { boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) { - if (fm instanceof BaseFileManager) { + if (fm instanceof BaseFileManager) { if (source.compareTo(Source.JDK8) <= 0) { if (((BaseFileManager) fm).isDefaultBootClassPath()) log.warning(LintCategory.OPTIONS, Warnings.SourceNoBootclasspath(source.name)); @@ -834,11 +835,6 @@ public List getDocLintOpts() { doclintOpts.add(DocLint.XCHECK_PACKAGE + checkPackages); } - String format = options.get(Option.DOCLINT_FORMAT); - if (format != null) { - doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + format); - } - return List.from(doclintOpts.toArray(new String[doclintOpts.size()])); } @@ -900,7 +896,7 @@ void error(Option.InvalidValueException f) { private void report(DiagnosticInfo diag) { // Would be good to have support for -XDrawDiagnostics here - if (diag instanceof JCDiagnostic.Error) { + if (diag instanceof JCDiagnostic.Error) { log.error((JCDiagnostic.Error)diag); } else if (diag instanceof JCDiagnostic.Warning){ log.warning((JCDiagnostic.Warning)diag); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java index c79f274..3c273b8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/DelegatingJavaFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 49f61dd..a63781e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -162,17 +162,6 @@ private static String version(String key) { * it does not depend on any unrelated errors that might have occurred. */ protected static enum CompilePolicy { - /** - * Just attribute the parse trees. - */ - ATTR_ONLY, - - /** - * Just attribute and do flow analysis on the parse trees. - * This should catch most user errors. - */ - CHECK_ONLY, - /** * Attribute everything, then do flow analysis for everything, * then desugar everything, and only then generate output. @@ -200,10 +189,6 @@ protected static enum CompilePolicy { static CompilePolicy decode(String option) { if (option == null) return DEFAULT_COMPILE_POLICY; - else if (option.equals("attr")) - return ATTR_ONLY; - else if (option.equals("check")) - return CHECK_ONLY; else if (option.equals("simple")) return SIMPLE; else if (option.equals("byfile")) @@ -459,11 +444,7 @@ public JavaCompiler(Context context) { verboseCompilePolicy = options.isSet("verboseCompilePolicy"); - if (options.isSet("should-stop.at") && - CompileState.valueOf(options.get("should-stop.at")) == CompileState.ATTR) - compilePolicy = CompilePolicy.ATTR_ONLY; - else - compilePolicy = CompilePolicy.decode(options.get("compilePolicy")); + compilePolicy = CompilePolicy.decode(options.get("compilePolicy")); implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit")); @@ -1024,14 +1005,6 @@ public void compile(Collection sourceFileObjects, if (!CompileState.ATTR.isAfter(shouldStopPolicyIfNoError)) { switch (compilePolicy) { - case ATTR_ONLY: - attribute(todo); - break; - - case CHECK_ONLY: - flow(attribute(todo)); - break; - case SIMPLE: generate(desugar(flow(attribute(todo)))); break; @@ -1938,18 +1911,22 @@ public void close() { names.dispose(); names = null; + FatalError fatalError = null; for (Closeable c: closeables) { try { c.close(); } catch (IOException e) { - // When javac uses JDK 7 as a baseline, this code would be - // better written to set any/all exceptions from all the - // Closeables as suppressed exceptions on the FatalError - // that is thrown. - JCDiagnostic msg = diagFactory.fragment(Fragments.FatalErrCantClose); - throw new FatalError(msg, e); + if (fatalError == null) { + JCDiagnostic msg = diagFactory.fragment(Fragments.FatalErrCantClose); + fatalError = new FatalError(msg, e); + } else { + fatalError.addSuppressed(e); + } } } + if (fatalError != null) { + throw fatalError; + } closeables = List.nil(); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java index d437678..461e689 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java index e37f04b..65d4314 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2021, 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 @@ -100,29 +100,7 @@ public void process(OptionHelper helper, String option) { XLINT("-Xlint", "opt.Xlint", EXTENDED, BASIC), - XLINT_CUSTOM("-Xlint:", "opt.arg.Xlint", "opt.Xlint.custom", EXTENDED, BASIC, ANYOF, getXLintChoices()) { - private final String LINT_KEY_FORMAT = LARGE_INDENT + " %-" + - (DEFAULT_SYNOPSIS_WIDTH + SMALL_INDENT.length() - LARGE_INDENT.length() - 2) + "s %s"; - @Override - protected void help(Log log) { - super.help(log); - log.printRawLines(WriterKind.STDOUT, - String.format(LINT_KEY_FORMAT, - "all", - log.localize(PrefixKind.JAVAC, "opt.Xlint.all"))); - for (LintCategory lc : LintCategory.values()) { - log.printRawLines(WriterKind.STDOUT, - String.format(LINT_KEY_FORMAT, - lc.option, - log.localize(PrefixKind.JAVAC, - "opt.Xlint.desc." + lc.option))); - } - log.printRawLines(WriterKind.STDOUT, - String.format(LINT_KEY_FORMAT, - "none", - log.localize(PrefixKind.JAVAC, "opt.Xlint.none"))); - } - }, + XLINT_CUSTOM("-Xlint:", "opt.arg.Xlint", "opt.Xlint.custom", EXTENDED, BASIC, ANYOF, getXLintChoices()), XDOCLINT("-Xdoclint", "opt.Xdoclint", EXTENDED, BASIC), @@ -160,8 +138,6 @@ public void process(OptionHelper helper, String option, String arg) { } }, - DOCLINT_FORMAT("--doclint-format", "opt.doclint.format", EXTENDED, BASIC, ONEOF, "html5"), - // -nowarn is retained for command-line backward compatibility NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) { @Override @@ -502,6 +478,32 @@ public void process(OptionHelper helper, String option) throws InvalidValueExcep } }, + HELP_LINT("--help-lint", "opt.help.lint", EXTENDED, INFO) { + private final String LINT_KEY_FORMAT = SMALL_INDENT + SMALL_INDENT + "%-" + + (DEFAULT_SYNOPSIS_WIDTH - LARGE_INDENT.length()) + "s %s"; + @Override + public void process(OptionHelper helper, String option) throws InvalidValueException { + Log log = helper.getLog(); + log.printRawLines(WriterKind.STDOUT, log.localize(PrefixKind.JAVAC, "opt.help.lint.header")); + log.printRawLines(WriterKind.STDOUT, + String.format(LINT_KEY_FORMAT, + "all", + log.localize(PrefixKind.JAVAC, "opt.Xlint.all"))); + for (LintCategory lc : LintCategory.values()) { + log.printRawLines(WriterKind.STDOUT, + String.format(LINT_KEY_FORMAT, + lc.option, + log.localize(PrefixKind.JAVAC, + "opt.Xlint.desc." + lc.option))); + } + log.printRawLines(WriterKind.STDOUT, + String.format(LINT_KEY_FORMAT, + "none", + log.localize(PrefixKind.JAVAC, "opt.Xlint.none"))); + super.process(helper, option); + } + }, + // This option exists only for the purpose of documenting itself. // It's actually implemented by the launcher. J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, ArgKind.ADJACENT) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java index 9e82337..39fbc37 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/FilteredMemberList.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/FilteredMemberList.java index 87047be..ae137b8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/FilteredMemberList.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/FilteredMemberList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -30,7 +30,6 @@ import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol; -import com.sun.tools.javac.util.Filter; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java index ffc57b7..8bc943e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -819,6 +819,12 @@ public boolean isFunctionalInterface(TypeElement element) { } } + @Override @DefinedBy(Api.LANGUAGE_MODEL) + public boolean isAutomaticModule(ModuleElement module) { + ModuleSymbol msym = (ModuleSymbol) module; + return (msym.flags() & Flags.AUTOMATIC_MODULE) != 0; + } + /** * Returns the tree node and compilation unit corresponding to this * element, or null if they can't be found. diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java index 8ca2c2e..3dfad6c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java index 22c75b9..11601ba 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java @@ -519,10 +519,13 @@ protected DCReference reference(boolean allowMember) throws ParseException { nextChar(); } - if (depth != 0) { + + // depth < 0 will be caught and reported by ReferenceParser#parse + if (depth > 0) { handleError("dc.unterminated.signature", pos); } + String sig = newString(pos, bp); // Break sig apart into qualifiedExpr member paramTypes. @@ -732,21 +735,9 @@ protected DCText inlineWord() { * Read general text content of an inline tag, including HTML entities and elements. * Matching pairs of { } are skipped; the text is terminated by the first * unmatched }. It is an error if the beginning of the next tag is detected. - * Nested tags are not permitted. - */ - private List inlineContent() { - return inlineContent(false); - } - - /** - * Read general text content of an inline tag, including HTML entities and elements. - * Matching pairs of { } are skipped; the text is terminated by the first - * unmatched }. It is an error if the beginning of the next tag is detected. - * - * @param allowNestedTags whether or not to allow nested tags */ @SuppressWarnings("fallthrough") - private List inlineContent(boolean allowNestedTags) { + private List inlineContent() { ListBuffer trees = new ListBuffer<>(); skipWhitespace(); @@ -790,9 +781,8 @@ private List inlineContent(boolean allowNestedTags) { } nextChar(); + if (ch == '@') { - - if (ch == '@' && allowNestedTags) { addPendingText(trees, bp - 2); trees.add(inlineTag()); textStart = bp; @@ -1521,7 +1511,7 @@ public DCTree parse(int pos, Kind kind) { description = blockContent(); break; case INLINE: - description = inlineContent(true); + description = inlineContent(); break; default: throw new IllegalArgumentException(kind.toString()); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java index 8e2c9ff..e9d6d98 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java @@ -214,8 +214,12 @@ protected void lexError(int pos, JCDiagnostic.Error key) { * @param key error key to report. */ protected void lexError(DiagnosticFlag flags, int pos, JCDiagnostic.Error key) { + log.error(flags, seek + pos, key); - tk = TokenKind.ERROR; + if (flags != DiagnosticFlag.SOURCE_LEVEL) { + tk = TokenKind.ERROR; + } + errPos = pos; } @@ -790,6 +794,13 @@ private void scanNumber(int pos, int radix) { break; } } + // If it is not a floating point literal, + // the octal number should be rescanned correctly. + if (radix == 8) { + sb.setLength(0); + reset(pos); + scanDigits(pos, 8); + } if (acceptOneOf('l', 'L')) { tk = TokenKind.LONGLITERAL; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index 5d2396c..5f2363d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -27,6 +27,7 @@ import java.util.*; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import com.sun.source.tree.CaseTree; @@ -60,12 +61,14 @@ import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed; import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed; import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed; - -/** The parser maps a token sequence into an abstract syntax - * tree. It operates by recursive descent, with code derived - * systematically from an LL(1) grammar. For efficiency reasons, an - * operator precedence scheme is used for parsing binary operation - * expressions. +import java.util.function.BiFunction; + +/** + * The parser maps a token sequence into an abstract syntax tree. + * The parser is a hand-written recursive-descent parser that + * implements the grammar described in the Java Language Specification. + * For efficiency reasons, an operator precedence scheme is used + * for parsing binary operation expressions. * *

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. @@ -181,15 +184,15 @@ protected JavacParser(ParserFactory fac, this.keepLineMap = keepLineMap; this.errorTree = F.Erroneous(); endPosTable = newEndPosTable(keepEndPositions); - this.allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) && - Feature.SWITCH_EXPRESSION.allowedInSource(source); + + this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source); docComments = newDocCommentTable(keepDocComments, fac, endPosTable); this.allowRecords = Feature.RECORDS.allowedInSource(source); - this.allowSealedTypes = (!preview.isPreview(Feature.SEALED_CLASSES) || preview.isEnabled()) && - Feature.SEALED_CLASSES.allowedInSource(source); + this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source); + } protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) { @@ -277,42 +280,42 @@ public void nextToken() { token = S.token(); } - protected boolean peekToken(Filter tk) { + protected boolean peekToken(Predicate tk) { return peekToken(0, tk); } - protected boolean peekToken(int lookahead, Filter tk) { - return tk.accepts(S.token(lookahead + 1).kind); + protected boolean peekToken(int lookahead, Predicate tk) { + return tk.test(S.token(lookahead + 1).kind); } - protected boolean peekToken(Filter tk1, Filter tk2) { + protected boolean peekToken(Predicate tk1, Predicate tk2) { return peekToken(0, tk1, tk2); } - protected boolean peekToken(int lookahead, Filter tk1, Filter tk2) { - return tk1.accepts(S.token(lookahead + 1).kind) && - tk2.accepts(S.token(lookahead + 2).kind); + protected boolean peekToken(int lookahead, Predicate tk1, Predicate tk2) { + return tk1.test(S.token(lookahead + 1).kind) && + tk2.test(S.token(lookahead + 2).kind); } - protected boolean peekToken(Filter tk1, Filter tk2, Filter tk3) { + protected boolean peekToken(Predicate tk1, Predicate tk2, Predicate tk3) { return peekToken(0, tk1, tk2, tk3); } - protected boolean peekToken(int lookahead, Filter tk1, Filter tk2, Filter tk3) { - return tk1.accepts(S.token(lookahead + 1).kind) && - tk2.accepts(S.token(lookahead + 2).kind) && - tk3.accepts(S.token(lookahead + 3).kind); + protected boolean peekToken(int lookahead, Predicate tk1, Predicate tk2, Predicate tk3) { + return tk1.test(S.token(lookahead + 1).kind) && + tk2.test(S.token(lookahead + 2).kind) && + tk3.test(S.token(lookahead + 3).kind); } @SuppressWarnings("unchecked") - protected boolean peekToken(Filter... kinds) { + protected boolean peekToken(Predicate... kinds) { return peekToken(0, kinds); } @SuppressWarnings("unchecked") - protected boolean peekToken(int lookahead, Filter... kinds) { - for (; lookahead < kinds.length ; lookahead++) { - if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) { + protected boolean peekToken(int lookahead, Predicate... kinds) { + for (Predicate kind : kinds) { + if (!kind.test(S.token(++lookahead).kind)) { return false; } } @@ -767,6 +770,33 @@ public JCExpression parseExpression() { return term(EXPR); } + + /** parses patterns. + */ + + public JCPattern parsePattern(int pos, JCModifiers mods, JCExpression parsedType, boolean inInstanceOf) { + JCPattern pattern; + if (token.kind == LPAREN && parsedType == null) { + int startPos = token.pos; + accept(LPAREN); + JCPattern p = parsePattern(token.pos, null, null, false); + accept(RPAREN); + pattern = toP(F.at(startPos).ParenthesizedPattern(p)); + } else { + mods = mods != null ? mods : optFinal(0); + JCExpression e = parsedType == null ? term(TYPE | NOLAMBDA) : parsedType; + JCVariableDecl var = toP(F.at(token.pos).VarDef(mods, ident(), e, null)); + pattern = toP(F.at(pos).BindingPattern(var)); + } + if (!inInstanceOf && token.kind == AMPAMP) { + checkSourceLevel(Feature.PATTERN_SWITCH); + nextToken(); + JCExpression guard = term(EXPR | NOLAMBDA); + pattern = F.at(pos).GuardPattern(pattern, guard); + } + return pattern; + } + /** * parses (optional) type annotations followed by a type. If the * annotations are present before the type and are not consumed during array @@ -945,31 +975,35 @@ JCExpression term2Rest(JCExpression t, int minprec) { if (token.kind == INSTANCEOF) { int pos = token.pos; nextToken(); - int patternPos = token.pos; - JCModifiers mods = optFinal(0); - int typePos = token.pos; - JCExpression type = unannotatedType(false); JCTree pattern; - if (token.kind == IDENTIFIER) { - checkSourceLevel(token.pos, Feature.PATTERN_MATCHING_IN_INSTANCEOF); - JCVariableDecl var = toP(F.at(token.pos).VarDef(mods, ident(), type, null)); - pattern = toP(F.at(patternPos).BindingPattern(var)); + if (token.kind == LPAREN) { + checkSourceLevel(token.pos, Feature.PATTERN_SWITCH); + pattern = parsePattern(token.pos, null, null, true); } else { - checkNoMods(typePos, mods.flags & ~Flags.DEPRECATED); - if (mods.annotations.nonEmpty()) { - checkSourceLevel(mods.annotations.head.pos, Feature.TYPE_ANNOTATIONS); - List typeAnnos = - mods.annotations - .map(decl -> { - JCAnnotation typeAnno = F.at(decl.pos) - .TypeAnnotation(decl.annotationType, - decl.args); - endPosTable.replaceTree(decl, typeAnno); - return typeAnno; - }); - type = insertAnnotationsToMostInner(type, typeAnnos, false); + int patternPos = token.pos; + JCModifiers mods = optFinal(0); + int typePos = token.pos; + JCExpression type = unannotatedType(false); + if (token.kind == IDENTIFIER) { + checkSourceLevel(token.pos, Feature.PATTERN_MATCHING_IN_INSTANCEOF); + pattern = parsePattern(patternPos, mods, type, true); + } else { + checkNoMods(typePos, mods.flags & ~Flags.DEPRECATED); + if (mods.annotations.nonEmpty()) { + checkSourceLevel(mods.annotations.head.pos, Feature.TYPE_ANNOTATIONS); + List typeAnnos = + mods.annotations + .map(decl -> { + JCAnnotation typeAnno = F.at(decl.pos) + .TypeAnnotation(decl.annotationType, + decl.args); + endPosTable.replaceTree(decl, typeAnno); + return typeAnno; + }); + type = insertAnnotationsToMostInner(type, typeAnnos, false); + } + pattern = type; } - pattern = type; } odStack[top] = F.at(pos).TypeTest(odStack[top], pattern); } else { @@ -1481,14 +1515,16 @@ protected JCExpression term3() { private List switchExpressionStatementGroup() { ListBuffer caseExprs = new ListBuffer<>(); int casePos = token.pos; - ListBuffer pats = new ListBuffer<>(); + ListBuffer pats = new ListBuffer<>(); if (token.kind == DEFAULT) { nextToken(); + pats.append(toP(F.at(casePos).DefaultCaseLabel())); } else { accept(CASE); while (true) { - pats.append(term(EXPR | NOLAMBDA)); + JCCaseLabel label = parseCaseLabel(); + pats.append(label); if (token.kind != COMMA) break; checkSourceLevel(Feature.SWITCH_MULTIPLE_CASE_LABELS); nextToken(); @@ -1762,31 +1798,7 @@ ParensResult analyzeParens() { return ParensResult.EXPLICIT_LAMBDA; case MONKEYS_AT: type = true; - lookahead += 1; //skip '@' - while (peekToken(lookahead, DOT)) { - lookahead += 2; - } - if (peekToken(lookahead, LPAREN)) { - lookahead++; - //skip annotation values - int nesting = 0; - for (; ; lookahead++) { - TokenKind tk2 = S.token(lookahead).kind; - switch (tk2) { - case EOF: - return ParensResult.PARENS; - case LPAREN: - nesting++; - break; - case RPAREN: - nesting--; - if (nesting == 0) { - continue outer; - } - break; - } - } - } + lookahead = skipAnnotation(lookahead); break; case LBRACKET: if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { @@ -1843,8 +1855,37 @@ ParensResult analyzeParens() { } } + private int skipAnnotation(int lookahead) { + lookahead += 1; //skip '@' + while (peekToken(lookahead, DOT)) { + lookahead += 2; + } + if (peekToken(lookahead, LPAREN)) { + lookahead++; + //skip annotation values + int nesting = 0; + for (; ; lookahead++) { + TokenKind tk2 = S.token(lookahead).kind; + switch (tk2) { + case EOF: + return lookahead; + case LPAREN: + nesting++; + break; + case RPAREN: + nesting--; + if (nesting == 0) { + return lookahead; + } + break; + } + } + } + return lookahead; + } + /** Accepts all identifier-like tokens */ - protected Filter LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; + protected Predicate LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; enum ParensResult { CAST, @@ -1901,7 +1942,7 @@ enum LambdaParameterKind { } } - private final static Fragment[][] decisionTable = new Fragment[][] { + private static final Fragment[][] decisionTable = new Fragment[][] { /* VAR EXPLICIT IMPLICIT */ /* VAR */ {null, VarAndExplicitNotAllowed, VarAndImplicitNotAllowed}, /* EXPLICIT */ {VarAndExplicitNotAllowed, null, ImplicitAndExplicitNotAllowed}, @@ -2146,7 +2187,7 @@ JCExpression typeArgument() { nextToken(); JCExpression bound = parseType(); result = F.at(pos).Wildcard(t, bound); - } else if (LAX_IDENTIFIER.accepts(token.kind)) { + } else if (LAX_IDENTIFIER.test(token.kind)) { //error recovery TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); JCExpression wc = toP(F.at(pos).Wildcard(t, null)); @@ -2232,7 +2273,7 @@ JCExpression bracketsSuffix(JCExpression t) { if (token.pos == endPosTable.errorEndPos) { // error recovery Name name; - if (LAX_IDENTIFIER.accepts(token.kind)) { + if (LAX_IDENTIFIER.test(token.kind)) { name = token.name(); nextToken(); } else { @@ -2439,16 +2480,12 @@ JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { List maybeDimAnnos = typeAnnotationsOpt(); int pos = token.pos; nextToken(); - if (token.kind == RBRACKET) { + if (token.kind == RBRACKET) { // no dimension elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); } else { - if (token.kind == RBRACKET) { // no dimension - elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); - } else { - dimAnnotations.append(maybeDimAnnos); - dims.append(parseExpression()); - accept(RBRACKET); - } + dimAnnotations.append(maybeDimAnnos); + dims.append(parseExpression()); + accept(RBRACKET); } } @@ -2683,6 +2720,9 @@ List blockStatement() { case PLUSPLUS: case SUBSUB: isYieldStatement = S.token(2).kind != SEMI; break; + case BANG: case TILDE: + isYieldStatement = S.token(1).kind != SEMI; + break; case LPAREN: int lookahead = 2; int balance = 1; @@ -2739,7 +2779,7 @@ List blockStatement() { nextToken(); JCStatement stat = parseStatementAsBlock(); return List.of(F.at(pos).Labelled(prevToken.name(), stat)); - } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { + } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) { pos = token.pos; JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); F.at(pos); @@ -2874,6 +2914,7 @@ public JCStatement parseSimpleStatement() { accept(LBRACE); List cases = switchBlockStatementGroups(); JCSwitch t = to(F.at(pos).Switch(selector, cases)); + t.endpos = token.endPos; accept(RBRACE); return t; } @@ -2899,14 +2940,14 @@ public JCStatement parseSimpleStatement() { } case BREAK: { nextToken(); - Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null; + Name label = LAX_IDENTIFIER.test(token.kind) ? ident() : null; accept(SEMI); JCBreak t = toP(F.at(pos).Break(label)); return t; } case CONTINUE: { nextToken(); - Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null; + Name label = LAX_IDENTIFIER.test(token.kind) ? ident() : null; accept(SEMI); JCContinue t = toP(F.at(pos).Continue(label)); return t; @@ -3014,9 +3055,9 @@ protected List switchBlockStatementGroup() { switch (token.kind) { case CASE: { nextToken(); - ListBuffer pats = new ListBuffer<>(); + ListBuffer pats = new ListBuffer<>(); while (true) { - pats.append(term(EXPR | NOLAMBDA)); + pats.append(parseCaseLabel()); if (token.kind != COMMA) break; nextToken(); checkSourceLevel(Feature.SWITCH_MULTIPLE_CASE_LABELS); @@ -3047,6 +3088,7 @@ protected List switchBlockStatementGroup() { nextToken(); CaseTree.CaseKind caseKind; JCTree body = null; + int patternPos = token.pos; if (token.kind == ARROW) { checkSourceLevel(Feature.SWITCH_RULE); accept(ARROW); @@ -3062,7 +3104,8 @@ protected List switchBlockStatementGroup() { caseKind = JCCase.STATEMENT; stats = blockStatements(); } - c = F.at(pos).Case(caseKind, List.nil(), stats, body); + JCCaseLabel defaultPattern = toP(F.at(patternPos).DefaultCaseLabel()); + c = F.at(pos).Case(caseKind, List.of(defaultPattern), stats, body); if (stats.isEmpty()) storeEnd(c, S.prevToken().endPos); return cases.append(c).toList(); @@ -3071,6 +3114,78 @@ protected List switchBlockStatementGroup() { throw new AssertionError("should not reach here"); } + private JCCaseLabel parseCaseLabel() { + int patternPos = token.pos; + JCCaseLabel label; + + if (token.kind == DEFAULT) { + checkSourceLevel(token.pos, Feature.PATTERN_SWITCH); + nextToken(); + label = toP(F.at(patternPos).DefaultCaseLabel()); + } else { + int lookahead = 0; + while (S.token(lookahead).kind == LPAREN) { + lookahead++; + } + JCModifiers mods = optFinal(0); + boolean pattern = mods.flags != 0 || mods.annotations.nonEmpty() || + analyzePattern(lookahead) == PatternResult.PATTERN; + if (pattern) { + checkSourceLevel(token.pos, Feature.PATTERN_SWITCH); + return parsePattern(patternPos, mods, null, false); + } else { + return term(EXPR | NOLAMBDA); + } + } + + return label; + } + + @SuppressWarnings("fallthrough") + PatternResult analyzePattern(int lookahead) { + int depth = 0; + while (true) { + TokenKind token = S.token(lookahead).kind; + switch (token) { + case BYTE: case SHORT: case INT: case LONG: case FLOAT: + case DOUBLE: case BOOLEAN: case CHAR: case VOID: + case ASSERT: case ENUM: case IDENTIFIER: case UNDERSCORE: + if (depth == 0 && peekToken(lookahead, LAX_IDENTIFIER)) return PatternResult.PATTERN; + break; + case DOT: case QUES: case EXTENDS: case SUPER: case COMMA: break; + case LT: depth++; break; + case GTGTGT: depth--; + case GTGT: depth--; + case GT: + depth--; + if (depth == 0) { + return peekToken(lookahead, LAX_IDENTIFIER) ? PatternResult.PATTERN + : PatternResult.EXPRESSION; + } else if (depth < 0) return PatternResult.EXPRESSION; + break; + case MONKEYS_AT: + lookahead = skipAnnotation(lookahead); + break; + case LBRACKET: + if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { + return PatternResult.PATTERN; + } else if (peekToken(lookahead, RBRACKET)) { + lookahead++; + break; + } else { + return PatternResult.EXPRESSION; + } + default: return PatternResult.EXPRESSION; + } + lookahead++; + } + } + + private enum PatternResult { + EXPRESSION, + PATTERN; + } + /** MoreStatementExpressions = { COMMA StatementExpression } */ > T moreStatementExpressions(int pos, @@ -3098,7 +3213,11 @@ List forInit() { return variableDeclarators(optFinal(0), parseType(true), stats, true).toList(); } else { JCExpression t = term(EXPR | TYPE); - if ((lastmode & TYPE) != 0 && (LAX_IDENTIFIER.accepts(token.kind) || token.kind == COLON)) { + + if ((lastmode & TYPE) != 0 && (LAX_IDENTIFIER.test(token.kind) || token.kind == COLON)) { + + + return variableDeclarators(modifiersOpt(), t, stats, true).toList(); } else if ((lastmode & TYPE) != 0 && token.kind == COLON) { log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop")); @@ -3285,7 +3404,7 @@ List annotationFieldValues() { * | Identifier "=" AnnotationValue */ JCExpression annotationFieldValue() { - if (LAX_IDENTIFIER.accepts(token.kind)) { + if (LAX_IDENTIFIER.test(token.kind)) { selectExprMode(); JCExpression t1 = term1(); if (t1.hasTag(IDENT) && token.kind == EQ) { @@ -3384,10 +3503,14 @@ JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean r */ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, boolean reqInit, Comment dc, boolean localDecl, boolean compound) { + boolean declaredUsingVar = false; JCExpression newType = bracketsOpt(type); if (newType.hasTag(ERRONEOUS)) { newType = type; } + + + JCExpression init = null; if (token.kind == EQ) { nextToken(); @@ -3401,13 +3524,18 @@ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression ty if (elemType.hasTag(IDENT)) { Name typeName = ((JCIdent)elemType).name; if (restrictedTypeNameStartingAtSource(typeName, pos, !compound && localDecl) != null) { - if (newType.hasTag(TYPEARRAY) && !compound) { + + if (typeName != names.var) { + reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedHere(typeName)); + } else if (newType.hasTag(TYPEARRAY) && !compound) { + //error - 'var' and arrays - reportSyntaxError(pos, Errors.RestrictedTypeNotAllowedArray(typeName)); + reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedArray(typeName)); } else { + declaredUsingVar = true; if(compound) //error - 'var' in compound local var decl - reportSyntaxError(pos, Errors.RestrictedTypeNotAllowedCompound(typeName)); + reportSyntaxError(elemType.pos, Errors.RestrictedTypeNotAllowedCompound(typeName)); startPos = TreeInfo.getStartPos(mods); if (startPos == Position.NOPOS) startPos = TreeInfo.getStartPos(newType); @@ -3417,7 +3545,11 @@ JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression ty } } JCVariableDecl result = - toP(F.at(pos).VarDef(mods, name, newType, init)); + + + + toP(F.at(pos).VarDef(mods, name, newType, init, declaredUsingVar)); + attach(result, dc); result.startPos = startPos; return result; @@ -3489,7 +3621,7 @@ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean } else { if (allowThisIdent || !lambdaParameter || - LAX_IDENTIFIER.accepts(token.kind) || + LAX_IDENTIFIER.test(token.kind) || mods.flags != Flags.PARAMETER || mods.annotations.nonEmpty()) { JCExpression pn = qualident(false); @@ -3535,7 +3667,12 @@ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean type = bracketsOpt(type); - return toP(F.at(pos).VarDef(mods, name, type, null)); + + + + return toP(F.at(pos).VarDef(mods, name, type, null, + type != null && type.hasTag(IDENT) && ((JCIdent)type).name == names.var)); + } /** Resources = Resource { ";" Resources } @@ -3567,8 +3704,10 @@ protected JCTree resource() { return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true, false); } JCExpression t = term(EXPR | TYPE); - if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { + + if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) { JCModifiers mods = F.at(Position.NOPOS).Modifiers(Flags.FINAL); + return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true, false); } else { checkSourceLevel(startPos, Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES); @@ -3680,6 +3819,7 @@ public JCTree.JCCompilationUnit parseCompilationUnit() { } } JCTree def = typeDeclaration(mods, docComment); + defs.append(def); if (def instanceof JCClassDecl) { checkForPackage = false; @@ -3945,7 +4085,7 @@ protected JCStatement classOrRecordOrInterfaceOrEnumDeclaration(JCModifiers mods nextToken(); return toP(F.Exec(erroneousTree)); } else { - if (LAX_IDENTIFIER.accepts(token.kind)) { + if (LAX_IDENTIFIER.test(token.kind)) { errs = List.of(mods, toP(F.at(pos).Ident(ident()))); setErrorEndPos(token.pos); } else { @@ -5014,6 +5154,7 @@ private JCExpression insertAnnotationsToMostInner( if (createNewLevel) { mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType)); + origEndPos = getEndPos(mostInnerType); } JCExpression mostInnerTypeToReturn = mostInnerType; @@ -5275,6 +5416,7 @@ protected SimpleEndPosTable(JavacParser parser) { } public void storeEnd(JCTree tree, int endpos) { + if (tree instanceof JCIdent) { JCIdent i = (JCIdent) tree; @@ -5284,8 +5426,10 @@ public void storeEnd(JCTree tree, int endpos) { if (f.pos + (f.name != null ? f.name.length() : 0) + 1 == endpos) return ; } - endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos, - endPosMap.lookup(tree)); + endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos); + + + } protected T to(T t) { @@ -5299,7 +5443,7 @@ protected T toP(T t) { } public int getEndPos(JCTree tree) { - int value = endPosMap.getFromIndex(endPosMap.lookup(tree)); + int value = endPosMap.get(tree); // As long as Position.NOPOS==-1, this just returns value. return (value == -1) ? Position.NOPOS : value; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java index 4331439..a233c09 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java @@ -46,7 +46,7 @@ public class ReferenceParser { * An object to contain the result of parsing a reference to an API element. * Any, but not all, of the member fields may be null. */ - static public class Reference { + public static class Reference { public final JCTree.JCExpression moduleName; /** The type, if any, in the signature. */ public final JCTree qualExpr; @@ -66,7 +66,7 @@ static public class Reference { /** * An exception that indicates an error occurred while parsing a signature. */ - static public class ParseException extends Exception { + public static class ParseException extends Exception { private static final long serialVersionUID = 0; ParseException(String message) { super(message); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ScannerFactory.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ScannerFactory.java index 75b5851..d7b158b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ScannerFactory.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ScannerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java index 9591cea..6de0234 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -25,17 +25,15 @@ package com.sun.tools.javac.parser; +import java.util.HashMap; import java.util.Locale; +import java.util.function.Predicate; +import java.util.Map; import com.sun.tools.javac.api.Formattable; import com.sun.tools.javac.api.Messages; import com.sun.tools.javac.parser.Tokens.Token.Tag; -import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.Name; -import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Filter; -import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Names; +import com.sun.tools.javac.util.*; /** A class that defines codes/utilities for Java source tokens * returned from lexical analysis. @@ -52,15 +50,7 @@ public class Tokens { /** * Keyword array. Maps name indices to Token. */ - private final TokenKind[] key; - - /** The number of the last entered keyword. - */ - private int maxKey = 0; - - /** The names of all tokens. - */ - private Name[] tokenName = new Name[TokenKind.values().length]; + private Map keywords = new HashMap<>(); public static final Context.Key tokensKey = new Context.Key<>(); @@ -75,44 +65,33 @@ protected Tokens(Context context) { context.put(tokensKey, this); names = Names.instance(context); for (TokenKind t : TokenKind.values()) { - if (t.name != null) - enterKeyword(t.name, t); - else - tokenName[t.ordinal()] = null; - } - - key = new TokenKind[maxKey+1]; - for (int i = 0; i <= maxKey; i++) key[i] = TokenKind.IDENTIFIER; - for (TokenKind t : TokenKind.values()) { - if (t.name != null) - key[tokenName[t.ordinal()].getIndex()] = t; + if (t.name != null) { + names.fromString(t.name); + keywords.put(t.name, t); + } } } - private void enterKeyword(String s, TokenKind token) { - Name n = names.fromString(s); - tokenName[token.ordinal()] = n; - if (n.getIndex() > maxKey) maxKey = n.getIndex(); - } - /** * Create a new token given a name; if the name corresponds to a token name, * a new token of the corresponding kind is returned; otherwise, an * identifier token is returned. */ TokenKind lookupKind(Name name) { - return (name.getIndex() > maxKey) ? TokenKind.IDENTIFIER : key[name.getIndex()]; + TokenKind t = keywords.get(name.toString()); + return (t != null) ? t : TokenKind.IDENTIFIER; } TokenKind lookupKind(String name) { - return lookupKind(names.fromString(name)); + TokenKind t = keywords.get(name); + return (t != null) ? t : TokenKind.IDENTIFIER; } /** * This enum defines all tokens used by the javac scanner. A token is * optionally associated with a name. */ - public enum TokenKind implements Formattable, Filter { + public enum TokenKind implements Formattable, Predicate { EOF(), ERROR(Tag.STRING), IDENTIFIER(Tag.NAMED), @@ -285,7 +264,7 @@ public String toString(Locale locale, Messages messages) { } @Override - public boolean accepts(TokenKind that) { + public boolean test(TokenKind that) { return this == that; } } @@ -412,7 +391,7 @@ private List getComments(Comment.CommentStyle style) { } } - final static class NamedToken extends Token { + static final class NamedToken extends Token { /** The name of this token */ public final Name name; @@ -454,7 +433,7 @@ public String stringVal() { } } - final static class NumericToken extends StringToken { + static final class NumericToken extends StringToken { /** The 'radix' value of this token */ public final int radix; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/UnicodeReader.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/UnicodeReader.java index 1ae6cca..5b90499 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/UnicodeReader.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/UnicodeReader.java @@ -178,7 +178,11 @@ private void nextUnicodeInputCharacter() { wasBackslash = false; } else if (character == '\\') { // May be an unicode escape. - wasBackslash = !unicodeEscape(); + switch (unicodeEscape()) { + case BACKSLASH: wasBackslash = true;break; + case VALID_ESCAPE: wasBackslash = false;break; + case BROKEN_ESCAPE: nextUnicodeInputCharacter();break; //skip broken unicode escapes + } } // Codepoint and character match if not surrogate. @@ -229,7 +233,7 @@ private void nextCodePoint() { * * @return true if was an unicode escape. */ - private boolean unicodeEscape() { + private UnicodeEscapeResult unicodeEscape() { // Start of unicode escape (past backslash.) int start = position + width; @@ -247,7 +251,7 @@ private boolean unicodeEscape() { // Needs to have been at least one u. if (index == start) { - return false; + return UnicodeEscapeResult.BACKSLASH; } int code = 0; @@ -272,12 +276,17 @@ private boolean unicodeEscape() { // If all digits are good. if (code >= 0) { character = (char)code; + return UnicodeEscapeResult.VALID_ESCAPE; } else { - log.error(position, Errors.IllegalUnicodeEsc); + log.error(index, Errors.IllegalUnicodeEsc); + return UnicodeEscapeResult.BROKEN_ESCAPE; } + } - // Return true even if error so that the invalid unicode escape is skipped. - return true; + private enum UnicodeEscapeResult { + BACKSLASH, + VALID_ESCAPE, + BROKEN_ESCAPE; } /** diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java index 4c39457..8c4e01e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, 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 @@ -239,7 +239,7 @@ public JavaFileObject next() { @Override public String inferBinaryName(Location location, JavaFileObject file) { - if (file instanceof SigJavaFileObject) { + if (file instanceof SigJavaFileObject) { file = ((SigJavaFileObject) file).getDelegate(); } return super.inferBinaryName(location, file); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java index 65fc3b6..4a349d1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -276,6 +276,13 @@ private class FilerOutputStream extends FilterOutputStream { this.fileObject = fileObject; } +// @Override +// public void write(byte b[], int off, int len) throws IOException { +// Objects.checkFromIndexSize(off, len, b.length); +// out.write(b, off, len); +// } + + @Override public synchronized void close() throws IOException { if (!closed) { closed = true; @@ -313,6 +320,7 @@ private class FilerWriter extends FilterWriter { this.fileObject = fileObject; } + @Override public synchronized void close() throws IOException { if (!closed) { closed = true; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index d139c3e..7db485e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -290,8 +290,10 @@ private void initProcessorLoader() { ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) : fileManager.getClassLoader(CLASS_PATH); + if (processorClassLoader != null && processorClassLoader instanceof Closeable) { compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader); + } } } catch (SecurityException e) { @@ -380,7 +382,7 @@ public ServiceLoader getServiceLoader(Class service) { * @param e If non-null, pass this exception to Abort */ private Iterator handleServiceLoaderUnavailability(String key, Exception e) { - if (fileManager instanceof JavacFileManager) { + if (fileManager instanceof JavacFileManager) { StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager; Iterable workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) ? standardFileManager.getLocationAsPaths(ANNOTATION_PROCESSOR_PATH) @@ -888,7 +890,7 @@ public ProcessorStateIterator iterator() { */ public void close() { if (processorIterator != null && - processorIterator instanceof ServiceIterator) { + processorIterator instanceof ServiceIterator) { ((ServiceIterator) processorIterator).close(); } } @@ -981,7 +983,6 @@ private void discoverAndRunProcs(Set annotationsPresent, * Computes the set of annotations on the symbol in question. * Leave class public for external testing purposes. */ - @SuppressWarnings("preview") public static class ComputeAnnotationSet extends ElementScanner14, Set> { final Elements elements; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java index 957a91a..4f76b37 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java @@ -124,9 +124,11 @@ public Set getElementsAnnotatedWith(TypeElement a) { throwIfNotAnnotation(a); Set result = Collections.emptySet(); - @SuppressWarnings("preview") + + AnnotationSetScanner scanner = new AnnotationSetScanner(result); + for (Element element : rootElements) result = scanner.scan(element, a); @@ -145,9 +147,13 @@ public Set getElementsAnnotatedWithAny(TypeElement... annotat } Set result = Collections.emptySet(); - @SuppressWarnings("preview") + + AnnotationSetMultiScanner scanner = new AnnotationSetMultiScanner(result); + + + for (Element element : rootElements) result = scanner.scan(element, annotationSet); @@ -155,7 +161,6 @@ public Set getElementsAnnotatedWithAny(TypeElement... annotat } // Could be written as a local class inside getElementsAnnotatedWith - @SuppressWarnings("preview") private class AnnotationSetScanner extends ElementScanner14, TypeElement> { // Insertion-order preserving set @@ -191,7 +196,6 @@ public Set visitPackage(PackageElement e, TypeElement annotation) { } // Could be written as a local class inside getElementsAnnotatedWithAny - @SuppressWarnings("preview") private class AnnotationSetMultiScanner extends ElementScanner14, Set> { // Insertion-order preserving set diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java index f0e47f0..e74e7a0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java @@ -43,6 +43,7 @@ import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.StringUtils; +import java.util.Map.Entry; /** * A processor which prints out elements. Used to implement the @@ -55,7 +56,7 @@ * deletion without notice. */ @SupportedAnnotationTypes("*") -@SupportedSourceVersion(SourceVersion.RELEASE_16) +@SupportedSourceVersion(SourceVersion.RELEASE_17) public class PrintingProcessor extends AbstractProcessor { PrintWriter writer; @@ -88,7 +89,6 @@ void print(Element element) { /** * Used for the -Xprint option and called by Elements.printElements */ - @SuppressWarnings("preview") public static class PrintingElementVisitor extends SimpleElementVisitor14 { int indentation; // Indentation level; @@ -522,9 +522,81 @@ private String annotationsToString(Element e) { private void printAnnotations(Element e) { List annots = e.getAnnotationMirrors(); for(AnnotationMirror annotationMirror : annots) { - indent(); - writer.println(annotationMirror); + // Handle compiler-generated container annotations specially + if (!printedContainerAnnotation(e, annotationMirror)) { + indent(); + writer.println(annotationMirror); + } + } + } + + private boolean printedContainerAnnotation(Element e, + AnnotationMirror annotationMirror) { + /* + * If the annotation mirror is marked as mandated and + * looks like a container annotation, elide printing the + * container and just print the wrapped contents. + */ + if (elementUtils.getOrigin(e, annotationMirror) == Elements.Origin.MANDATED) { + // From JLS Chapter 9, an annotation interface AC is a + // containing annotation interface of A if AC declares + // a value() method whose return type is A[] and any + // methods declared by AC other than value() have a + // default value. As an implementation choice, if more + // than one annotation element is found on the outer + // annotation, in other words, something besides a + // "value" method, the annotation will not be treated + // as a wrapper for the purposes of printing. These + // checks are intended to preserve correctness in the + // face of some other kind of annotation being marked + // as mandated. + //var entries = annotationMirror.getElementValues().entrySet(); + annotationMirror.getElementValues().entrySet(); + if (annotationMirror.getElementValues().entrySet().size() == 1) { + DeclaredType annotationType = annotationMirror.getAnnotationType(); + Element annotationTypeAsElement = annotationType.asElement(); + + Entry entry = annotationMirror.getElementValues().entrySet().iterator().next(); + AnnotationValue annotationElements = (AnnotationValue) entry.getValue(); + + // Check that the annotation type declaration has + // a single method named "value" and that it + // returns an array. A stricter check would be + // that it is an array of an annotation type and + // that annotation type in turn was repeatable. + if (annotationTypeAsElement.getKind() == ElementKind.ANNOTATION_TYPE) { + List annotationMethods = ElementFilter.methodsIn(annotationTypeAsElement.getEnclosedElements()); + if (annotationMethods.size() == 1) { + ExecutableElement valueMethod = annotationMethods.get(0); + TypeMirror returnType = valueMethod.getReturnType(); + + if ("value".equals(valueMethod.getSimpleName().toString()) && + returnType.getKind() == TypeKind.ARRAY) { + // Use annotation value visitor that + // returns a boolean if it prints out + // contained annotations as expected + // and false otherwise + + return (new SimpleAnnotationValueVisitor14(false) { + @Override + public Boolean visitArray(List vals, Void p) { + if (vals.size() < 2) { + return false; + } else { + for (AnnotationValue annotValue: vals) { + indent(); + writer.println(annotValue.toString()); + } + return true; + } + } + }).visit(annotationElements); + } + } + } + } } + return false; } // TODO: Refactor diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/CompilerProperties.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/CompilerProperties.java index bb60702..45aa5f5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/CompilerProperties.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/CompilerProperties.java @@ -1007,6 +1007,14 @@ public static Error ConflictingOpensToModule(Symbol arg0) { */ public static final Error ConstExprReq = new Error("compiler", "const.expr.req"); + /** + * compiler.err.constant.label.not.compatible=\ + * constant label of type {0} is not compatible with switch selector type {1} + */ + public static Error ConstantLabelNotCompatible(Type arg0, Type arg1) { + return new Error("compiler", "constant.label.not.compatible", arg0, arg1); + } + /** * compiler.err.cont.outside.loop=\ * continue outside of loop @@ -1101,7 +1109,7 @@ public static Error CyclicRequires(Symbol arg0) { /** * compiler.err.dc.ref.bad.parens=\ - * '')'' missing in reference + * unexpected text after parenthesis */ public static final Error DcRefBadParens = new Error("compiler", "dc.ref.bad.parens"); @@ -1253,6 +1261,12 @@ public static Error DuplicateRequires(Symbol arg0) { return new Error("compiler", "duplicate.requires", arg0); } + /** + * compiler.err.duplicate.total.pattern=\ + * duplicate total pattern + */ + public static final Error DuplicateTotalPattern = new Error("compiler", "duplicate.total.pattern"); + /** * compiler.err.duplicate.uses=\ * duplicate uses: {0} @@ -1550,6 +1564,18 @@ public static Error FirstStatementMustBeCallToAnotherConstructor(Symbol arg0) { return new Error("compiler", "first.statement.must.be.call.to.another.constructor", arg0); } + /** + * compiler.err.flows.through.from.pattern=\ + * illegal fall-through from a pattern + */ + public static final Error FlowsThroughFromPattern = new Error("compiler", "flows.through.from.pattern"); + + /** + * compiler.err.flows.through.to.pattern=\ + * illegal fall-through to a pattern + */ + public static final Error FlowsThroughToPattern = new Error("compiler", "flows.through.to.pattern"); + /** * compiler.err.foreach.not.applicable.to.type=\ * for-each not applicable to expression type\n\ @@ -1572,13 +1598,13 @@ public static Error ForeachNotApplicableToType(Type arg0, Fragment arg1) { /** * compiler.err.fp.number.too.large=\ - * floating point number too large + * floating-point number too large */ public static final Error FpNumberTooLarge = new Error("compiler", "fp.number.too.large"); /** * compiler.err.fp.number.too.small=\ - * floating point number too small + * floating-point number too small */ public static final Error FpNumberTooSmall = new Error("compiler", "fp.number.too.small"); @@ -1898,7 +1924,7 @@ public static Error IncorrectReceiverType(Type arg0, Type arg1) { /** * compiler.err.instanceof.pattern.no.subtype=\ - * pattern type {0} is a subtype of expression type {1} + * expression type {0} is a subtype of pattern type {1} */ public static Error InstanceofPatternNoSubtype(Type arg0, Type arg1) { return new Error("compiler", "instanceof.pattern.no.subtype", arg0, arg1); @@ -2257,7 +2283,8 @@ public static Error InvalidTarget(String arg0) { /** * compiler.err.is.preview=\ - * {0} is an API that is part of a preview feature + * {0} is a preview API and is disabled by default.\n\ + * (use --enable-preview to enable preview APIs) */ public static Error IsPreview(Symbol arg0) { return new Error("compiler", "is.preview", arg0); @@ -2411,7 +2438,7 @@ public static Error LocnModuleInfoNotAllowedOnPatchPath(JavaFileObject arg0) { /** * compiler.err.malformed.fp.lit=\ - * malformed floating point literal + * malformed floating-point literal */ public static final Error MalformedFpLit = new Error("compiler", "malformed.fp.lit"); @@ -2800,6 +2827,12 @@ public static Error NotEnclClass(Symbol arg0) { */ public static final Error NotExhaustive = new Error("compiler", "not.exhaustive"); + /** + * compiler.err.not.exhaustive.statement=\ + * the switch statement does not cover all possible input values + */ + public static final Error NotExhaustiveStatement = new Error("compiler", "not.exhaustive.statement"); + /** * compiler.err.not.in.module.on.module.source.path=\ * not in a module on the module source path @@ -3066,6 +3099,18 @@ public static Error PackageNotVisible(Symbol arg0, Fragment arg1) { return new Error("compiler", "package.not.visible", arg0, arg1); } + /** + * compiler.err.pattern.dominated=\ + * this case label is dominated by a preceding case label + */ + public static final Error PatternDominated = new Error("compiler", "pattern.dominated"); + + /** + * compiler.err.pattern.expected=\ + * type pattern expected + */ + public static final Error PatternExpected = new Error("compiler", "pattern.expected"); + /** * compiler.err.pkg.annotations.sb.in.package-info.java=\ * package annotations should be in file package-info.java @@ -3114,8 +3159,8 @@ public static Error PreviewFeatureDisabled(Fragment arg0) { /** * compiler.err.preview.feature.disabled.classfile=\ - * classfile for {0} uses preview features of Java SE {1}.\n\ - * (use --enable-preview to allow loading of classfiles which contain preview features) + * class file for {0} uses preview features of Java SE {1}.\n\ + * (use --enable-preview to allow loading of class files which contain preview features) */ public static Error PreviewFeatureDisabledClassfile(JavaFileObject arg0, String arg1) { return new Error("compiler", "preview.feature.disabled.classfile", arg0, arg1); @@ -3654,12 +3699,6 @@ public static Error StackSimError(Symbol arg0) { */ public static final Error SwitchMixingCaseTypes = new Error("compiler", "switch.mixing.case.types"); - /** - * compiler.err.switch.null.not.allowed=\ - * null label in case is not allowed - */ - public static final Error SwitchNullNotAllowed = new Error("compiler", "switch.null.not.allowed"); - /** * compiler.err.this.as.identifier=\ * as of release 8, ''this'' is allowed as the parameter name for the receiver type only\n\ @@ -3687,6 +3726,12 @@ public static Error TooManyPatchedModules(Set arg0) { return new Error("compiler", "too.many.patched.modules", arg0); } + /** + * compiler.err.total.pattern.and.default=\ + * switch has both a total pattern and a default label + */ + public static final Error TotalPatternAndDefault = new Error("compiler", "total.pattern.and.default"); + /** * compiler.err.try.resource.may.not.be.assigned=\ * auto-closeable resource {0} may not be assigned @@ -4171,6 +4216,14 @@ public static Warning ConstantSVUID(Symbol arg0) { return new Warning("compiler", "constant.SVUID", arg0); } + /** + * compiler.warn.declared.using.preview=\ + * {0} {1} is declared using a preview feature, which may be removed in a future release. + */ + public static Warning DeclaredUsingPreview(KindName arg0, Symbol arg1) { + return new Warning("compiler", "declared.using.preview", arg0, arg1); + } + /** * compiler.warn.deprecated.annotation.has.no.effect=\ * @Deprecated annotation has no effect on this {0} declaration @@ -4384,12 +4437,20 @@ public static Warning InvalidPath(String arg0) { /** * compiler.warn.is.preview=\ - * {0} is an API that is part of a preview feature + * {0} is a preview API and may be removed in a future release. */ public static Warning IsPreview(Symbol arg0) { return new Warning("compiler", "is.preview", arg0); } + /** + * compiler.warn.is.preview.reflective=\ + * {0} is a reflective preview API and may be removed in a future release. + */ + public static Warning IsPreviewReflective(Symbol arg0) { + return new Warning("compiler", "is.preview.reflective", arg0); + } + /** * compiler.warn.leaks.not.accessible=\ * {0} {1} in module {2} is not accessible to clients that require this module @@ -4704,7 +4765,7 @@ public static Warning PreviewFeatureUse(Fragment arg0) { /** * compiler.warn.preview.feature.use.classfile=\ - * classfile for {0} uses preview features of Java SE {1}. + * class file for {0} uses preview features of Java SE {1}. */ public static Warning PreviewFeatureUseClassfile(JavaFileObject arg0, String arg1) { return new Warning("compiler", "preview.feature.use.classfile", arg0, arg1); @@ -4995,6 +5056,12 @@ public static Warning StaticNotQualifiedByType(KindName arg0, Symbol arg1) { return new Warning("compiler", "static.not.qualified.by.type", arg0, arg1); } + /** + * compiler.warn.strictfp=\ + * as of release 17, all floating-point expressions are evaluated strictly and ''strictfp'' is not required + */ + public static final Warning Strictfp = new Warning("compiler", "strictfp"); + /** * compiler.warn.sun.proprietary=\ * {0} is internal proprietary API and may be removed in a future release @@ -5318,63 +5385,67 @@ public static Note MultipleElements(String arg0, String arg1, String arg2) { /** * compiler.note.preview.filename=\ - * {0} uses preview language features. + * {0} uses preview features of Java SE {1}. */ - public static Note PreviewFilename(File arg0) { - return new Note("compiler", "preview.filename", arg0); + public static Note PreviewFilename(File arg0, Source arg1) { + return new Note("compiler", "preview.filename", arg0, arg1); } /** * compiler.note.preview.filename=\ - * {0} uses preview language features. + * {0} uses preview features of Java SE {1}. */ - public static Note PreviewFilename(JavaFileObject arg0) { - return new Note("compiler", "preview.filename", arg0); + public static Note PreviewFilename(JavaFileObject arg0, Source arg1) { + return new Note("compiler", "preview.filename", arg0, arg1); } /** * compiler.note.preview.filename=\ - * {0} uses preview language features. + * {0} uses preview features of Java SE {1}. */ - public static Note PreviewFilename(Path arg0) { - return new Note("compiler", "preview.filename", arg0); + public static Note PreviewFilename(Path arg0, Source arg1) { + return new Note("compiler", "preview.filename", arg0, arg1); } /** * compiler.note.preview.filename.additional=\ - * {0} has additional uses of preview language features. + * {0} has additional uses of preview features of Java SE {1}. */ - public static Note PreviewFilenameAdditional(File arg0) { - return new Note("compiler", "preview.filename.additional", arg0); + public static Note PreviewFilenameAdditional(File arg0, Source arg1) { + return new Note("compiler", "preview.filename.additional", arg0, arg1); } /** * compiler.note.preview.filename.additional=\ - * {0} has additional uses of preview language features. + * {0} has additional uses of preview features of Java SE {1}. */ - public static Note PreviewFilenameAdditional(JavaFileObject arg0) { - return new Note("compiler", "preview.filename.additional", arg0); + public static Note PreviewFilenameAdditional(JavaFileObject arg0, Source arg1) { + return new Note("compiler", "preview.filename.additional", arg0, arg1); } /** * compiler.note.preview.filename.additional=\ - * {0} has additional uses of preview language features. + * {0} has additional uses of preview features of Java SE {1}. */ - public static Note PreviewFilenameAdditional(Path arg0) { - return new Note("compiler", "preview.filename.additional", arg0); + public static Note PreviewFilenameAdditional(Path arg0, Source arg1) { + return new Note("compiler", "preview.filename.additional", arg0, arg1); } /** * compiler.note.preview.plural=\ - * Some input files use preview language features. + * Some input files use preview features of Java SE {0}. */ - public static final Note PreviewPlural = new Note("compiler", "preview.plural"); + public static Note PreviewPlural(Source arg0) { + return new Note("compiler", "preview.plural", arg0); + } /** * compiler.note.preview.plural.additional=\ - * Some input files additionally use preview language features. + * Some input files additionally use preview features of Java SE {0}. */ - public static final Note PreviewPluralAdditional = new Note("compiler", "preview.plural.additional"); + public static Note PreviewPluralAdditional(Source arg0) { + return new Note("compiler", "preview.plural.additional", arg0); + } /** * compiler.note.preview.recompile=\ @@ -6819,6 +6890,12 @@ public static Fragment FatalErrCantLocateMeth(Name arg0) { */ public static final Fragment FeatureAnnotationsAfterTypeParams = new Fragment("compiler", "feature.annotations.after.type.params"); + /** + * compiler.misc.feature.case.null=\ + * null in switch cases + */ + public static final Fragment FeatureCaseNull = new Fragment("compiler", "feature.case.null"); + /** * compiler.misc.feature.default.methods=\ * default methods @@ -6909,6 +6986,12 @@ public static Fragment FeatureNotSupportedInSourcePlural(Fragment arg0, String a */ public static final Fragment FeaturePatternMatchingInstanceof = new Fragment("compiler", "feature.pattern.matching.instanceof"); + /** + * compiler.misc.feature.pattern.switch=\ + * patterns in switch statements + */ + public static final Fragment FeaturePatternSwitch = new Fragment("compiler", "feature.pattern.switch"); + /** * compiler.misc.feature.private.intf.methods=\ * private interface methods @@ -7009,6 +7092,12 @@ public static Fragment FileDoesntContainClass(Name arg0) { return new Fragment("compiler", "file.doesnt.contain.class", arg0); } + /** + * compiler.misc.guard=\ + * a guard + */ + public static final Fragment Guard = new Fragment("compiler", "guard"); + /** * compiler.misc.illegal.signature=\ * illegal signature attribute for type {1} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 77cc748..24e2fcb 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2021, 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 @@ -351,6 +351,9 @@ compiler.misc.lambda=\ compiler.misc.inner.cls=\ an inner class +compiler.misc.guard=\ + a guard + # 0: type compiler.err.cant.deref=\ {0} cannot be dereferenced @@ -494,9 +497,28 @@ compiler.err.same.binary.name=\ compiler.err.duplicate.case.label=\ duplicate case label +compiler.err.pattern.dominated=\ + this case label is dominated by a preceding case label + compiler.err.duplicate.default.label=\ duplicate default label +compiler.err.duplicate.total.pattern=\ + duplicate total pattern + +compiler.err.total.pattern.and.default=\ + switch has both a total pattern and a default label + +# 0: type, 1: type +compiler.err.constant.label.not.compatible=\ + constant label of type {0} is not compatible with switch selector type {1} + +compiler.err.flows.through.to.pattern=\ + illegal fall-through to a pattern + +compiler.err.flows.through.from.pattern=\ + illegal fall-through from a pattern + compiler.err.else.without.if=\ ''else'' without ''if'' @@ -564,10 +586,10 @@ compiler.err.foreach.not.applicable.to.type=\ found: {0} compiler.err.fp.number.too.large=\ - floating point number too large + floating-point number too large compiler.err.fp.number.too.small=\ - floating point number too small + floating-point number too small compiler.err.generic.array.creation=\ generic array creation @@ -785,7 +807,7 @@ compiler.err.limit.string.overflow=\ UTF8 representation for string \"{0}...\" is too long for the constant pool compiler.err.malformed.fp.lit=\ - malformed floating point literal + malformed floating-point literal compiler.err.method.does.not.override.superclass=\ method does not override or implement a method from a supertype @@ -1167,6 +1189,9 @@ compiler.err.static.imp.only.classes.and.interfaces=\ compiler.err.string.const.req=\ constant string expression required +compiler.err.pattern.expected=\ + type pattern expected + # 0: symbol, 1: fragment compiler.err.cannot.generate.class=\ error while generating class {0}\n\ @@ -1361,6 +1386,9 @@ compiler.err.unreachable.stmt=\ compiler.err.not.exhaustive=\ the switch expression does not cover all possible input values +compiler.err.not.exhaustive.statement=\ + the switch statement does not cover all possible input values + compiler.err.initializer.must.be.able.to.complete.normally=\ initializer must be able to complete normally @@ -1417,7 +1445,7 @@ compiler.err.instanceof.reifiable.not.safe=\ # 0: type, 1: type compiler.err.instanceof.pattern.no.subtype=\ - pattern type {0} is a subtype of expression type {1} + expression type {0} is a subtype of pattern type {1} # 0: symbol compiler.misc.varargs.trustme.on.non.varargs.meth=\ @@ -1636,24 +1664,26 @@ compiler.note.unchecked.filename.additional=\ compiler.note.unchecked.plural.additional=\ Some input files additionally use unchecked or unsafe operations. -# 0: file name +# 0: file name, 1: source compiler.note.preview.filename=\ - {0} uses preview language features. + {0} uses preview features of Java SE {1}. +# 0: source compiler.note.preview.plural=\ - Some input files use preview language features. + Some input files use preview features of Java SE {0}. # The following string may appear after one of the above deprecation # messages. compiler.note.preview.recompile=\ Recompile with -Xlint:preview for details. -# 0: file name +# 0: file name, 1: source compiler.note.preview.filename.additional=\ - {0} has additional uses of preview language features. + {0} has additional uses of preview features of Java SE {1}. +# 0: source compiler.note.preview.plural.additional=\ - Some input files additionally use preview language features. + Some input files additionally use preview features of Java SE {0}. # Notes related to annotation processing @@ -1766,6 +1796,9 @@ compiler.warn.dir.path.element.not.directory=\ compiler.warn.missing-explicit-ctor=\ class {0} in exported package {1} declares no explicit constructors, thereby exposing a default constructor to clients of module {2} +compiler.warn.strictfp=\ + as of release 17, all floating-point expressions are evaluated strictly and ''strictfp'' is not required + compiler.warn.finally.cannot.complete=\ finally clause cannot complete normally @@ -1787,11 +1820,16 @@ compiler.warn.has.been.deprecated.for.removal=\ # 0: symbol compiler.warn.is.preview=\ - {0} is an API that is part of a preview feature + {0} is a preview API and may be removed in a future release. # 0: symbol compiler.err.is.preview=\ - {0} is an API that is part of a preview feature + {0} is a preview API and is disabled by default.\n\ + (use --enable-preview to enable preview APIs) + +# 0: symbol +compiler.warn.is.preview.reflective=\ + {0} is a reflective preview API and may be removed in a future release. # 0: symbol compiler.warn.has.been.deprecated.module=\ @@ -2195,9 +2233,6 @@ compiler.err.enum.constant.not.expected=\ enum constant not expected here ## The following are related in form, but do not easily fit the above paradigm. -compiler.err.expected.module=\ - ''module'' expected - compiler.err.expected.module.or.open=\ ''module'' or ''open'' expected @@ -2870,8 +2905,8 @@ compiler.err.preview.feature.disabled.plural=\ # 0: file object (classfile), 1: string (expected version) compiler.err.preview.feature.disabled.classfile=\ - classfile for {0} uses preview features of Java SE {1}.\n\ - (use --enable-preview to allow loading of classfiles which contain preview features) + class file for {0} uses preview features of Java SE {1}.\n\ + (use --enable-preview to allow loading of class files which contain preview features) # 0: message segment (feature) compiler.warn.preview.feature.use=\ @@ -2883,7 +2918,7 @@ compiler.warn.preview.feature.use.plural=\ # 0: file object (classfile), 1: string (expected version) compiler.warn.preview.feature.use.classfile=\ - classfile for {0} uses preview features of Java SE {1}. + class file for {0} uses preview features of Java SE {1}. compiler.misc.feature.modules=\ @@ -2955,6 +2990,12 @@ compiler.misc.feature.records=\ compiler.misc.feature.sealed.classes=\ sealed classes +compiler.misc.feature.case.null=\ + null in switch cases + +compiler.misc.feature.pattern.switch=\ + patterns in switch statements + compiler.warn.underscore.as.identifier=\ as of release 9, ''_'' is a keyword, and may not be used as an identifier @@ -3212,7 +3253,7 @@ compiler.err.dc.gt.expected=\ ''>'' expected compiler.err.dc.ref.bad.parens=\ - '')'' missing in reference + unexpected text after parenthesis compiler.err.dc.ref.syntax.error=\ syntax error in reference @@ -3476,9 +3517,6 @@ compiler.err.illegal.argument.for.option=\ compiler.err.match.binding.exists=\ illegal attempt to redefine an existing match binding -compiler.err.switch.null.not.allowed=\ - null label in case is not allowed - compiler.err.switch.case.unexpected.statement=\ unexpected statement in case, expected is an expression, a block or a throw statement @@ -3780,6 +3818,7 @@ compiler.err.preview.without.source.or.release=\ --enable-preview must be used with either -source or --release + compiler.javadoc.enum.valueOf=\ Returns the enum constant of this type with the specified name.\n\ The string must match exactly an identifier used to declare\n\ @@ -3798,8 +3837,12 @@ used to iterate over the constants as follows:\n

\
 \n        System.out.println(c);\n
\n\ @return an array containing the constants of this enum\n\ type, in the order they are declared +# 0: kind name, 1: symbol +compiler.warn.declared.using.preview=\ + {0} {1} is declared using a preview feature, which may be removed in a future release. compiler.warn.attempt.to.synchronize.on.instance.of.value.based.class=\ attempt to synchronize on an instance of a value-based class + diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties index 4bb02bd..3768f6f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2021, 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 @@ -172,7 +172,7 @@ javac.opt.arg.Xlint=\ javac.opt.Xlint.custom=\ Warnings to enable or disable, separated by comma.\n\ Precede a key by '-' to disable the specified warning.\n\ - Supported keys are: + Use --help-lint to see the supported keys. javac.opt.Xlint.desc.auxiliaryclass=\ Warn about an auxiliary class that is hidden in a source file, and is used from other files. @@ -241,11 +241,14 @@ javac.opt.Xlint.desc.requires-transitive-automatic=\ javac.opt.Xlint.desc.serial=\ Warn about Serializable classes that do not provide a serial version ID. \n\ -\ Also warn about access to non-public members from a serializable element. +\ Also warn about access to non-public members from a serializable element. javac.opt.Xlint.desc.static=\ Warn about accessing a static member using an instance. +javac.opt.Xlint.desc.strictfp=\ + Warn about unnecessary use of the strictfp modifier. + javac.opt.Xlint.desc.text-blocks=\ Warn about inconsistent white space characters in text block indentation. @@ -286,15 +289,16 @@ javac.opt.Xdoclint.package.desc=\ expands to all sub-packages of the given package. Each can be prefixed\n\ with '-' to disable checks for the specified package or packages. -javac.opt.doclint.format=\ - Specify the format for documentation comments - javac.opt.Xstdout=\ Redirect standard output javac.opt.X=\ Print help on extra options javac.opt.help=\ Print this help message +javac.opt.help.lint=\ + Print the supported keys for -Xlint +javac.opt.help.lint.header=\ + The supported keys for -Xlint are: javac.opt.print=\ Print out a textual representation of specified types javac.opt.printRounds=\ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java index f4d0280..177894e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -501,7 +501,7 @@ public Void visitStartElement(StartElementTree node, Void p) { print(attrs, " "); DocTree last = node.getAttributes().get(attrs.size() - 1); if (node.isSelfClosing() && last instanceof AttributeTree - && ((AttributeTree) last).getValueKind() == ValueKind.UNQUOTED) + && ((AttributeTree)last).getValueKind() == ValueKind.UNQUOTED) print(" "); } if (node.isSelfClosing()) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index 29e52af..bef5d8c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -242,6 +242,9 @@ public enum Tag { /** Patterns. */ BINDINGPATTERN, + DEFAULTCASELABEL, + GUARDPATTERN, + PARENTHESIZEDPATTERN, /** Indexed array expressions, of type Indexed. */ @@ -555,6 +558,11 @@ public JCModuleDecl getModuleDecl() { return null; } + @DefinedBy(Api.COMPILER_TREE) + public JCModuleDecl getModule() { + return getModuleDecl(); + } + @DefinedBy(Api.COMPILER_TREE) public JCPackageDecl getPackage() { for (JCTree tree : defs) { @@ -593,12 +601,15 @@ public Position.LineMap getLineMap() { } @DefinedBy(Api.COMPILER_TREE) public List getTypeDecls() { + ListBuffer typeDefs = new ListBuffer(); for (JCTree tree : defs) { - if (!tree.hasTag(PACKAGEDEF) && !tree.hasTag(IMPORT)) + if (!tree.hasTag(PACKAGEDEF) && !tree.hasTag(IMPORT)) typeDefs.append(tree); } return typeDefs.toList(); + + } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { @@ -693,7 +704,15 @@ public JCStatement setPos(int pos) { } } - public static abstract class JCExpression extends JCTree implements ExpressionTree { + public static abstract class JCCaseLabel extends JCTree implements CaseLabelTree { + public abstract boolean isExpression(); + public boolean isNullPattern() { + return isExpression() && TreeInfo.isNull((JCExpression) this); + } + public abstract boolean isPattern(); + } + + public static abstract class JCExpression extends JCCaseLabel implements ExpressionTree { @Override public JCExpression setType(Type type) { super.setType(type); @@ -707,6 +726,16 @@ public JCExpression setPos(int pos) { public boolean isPoly() { return false; } public boolean isStandalone() { return true; } + + @Override + public boolean isExpression() { + return true; + } + + @Override + public boolean isPattern() { + return false; + } } /** @@ -803,7 +832,6 @@ protected JCClassDecl(JCModifiers mods, @Override public void accept(Visitor v) { v.visitClassDef(this); } - @SuppressWarnings("preview") @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { if ((mods.flags & Flags.ANNOTATION) != 0) @@ -964,23 +992,35 @@ public static class JCVariableDecl extends JCStatement implements VariableTree { public VarSymbol sym; /** explicit start pos */ public int startPos = Position.NOPOS; + /** declared using `var` */ + private boolean declaredUsingVar; protected JCVariableDecl(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, VarSymbol sym) { + this(mods, name, vartype, init, sym, false); + } + + protected JCVariableDecl(JCModifiers mods, + Name name, + JCExpression vartype, + JCExpression init, + VarSymbol sym, + boolean declaredUsingVar) { this.mods = mods; this.name = name; this.vartype = vartype; this.init = init; this.sym = sym; + this.declaredUsingVar = declaredUsingVar; } protected JCVariableDecl(JCModifiers mods, JCExpression nameexpr, JCExpression vartype) { - this(mods, null, vartype, null, null); + this(mods, null, vartype, null, null, false); this.nameexpr = nameexpr; if (nameexpr.hasTag(Tag.IDENT)) { this.name = ((JCIdent)nameexpr).name; @@ -994,6 +1034,10 @@ public boolean isImplicitlyTyped() { return vartype == null; } + public boolean declaredUsingVar() { + return declaredUsingVar; + } + @Override public void accept(Visitor v) { v.visitVarDef(this); } @@ -1253,6 +1297,10 @@ public Tag getTag() { public static class JCSwitch extends JCStatement implements SwitchTree { public JCExpression selector; public List cases; + /** Position of closing brace, optional. */ + public int endpos = Position.NOPOS; + public boolean hasTotalPattern; + public boolean patternSwitch; protected JCSwitch(JCExpression selector, List cases) { this.selector = selector; this.cases = cases; @@ -1285,16 +1333,18 @@ public static class JCCase extends JCStatement implements CaseTree { public static final CaseKind STATEMENT = CaseKind.STATEMENT; public static final CaseKind RULE = CaseKind.RULE; public final CaseKind caseKind; + public List labels; public List pats; public List stats; public JCTree body; public boolean completesNormally; - protected JCCase(CaseKind caseKind, List pats, + protected JCCase(CaseKind caseKind, List labels, List stats, JCTree body) { - Assert.checkNonNull(pats); - Assert.check(pats.isEmpty() || pats.head != null); + Assert.checkNonNull(labels); + Assert.check(labels.isEmpty() || labels.head != null); this.caseKind = caseKind; - this.pats = pats; + this.labels = labels; + this.pats = labels.stream().filter(p -> p instanceof JCExpression).map(p -> (JCExpression) p).collect(List.collector()); this.stats = stats; this.body = body; } @@ -1304,9 +1354,11 @@ protected JCCase(CaseKind caseKind, List pats, @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.CASE; } @Override @Deprecated @DefinedBy(Api.COMPILER_TREE) - public JCExpression getExpression() { return pats.head; } + public JCExpression getExpression() { return getExpressions().head; } @Override @DefinedBy(Api.COMPILER_TREE) - public List getExpressions() { return pats; } + public List getExpressions() { return labels.stream().filter(p -> p instanceof JCExpression).map(p -> (JCExpression) p).collect(List.collector()); } + @Override @DefinedBy(Api.COMPILER_TREE) + public List getLabels() { return labels; } @Override @DefinedBy(Api.COMPILER_TREE) public List getStatements() { return caseKind == CaseKind.STATEMENT ? stats : null; @@ -1335,6 +1387,8 @@ public static class JCSwitchExpression extends JCPolyExpression implements Switc public List cases; /** Position of closing brace, optional. */ public int endpos = Position.NOPOS; + public boolean hasTotalPattern; + public boolean patternSwitch; protected JCSwitchExpression(JCExpression selector, List cases) { this.selector = selector; this.cases = cases; @@ -2201,8 +2255,18 @@ public Tag getTag() { /** * Pattern matching forms. */ - public static abstract class JCPattern extends JCTree + public static abstract class JCPattern extends JCCaseLabel implements PatternTree { + + @Override + public boolean isExpression() { + return false; + } + + @Override + public boolean isPattern() { + return true; + } } public static class JCBindingPattern extends JCPattern @@ -2240,6 +2304,121 @@ public Tag getTag() { } } + public static class JCDefaultCaseLabel extends JCCaseLabel + implements DefaultCaseLabelTree { + + protected JCDefaultCaseLabel() { + } + + @Override + public void accept(Visitor v) { + v.visitDefaultCaseLabel(this); + } + + @DefinedBy(Api.COMPILER_TREE) + public Kind getKind() { + return Kind.DEFAULT_CASE_LABEL; + } + + @Override + @DefinedBy(Api.COMPILER_TREE) + public R accept(TreeVisitor v, D d) { + return v.visitDefaultCaseLabel(this, d); + } + + @Override + public Tag getTag() { + return DEFAULTCASELABEL; + } + + @Override + public boolean isExpression() { + return false; + } + + @Override + public boolean isPattern() { + return false; + } + } + + public static class JCParenthesizedPattern extends JCPattern + implements ParenthesizedPatternTree { + public JCPattern pattern; + + public JCParenthesizedPattern(JCPattern pattern) { + this.pattern = pattern; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public PatternTree getPattern() { + return pattern; + } + + @Override + public void accept(Visitor v) { + v.visitParenthesizedPattern(this); + } + + @DefinedBy(Api.COMPILER_TREE) + public Kind getKind() { + return Kind.PARENTHESIZED_PATTERN; + } + + @Override + @DefinedBy(Api.COMPILER_TREE) + public R accept(TreeVisitor v, D d) { + return v.visitParenthesizedPattern(this, d); + } + + @Override + public Tag getTag() { + return PARENTHESIZEDPATTERN; + } + } + + public static class JCGuardPattern extends JCPattern + implements GuardedPatternTree { + public JCPattern patt; + public JCExpression expr; + + public JCGuardPattern(JCPattern patt, JCExpression expr) { + this.patt = patt; + this.expr = expr; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public PatternTree getPattern() { + return patt; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public ExpressionTree getExpression() { + return expr; + } + + @Override + public void accept(Visitor v) { + v.visitGuardPattern(this); + } + + @DefinedBy(Api.COMPILER_TREE) + public Kind getKind() { + return Kind.GUARDED_PATTERN; + } + + @Override + @DefinedBy(Api.COMPILER_TREE) + public R accept(TreeVisitor v, D d) { + return v.visitGuardedPattern(this, d); + } + + @Override + public Tag getTag() { + return Tag.GUARDPATTERN; + } + } + /** * An array selection */ @@ -3176,7 +3355,7 @@ JCForLoop ForLoop(List init, JCLabeledStatement Labelled(Name label, JCStatement body); JCSwitch Switch(JCExpression selector, List cases); JCSwitchExpression SwitchExpression(JCExpression selector, List cases); - JCCase Case(CaseTree.CaseKind caseKind, List pat, + JCCase Case(CaseTree.CaseKind caseKind, List labels, List stats, JCTree body); JCSynchronized Synchronized(JCExpression lock, JCBlock body); JCTry Try(JCBlock body, List catchers, JCBlock finalizer); @@ -3280,6 +3459,9 @@ public static abstract class Visitor { public void visitTypeCast(JCTypeCast that) { visitTree(that); } public void visitTypeTest(JCInstanceOf that) { visitTree(that); } public void visitBindingPattern(JCBindingPattern that) { visitTree(that); } + public void visitDefaultCaseLabel(JCDefaultCaseLabel that) { visitTree(that); } + public void visitParenthesizedPattern(JCParenthesizedPattern that) { visitTree(that); } + public void visitGuardPattern(JCGuardPattern that) { visitTree(that); } public void visitIndexed(JCArrayAccess that) { visitTree(that); } public void visitSelect(JCFieldAccess that) { visitTree(that); } public void visitReference(JCMemberReference that) { visitTree(that); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java index 471e524..4f3904a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -83,12 +83,12 @@ public Pretty(Writer out, boolean sourceOutput) { * A string sequence to be used when Pretty output should be constrained * to fit into a given size */ - private final static String trimSequence = "[...]"; + private static final String trimSequence = "[...]"; /** * Max number of chars to be generated when output should fit into a single line */ - private final static int PREFERRED_LENGTH = 20; + private static final int PREFERRED_LENGTH = 20; /** Align code to be indented to left margin. */ @@ -461,6 +461,7 @@ public void visitModuleDef(JCModuleDecl tree) { if (tree.directives == null) { print(";"); } else { + print(" "); printBlock(tree.directives); } println(); @@ -702,8 +703,9 @@ public void visitVarDef(JCVariableDecl tree) { JCTree vartype = tree.vartype; List tas = null; if (vartype instanceof JCAnnotatedType) { - tas = ((JCAnnotatedType)vartype).annotations; - vartype = ((JCAnnotatedType)vartype).underlyingType; + JCAnnotatedType annotatedType = (JCAnnotatedType)vartype; + tas = annotatedType.annotations; + vartype = annotatedType.underlyingType; } printExpr(((JCArrayTypeTree) vartype).elemtype); if (tas != null) { @@ -852,11 +854,11 @@ public void visitSwitch(JCSwitch tree) { public void visitCase(JCCase tree) { try { - if (tree.pats.isEmpty()) { + if (tree.labels.size() == 1 && tree.labels.get(0).hasTag(DEFAULTCASELABEL)) { print("default"); } else { print("case "); - printExprs(tree.pats); + printExprs(tree.labels); } if (tree.caseKind == JCCase.STATEMENT) { print(":"); @@ -867,13 +869,26 @@ public void visitCase(JCCase tree) { align(); } else { print(" -> "); - printStat(tree.stats.head); + if (tree.stats.size() == 1) { + printStat(tree.stats.head); + } else { + printBlock(tree.stats); + } } } catch (IOException e) { throw new UncheckedIOException(e); } } + @Override + public void visitDefaultCaseLabel(JCTree.JCDefaultCaseLabel that) { + try { + print("default"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitSwitchExpression(JCSwitchExpression tree) { try { print("switch "); @@ -902,6 +917,28 @@ public void visitBindingPattern(JCBindingPattern patt) { } } + @Override + public void visitParenthesizedPattern(JCParenthesizedPattern patt) { + try { + print("("); + printExpr(patt.pattern); + print(")"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + public void visitGuardPattern(JCGuardPattern patt) { + try { + printExpr(patt.patt); + print(" && "); + printExpr(patt.expr); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitSynchronized(JCSynchronized tree) { try { print("synchronized "); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java index c4f90e0..2e223a3 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -152,7 +152,7 @@ public JCTree visitYield(YieldTree node, P p) { @DefinedBy(Api.COMPILER_TREE) public JCTree visitCase(CaseTree node, P p) { JCCase t = (JCCase) node; - List pats = copy(t.pats, p); + List labels = copy(t.labels, p); List stats = copy(t.stats, p); JCTree body; if (node.getCaseKind() == CaseTree.CaseKind.RULE) { @@ -161,7 +161,7 @@ public JCTree visitCase(CaseTree node, P p) { } else { body = null; } - return M.at(t.pos).Case(t.caseKind, pats, stats, body); + return M.at(t.pos).Case(t.caseKind, labels, stats, body); } @DefinedBy(Api.COMPILER_TREE) @@ -497,6 +497,27 @@ public JCTree visitBindingPattern(BindingPatternTree node, P p) { return M.at(t.pos).BindingPattern(var); } + @DefinedBy(Api.COMPILER_TREE) + public JCTree visitGuardedPattern(GuardedPatternTree node, P p) { + JCGuardPattern t = (JCGuardPattern) node; + JCPattern patt = copy(t.patt, p); + JCExpression expr = copy(t.expr, p); + return M.at(t.pos).GuardPattern(patt, expr); + } + + @DefinedBy(Api.COMPILER_TREE) + public JCTree visitParenthesizedPattern(ParenthesizedPatternTree node, P p) { + JCParenthesizedPattern t = (JCParenthesizedPattern) node; + JCPattern pattern = copy(t.pattern, p); + return M.at(t.pos).ParenthesizedPattern(pattern); + } + + @DefinedBy(Api.COMPILER_TREE) + public JCTree visitDefaultCaseLabel(DefaultCaseLabelTree node, P p) { + JCDefaultCaseLabel t = (JCDefaultCaseLabel) node; + return M.at(t.pos).DefaultCaseLabel(); + } + @DefinedBy(Api.COMPILER_TREE) public JCTree visitUnary(UnaryTree node, P p) { JCUnary t = (JCUnary) node; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index b2addea..236464a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -40,6 +40,7 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.Kind.*; import com.sun.tools.javac.code.Symbol.VarSymbol; +import static com.sun.tools.javac.code.TypeTag.BOOLEAN; import static com.sun.tools.javac.code.TypeTag.BOT; import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK; @@ -429,6 +430,9 @@ else if (tree.hasTag(TRY)) { JCTry t = (JCTry) tree; return endPos((t.finalizer != null) ? t.finalizer : (t.catchers.nonEmpty() ? t.catchers.last().body : t.body)); + } else if (tree.hasTag(SWITCH) && + ((JCSwitch) tree).endpos != Position.NOPOS) { + return ((JCSwitch) tree).endpos; } else if (tree.hasTag(SWITCH_EXPRESSION) && ((JCSwitchExpression) tree).endpos != Position.NOPOS) { return ((JCSwitchExpression) tree).endpos; @@ -551,6 +555,10 @@ public static int getStartPos(JCTree tree) { JCBindingPattern node = (JCBindingPattern)tree; return getStartPos(node.var); } + case GUARDPATTERN: { + JCGuardPattern node = (JCGuardPattern) tree; + return getStartPos(node.patt); + } case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; if (node.errs != null && node.errs.nonEmpty()) { @@ -645,6 +653,14 @@ public static int getEndPos(JCTree tree, EndPosTable endPosTable) { return getEndPos(((JCWhileLoop) tree).body, endPosTable); case ANNOTATED_TYPE: return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable); + case PARENTHESIZEDPATTERN: { + JCParenthesizedPattern node = (JCParenthesizedPattern) tree; + return getEndPos(node.pattern, endPosTable); + } + case GUARDPATTERN: { + JCGuardPattern node = (JCGuardPattern) tree; + return getEndPos(node.expr, endPosTable); + } case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; if (node.errs != null && node.errs.nonEmpty()) @@ -1058,7 +1074,7 @@ public static long flags(JCTree tree) { */ public static long firstFlag(long flags) { long flag = 1; - while ((flag & flags & ExtendedStandardFlags) == 0) + while ((flag & flags) == 0) flag = flag << 1; return flag; } @@ -1352,4 +1368,71 @@ public static boolean isPackageInfo(JCCompilationUnit tree) { return tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE); } + public static boolean isErrorEnumSwitch(JCExpression selector, List cases) { + return selector.type.tsym.kind == Kinds.Kind.ERR && + cases.stream().flatMap(c -> c.labels.stream()) + .allMatch(p -> p.hasTag(IDENT)); + } + + public static PatternPrimaryType primaryPatternType(JCPattern pat) { + PatternPrimaryType patternPrimaryType = null; + switch (pat.getTag()) { + case BINDINGPATTERN: + patternPrimaryType = new PatternPrimaryType(((JCBindingPattern) pat).type, true); + break; + case GUARDPATTERN: { + JCGuardPattern guarded = (JCGuardPattern) pat; + PatternPrimaryType nested = primaryPatternType(guarded.patt); + boolean unconditional = nested.unconditional(); + if (guarded.expr.type.hasTag(BOOLEAN) && unconditional) { + unconditional = false; + Object constValue = guarded.expr.type.constValue(); + if (constValue != null && ((int) constValue) == 1) { + unconditional = true; + } + } + patternPrimaryType = new PatternPrimaryType(nested.type(), unconditional); + } + break; + case PARENTHESIZEDPATTERN: + patternPrimaryType = primaryPatternType(((JCParenthesizedPattern) pat).pattern); + break; + default: throw new AssertionError(); + } + return patternPrimaryType; + } + + public static JCBindingPattern primaryPatternTree(JCPattern pat) { + JCBindingPattern jcBindingPattern = null; + switch (pat.getTag()) { + case BINDINGPATTERN: jcBindingPattern = (JCBindingPattern) pat; + break; + case GUARDPATTERN: jcBindingPattern = primaryPatternTree(((JCGuardPattern) pat).patt); + break; + case PARENTHESIZEDPATTERN: jcBindingPattern = primaryPatternTree(((JCParenthesizedPattern) pat).pattern); + break; + default: throw new AssertionError(); + } + return jcBindingPattern; + } + + public static class PatternPrimaryType { + private final Type type; + private final boolean unconditional; + + public PatternPrimaryType(Type type, boolean unconditional) { + this.type = type; + this.unconditional = unconditional; + } + + public Type type() { + return type; + } + + public boolean unconditional() { + return unconditional; + } + + } + } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 6488ede..1897527 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -229,6 +229,12 @@ public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, return tree; } + public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, boolean declaredUsingVar) { + JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null, declaredUsingVar); + tree.pos = pos; + return tree; + } + public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) { JCVariableDecl tree = new JCVariableDecl(mods, name, vartype); tree.pos = pos; @@ -287,9 +293,9 @@ public JCSwitch Switch(JCExpression selector, List cases) { return tree; } - public JCCase Case(CaseTree.CaseKind caseKind, List pats, + public JCCase Case(CaseTree.CaseKind caseKind, List labels, List stats, JCTree body) { - JCCase tree = new JCCase(caseKind, pats, stats, body); + JCCase tree = new JCCase(caseKind, labels, stats, body); tree.pos = pos; return tree; } @@ -484,6 +490,24 @@ public JCBindingPattern BindingPattern(JCVariableDecl var) { return tree; } + public JCDefaultCaseLabel DefaultCaseLabel() { + JCDefaultCaseLabel tree = new JCDefaultCaseLabel(); + tree.pos = pos; + return tree; + } + + public JCParenthesizedPattern ParenthesizedPattern(JCPattern pattern) { + JCParenthesizedPattern tree = new JCParenthesizedPattern(pattern); + tree.pos = pos; + return tree; + } + + public JCGuardPattern GuardPattern(JCPattern guardedPattern, JCExpression expr) { + JCGuardPattern tree = new JCGuardPattern(guardedPattern, expr); + tree.pos = pos; + return tree; + } + public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) { JCArrayAccess tree = new JCArrayAccess(indexed, index); tree.pos = pos; @@ -998,7 +1022,7 @@ public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) { new JCMethodDecl( Modifiers(m.flags(), Annotations(m.getRawAttributes())), m.name, - Type(mtype.getReturnType()), + m.name != names.init ? Type(mtype.getReturnType()) : null, TypeParams(mtype.getTypeArguments()), null, // receiver type Params(mtype.getParameterTypes(), m), diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java index 3d64c1f..ffdb2ea 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java @@ -177,7 +177,7 @@ public void visitSwitch(JCSwitch tree) { } public void visitCase(JCCase tree) { - scan(tree.pats); + scan(tree.labels); scan(tree.stats); } @@ -307,6 +307,21 @@ public void visitBindingPattern(JCBindingPattern tree) { scan(tree.var); } + @Override + public void visitDefaultCaseLabel(JCDefaultCaseLabel tree) { + } + + @Override + public void visitParenthesizedPattern(JCParenthesizedPattern that) { + scan(that.pattern); + } + + @Override + public void visitGuardPattern(JCGuardPattern that) { + scan(that.patt); + scan(that.expr); + } + public void visitIndexed(JCArrayAccess tree) { scan(tree.indexed); scan(tree.index); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java index b6a5d6d..1796b4d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java @@ -207,7 +207,7 @@ public void visitSwitch(JCSwitch tree) { } public void visitCase(JCCase tree) { - tree.pats = translate(tree.pats); + tree.labels = translate(tree.labels); tree.stats = translate(tree.stats); result = tree; } @@ -363,6 +363,24 @@ public void visitBindingPattern(JCBindingPattern tree) { result = tree; } + @Override + public void visitDefaultCaseLabel(JCDefaultCaseLabel tree) { + result = tree; + } + + @Override + public void visitParenthesizedPattern(JCParenthesizedPattern tree) { + tree.pattern = translate(tree.pattern); + result = tree; + } + + @Override + public void visitGuardPattern(JCGuardPattern tree) { + tree.patt = translate(tree.patt); + tree.expr = translate(tree.expr); + result = tree; + } + public void visitIndexed(JCArrayAccess tree) { tree.indexed = translate(tree.indexed); tree.index = translate(tree.index); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java index 3db7f41..7660a5d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2021, 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 @@ -149,7 +149,7 @@ public String formatSource(JCDiagnostic d, boolean fullname, Locale l) { if (fullname) return fo.getName(); else if (fo instanceof PathFileObject) - return ((PathFileObject) fo).getShortName(); + return ((PathFileObject)fo).getShortName(); else return PathFileObject.getSimpleName(fo); } @@ -403,7 +403,7 @@ public SimpleConfiguration getConfiguration() { return config; } - static public class SimpleConfiguration implements Configuration { + public static class SimpleConfiguration implements Configuration { protected Map multilineLimits; protected EnumSet visibleParts; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java index d6c9834..226c73d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java @@ -215,7 +215,7 @@ public BasicConfiguration getConfiguration() { return (BasicConfiguration)super.getConfiguration(); } - static public class BasicConfiguration extends SimpleConfiguration { + public static class BasicConfiguration extends SimpleConfiguration { protected Map indentationLevels; protected Map availableFormats; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java index 061a25d..388adf6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Bits.java @@ -84,6 +84,7 @@ static BitsState getState(int[] someBits, boolean reset) { } + public enum BitsOpKind { INIT, CLEAR, @@ -102,6 +103,7 @@ public enum BitsOpKind { private final static int wordshift = 5; private final static int wordmask = wordlen - 1; + public int[] bits = null; // This field will store last version of bits after every change. private static final int[] unassignedBits = new int[0]; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constants.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constants.java index 30753d7..92a98aa 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constants.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -45,7 +45,7 @@ public class Constants { */ public static Object decode(Object value, Type type) { if (value instanceof Integer) { - int i = (Integer) value; + int i = (Integer)value; switch (type.getTag()) { case BOOLEAN: return i != 0; case CHAR: return (char) i; @@ -70,7 +70,7 @@ public static String format(Object value, Type type) { case CHAR: return formatChar((Character) value); } if (value instanceof String) - return formatString((String) value); + return formatString((String)value); return value + ""; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Context.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Context.java index e12a117..cc098b7 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Context.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Context.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java index 8fcf026..ee358c1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, 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 @@ -78,12 +78,12 @@ protected Dependencies(Context context) { /** * Push a new completion node on the stack. */ - abstract public void push(ClassSymbol s, CompletionCause phase); + public abstract void push(ClassSymbol s, CompletionCause phase); /** * Remove current dependency node from the stack. */ - abstract public void pop(); + public abstract void pop(); public enum CompletionCause implements GraphUtils.DependencyKind { CLASS_READER, @@ -202,7 +202,7 @@ void addDependency(DependencyKind depKind, Node dep) { @Override public boolean equals(Object obj) { - return obj instanceof Node && data.equals(((Node) obj).data); + return obj instanceof Node && data.equals(((Node)obj).data); } @Override @@ -402,7 +402,7 @@ private FilterVisitor(CompletionNode.Kind ck) { @Override public void visitNode(Node node, Void arg) { if (node instanceof CompletionNode) { - if (((CompletionNode) node).ck != ck) { + if (((CompletionNode)node).ck != ck) { dependencyNodeMap.remove(node.data); } } @@ -411,7 +411,7 @@ public void visitNode(Node node, Void arg) { @Override public void visitDependency(GraphUtils.DependencyKind dk, Node from, Node to, Void arg) { if (to instanceof CompletionNode) { - if (((CompletionNode) to).ck != ck) { + if (((CompletionNode)to).ck != ck) { from.depsByKind.get(dk).remove(to); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java index 11710f4..ddb05ca 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/DiagnosticSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -185,9 +185,9 @@ protected char[] initBuf(JavaFileObject fileObject) throws IOException { char[] buf; CharSequence cs = fileObject.getCharContent(true); if (cs instanceof CharBuffer) { - CharBuffer cb = (CharBuffer) cs; - buf = JavacFileManager.toArray(cb); - bufLen = cb.limit(); + CharBuffer charBuffer = (CharBuffer)cs; + buf = JavacFileManager.toArray(charBuffer); + bufLen = charBuffer.limit(); } else { buf = cs.toString().toCharArray(); bufLen = buf.length; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java index b5ef52e..409dc70 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/IntHashTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, 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 @@ -40,7 +40,7 @@ public class IntHashTable { protected int[] ints; // the image set protected int mask; // used to clip int's into the domain protected int num_bindings; // the number of mappings (including DELETED) - private final static Object DELETED = new Object(); + private static final Object DELETED = new Object(); /** * Construct an Object {@literal ->} int hash table. @@ -74,20 +74,20 @@ public IntHashTable(int capacity) { * @param key The object whose hash code is to be computed. * @return zero if the object is null, otherwise the identityHashCode */ - public int hash(Object key) { + protected int hash(Object key) { return System.identityHashCode(key); } /** * Find either the index of a key's value, or the index of an available space. * - * @param key The key to whose value you want to find. - * @param hash The hash code of this key. + * @param key The key to whose index you want to find. * @return Either the index of the key's value, or an index pointing to * unoccupied space. */ - public int lookup(Object key, int hash) { + protected int lookup(Object key) { Object node; + int hash = hash(key); int hash1 = hash ^ (hash >>> 15); int hash2 = (hash ^ (hash << 6)) | 1; //ensure coprimeness int deleted = -1; @@ -103,24 +103,14 @@ public int lookup(Object key, int hash) { } /** - * Lookup a given key's value in the hash table. - * - * @param key The key whose value you want to find. - * @return Either the index of the key's value, or an index pointing to - * unoccupied space. - */ - public int lookup(Object key) { - return lookup(key, hash(key)); - } - - /** - * Return the value stored at the specified index in the table. + * Return the value to which the specified key is mapped. * - * @param index The index to inspect, as returned from {@link #lookup} - * @return A non-negative integer if the index contains a non-null - * value, or -1 if it does. + * @param key The key to whose value you want to find. + * @return A non-negative integer if the value is found. + * Otherwise, it is -1. */ - public int getFromIndex(int index) { + public int get(Object key) { + int index = lookup(key); Object node = objs[index]; return node == null || node == DELETED ? -1 : ints[index]; } @@ -130,12 +120,11 @@ public int getFromIndex(int index) { * * @param key key with which the specified value is to be associated. * @param value value to be associated with the specified key. - * @param index the index at which to place this binding, as returned - * from {@link #lookup}. * @return previous value associated with specified key, or -1 if there was * no mapping for key. */ - public int putAtIndex(Object key, int value, int index) { + public int put(Object key, int value) { + int index = lookup(key); Object old = objs[index]; if (old == null || old == DELETED) { objs[index] = key; @@ -152,6 +141,13 @@ public int putAtIndex(Object key, int value, int index) { } } + /** + * Remove the mapping(key and value) of the specified key. + * + * @param key the key to whose value you want to remove. + * @return the removed value associated with the specified key, + * or -1 if there was no mapping for the specified key. + */ public int remove(Object key) { int index = lookup(key); Object old = objs[index]; @@ -169,20 +165,16 @@ public int remove(Object key) { protected void rehash() { Object[] oldObjsTable = objs; int[] oldIntsTable = ints; - int oldCapacity = oldObjsTable.length; - int newCapacity = oldCapacity << 1; - Object[] newObjTable = new Object[newCapacity]; - int[] newIntTable = new int[newCapacity]; - int newMask = newCapacity - 1; - objs = newObjTable; - ints = newIntTable; - mask = newMask; + int newCapacity = oldObjsTable.length << 1; + objs = new Object[newCapacity]; + ints = new int[newCapacity]; + mask = newCapacity - 1; num_bindings = 0; // this is recomputed below Object key; for (int i = oldIntsTable.length; --i >= 0;) { key = oldObjsTable[i]; if (key != null && key != DELETED) - putAtIndex(key, oldIntsTable[i], lookup(key, hash(key))); + put(key, oldIntsTable[i]); } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java index d8ecd37..9101b16 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java @@ -83,7 +83,7 @@ private void update() { } @SuppressWarnings("rawtypes") - private final static Iterator EMPTY = new Iterator() { + private static final Iterator EMPTY = new Iterator() { public boolean hasNext() { return false; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java index 1e7b183..69fbc90 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JavacMessages.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JavacMessages.java index 17b12c0..de4444e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JavacMessages.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JavacMessages.java @@ -210,7 +210,7 @@ public static ResourceBundle getDefaultBundle() { } } - static private String getLocalizedString(List bundles, + private static String getLocalizedString(List bundles, String key, Object... args) { String msg = null; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/LayoutCharacters.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/LayoutCharacters.java index 0558328..6315a98 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/LayoutCharacters.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/LayoutCharacters.java @@ -37,37 +37,37 @@ public interface LayoutCharacters { /** Tabulator column increment. */ - final static int TabInc = 8; + static final int TabInc = 8; /** Standard indentation for subdiagnostics */ - final static int DiagInc = 4; + static final int DiagInc = 4; /** Standard indentation for additional diagnostic lines */ - final static int DetailsInc = 2; + static final int DetailsInc = 2; /** Tabulator character. */ - final static byte TAB = 0x9; + static final byte TAB = 0x9; /** Line feed character. */ - final static byte LF = 0xA; + static final byte LF = 0xA; /** Form feed character. */ - final static byte FF = 0xC; + static final byte FF = 0xC; /** Carriage return character. */ - final static byte CR = 0xD; + static final byte CR = 0xD; /** End of input character. Used as a sentinel to denote the * character one beyond the last defined character in a * source file. */ - final static byte EOI = 0x1A; + static final byte EOI = 0x1A; /** Bump column to the next tab. */ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java index 9c9bfe8..51de4ab 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java index be1436d..d1be97b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -136,13 +136,13 @@ public void report(JCDiagnostic diag) { } public static class DeferredDiagnosticHandler extends DiagnosticHandler { private Queue deferred = new ListBuffer<>(); private Throwable t; - private final Filter filter; + private final Predicate filter; public DeferredDiagnosticHandler(Log log) { this(log, null); } - public DeferredDiagnosticHandler(Log log, Filter filter) { + public DeferredDiagnosticHandler(Log log, Predicate filter) { this.filter = filter; install(log); } @@ -150,7 +150,7 @@ public DeferredDiagnosticHandler(Log log, Filter filter) { @Override public void report(JCDiagnostic diag) { if (!diag.isFlagSet(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE) && - (filter == null || filter.accepts(diag))) { + (filter == null || filter.test(diag))) { deferred.add(diag); } else { prev.report(diag); @@ -323,40 +323,6 @@ private static Map initWriters(PrintWriter out, PrintWr return writers; } - /** - * Construct a log with given I/O redirections. - * @deprecated - * This constructor is provided to support the supported but now-deprecated javadoc entry point - * com.sun.tools.javadoc.Main.execute(String programName, - * PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter, - * String defaultDocletClassName, String... args) - */ - @Deprecated - protected Log(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { - this(context, initWriters(errWriter, warnWriter, noticeWriter)); - } - - /** - * Initialize a writer map with different streams for different types of diagnostics. - * @param errWriter a stream for writing error messages - * @param warnWriter a stream for writing warning messages - * @param noticeWriter a stream for writing notice messages - * @return a map of writers - * @deprecated This method exists to support a supported but now deprecated javadoc entry point. - */ - @Deprecated - private static Map initWriters(PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) { - Map writers = new EnumMap<>(WriterKind.class); - writers.put(WriterKind.ERROR, errWriter); - writers.put(WriterKind.WARNING, warnWriter); - writers.put(WriterKind.NOTICE, noticeWriter); - - writers.put(WriterKind.STDOUT, noticeWriter); - writers.put(WriterKind.STDERR, errWriter); - - return writers; - } - /** * Creates a log. * @param context the context in which the log should be registered @@ -604,7 +570,7 @@ private List getCode(JCDiagnostic d) { private void getCodeRecursive(ListBuffer buf, JCDiagnostic d) { buf.add(d.getCode()); for (Object o : d.getArgs()) { - if (o instanceof JCDiagnostic) { + if (o instanceof JCDiagnostic) { getCodeRecursive(buf, (JCDiagnostic)o); } } @@ -830,7 +796,6 @@ protected void writeDiagnostic(JCDiagnostic diag) { writer.flush(); } - @Deprecated protected PrintWriter getWriterForDiagnosticType(DiagnosticType dt) { switch (dt) { case FRAGMENT: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java index 51b2d24..9fe9590 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java @@ -31,6 +31,7 @@ import javax.tools.JavaFileObject; import com.sun.tools.javac.code.Lint.LintCategory; +import com.sun.tools.javac.code.Source; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.Note; import com.sun.tools.javac.util.JCDiagnostic.Warning; @@ -111,10 +112,11 @@ private enum DeferredDiagnosticKind { * the messages that may be generated. * @param lc An associated lint category for the warnings, or null if none. */ - public MandatoryWarningHandler(Log log, boolean verbose, + public MandatoryWarningHandler(Log log, Source source, boolean verbose, boolean enforceMandatory, String prefix, LintCategory lc) { this.log = log; + this.source = source; this.verbose = verbose; this.prefix = prefix; this.enforceMandatory = enforceMandatory; @@ -173,10 +175,19 @@ public void report(DiagnosticPosition pos, Warning warnKey) { */ public void reportDeferredDiagnostic() { if (deferredDiagnosticKind != null) { - if (deferredDiagnosticArg == null) - logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix)); - else - logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg); + if (deferredDiagnosticArg == null) { + if (source != null) { + logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), source); + } else { + logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix)); + } + } else { + if (source != null) { + logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg, source); + } else { + logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg); + } + } if (!verbose) logMandatoryNote(deferredDiagnosticSource, prefix + ".recompile"); @@ -187,6 +198,7 @@ public void reportDeferredDiagnostic() { * The log to which to report warnings. */ private final Log log; + private final Source source; /** * Whether or not to report individual warnings, or simply to report a diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java index f3d84ee..3e47705 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -87,7 +87,7 @@ public static Names instance(Context context) { public final Name error; public final Name finalize; public final Name forRemoval; - public final Name essentialAPI; + public final Name reflective; public final Name getClass; public final Name hasNext; public final Name hashCode; @@ -118,6 +118,7 @@ public static Names instance(Context context) { public final Name Method; // package names + public final Name java; public final Name java_lang; // module names @@ -215,6 +216,10 @@ public static Names instance(Context context) { public final Name permits; public final Name sealed; + // pattern switches + public final Name typeSwitch; + public final Name enumSwitch; + public final Name.Table table; public Names(Context context) { @@ -260,7 +265,7 @@ public Names(Context context) { error = fromString(""); finalize = fromString("finalize"); forRemoval = fromString("forRemoval"); - essentialAPI = fromString("essentialAPI"); + reflective = fromString("reflective"); getClass = fromString("getClass"); hasNext = fromString("hasNext"); hashCode = fromString("hashCode"); @@ -292,6 +297,7 @@ public Names(Context context) { Method = fromString("Method"); // package names + java = fromString("java"); java_lang = fromString("java.lang"); // module names @@ -383,6 +389,10 @@ record = fromString("record"); // sealed types permits = fromString("permits"); sealed = fromString("sealed"); + + // pattern switches + typeSwitch = fromString("typeSwitch"); + enumSwitch = fromString("enumSwitch"); } protected Name.Table createTable(Context context) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Pair.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Pair.java index c70c876..3b2f544 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Pair.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Pair.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java index 2305f8f..4203734 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RawDiagnosticFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2021, 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 @@ -28,14 +28,18 @@ import java.util.Collection; import java.util.EnumSet; import java.util.Locale; +import java.util.Set; import javax.tools.JavaFileObject; import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*; import com.sun.tools.javac.api.Formattable; +import com.sun.tools.javac.code.Source; import com.sun.tools.javac.file.PathFileObject; import com.sun.tools.javac.tree.JCTree.*; import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*; +import java.util.Arrays; +import java.util.HashSet; /** * A raw formatter for diagnostic messages. @@ -150,7 +154,7 @@ public String formatMessage(JCDiagnostic d, Locale l) { @Override protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) { - String s; + String s; if (arg instanceof Formattable) { s = arg.toString(); } else if (arg instanceof JCExpression) { @@ -165,6 +169,8 @@ protected String formatArgument(JCDiagnostic diag, Object arg, Locale l) { } return (arg instanceof JCDiagnostic) ? "(" + s + ")" : s; } + //where: + private static final Set CODES_NEEDING_SOURCE_NORMALIZATION = new HashSet<>(Arrays.asList("compiler.note.preview.filename","compiler.note.preview.plural")); @Override protected String localize(Locale l, String key, Object... args) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index 565372e..feb0793 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/SharedNameTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/SharedNameTable.java index 74bcde7..8f2a6e8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/SharedNameTable.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/SharedNameTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -43,7 +43,11 @@ public class SharedNameTable extends Name.Table { // maintain a freelist of recently used name tables for reuse. private static List> freelist = List.nil(); + static public synchronized SharedNameTable create(Names names, Context context) { + + + while (freelist.nonEmpty()) { SharedNameTable t = freelist.head.get(); freelist = freelist.tail; @@ -54,7 +58,7 @@ static public synchronized SharedNameTable create(Names names, Context context) return new SharedNameTable(names, context); } - static private synchronized void dispose(SharedNameTable t) { + private static synchronized void dispose(SharedNameTable t) { freelist = freelist.prepend(new SoftReference<>(t)); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java index b0a8ab4..3bc28ae 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, 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 @@ -38,8 +38,10 @@ * deletion without notice. */ public class UnsharedNameTable extends Name.Table { + static public Name.Table create(Names names, Context context) { return new UnsharedNameTable(names, context); + } static class HashEntry extends WeakReference { @@ -96,10 +98,6 @@ public Name fromUtf(byte[] cs, int start, int len) { HashEntry firstTableEntry = element; while (element != null) { - if (element == null) { - break; - } - n = element.get(); if (n == null) { diff --git a/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java b/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java index b6c11c9..afc10d0 100644 --- a/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java +++ b/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -593,6 +593,7 @@ public Object scan(DocTree node, Object p) { private void reflowTillNow() { while (result.length() > 0 && result.charAt(result.length() - 1) == ' ') result.delete(result.length() - 1, result.length()); + reflownTo = Math.min(reflownTo, result.length()); reflow(result, reflownTo, indent, limit); reflownTo = result.length(); } diff --git a/src/jdk.compiler/share/man/javac.1 b/src/jdk.compiler/share/man/javac.1 index b6316ab..8782020 100644 --- a/src/jdk.compiler/share/man/javac.1 +++ b/src/jdk.compiler/share/man/javac.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVAC" "1" "2021" "JDK 16" "JDK Commands" +.TH "JAVAC" "1" "2021" "JDK 17\-ea" "JDK Commands" .hy .SH NAME .PP @@ -631,11 +631,6 @@ As applicable, see the descriptions in \f[B]\f[BC]\-\-release\f[B]\f[R], details. .RE .TP -.B \f[CB]\-\-doclint\-format\f[R] [\f[CB]html4\f[R]|\f[CB]html5\f[R]] -Specifies the format for documentation comments. -.RS -.RE -.TP .B \f[CB]\-\-patch\-module\f[R] \f[I]module\f[R]\f[CB]=\f[R]\f[I]path\f[R] Overrides or augments a module with classes and resources in JAR files or directories. diff --git a/src/jdk.compiler/share/man/serialver.1 b/src/jdk.compiler/share/man/serialver.1 index c051ec8..c1ec3eb 100644 --- a/src/jdk.compiler/share/man/serialver.1 +++ b/src/jdk.compiler/share/man/serialver.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "SERIALVER" "1" "2021" "JDK 16" "JDK Commands" +.TH "SERIALVER" "1" "2021" "JDK 17\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Instruction.java b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Instruction.java index 14d080b..0f5f15e 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Instruction.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Instruction.java @@ -285,6 +285,8 @@ public R accept(KindVisitor visitor, P p) { int default_ = getInt(pad); int low = getInt(pad + 4); int high = getInt(pad + 8); + if (low > high) + throw new IllegalStateException(); int[] values = new int[high - low + 1]; for (int i = 0; i < values.length; i++) values[i] = getInt(pad + 12 + 4 * i); @@ -295,6 +297,8 @@ public R accept(KindVisitor visitor, P p) { int pad = align(pc + 1) - pc; int default_ = getInt(pad); int npairs = getInt(pad + 4); + if (npairs < 0) + throw new IllegalStateException(); int[] matches = new int[npairs]; int[] offsets = new int[npairs]; for (int i = 0; i < npairs; i++) { diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java index 8ae4502..ccd0ea5 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java @@ -229,6 +229,8 @@ else if (classFile.isInterface()) } } catch (ConstantPoolException e) { print(report(e)); + } catch (IllegalStateException e) { + report("Invalid value for Signature attribute: " + e.getMessage()); } } @@ -500,7 +502,7 @@ protected void writeMethod(Method m) { methodExceptions = methodType.throwsTypes; if (methodExceptions != null && methodExceptions.isEmpty()) methodExceptions = null; - } catch (ConstantPoolException e) { + } catch (ConstantPoolException | IllegalStateException e) { // report error? // fall back on standard descriptor methodType = null; diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java index be58570..9d1e66f 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java @@ -106,7 +106,7 @@ public void writeInstrs(Code_attribute attr) { for (InstructionDetailWriter w: detailWriters) w.writeDetails(instr); writeInstr(instr); - } catch (ArrayIndexOutOfBoundsException e) { + } catch (ArrayIndexOutOfBoundsException | IllegalStateException e) { println(report("error at or after byte " + instr.getPC())); break; } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java index 2f8e61e..c67510d 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java @@ -166,7 +166,7 @@ boolean doClassNames(Collection classNames) throws IOException { if (forRemoval) { deprList = proc.getDeprecations().stream() .filter(DeprData::isForRemoval) - .collect(toList()); + .toList(); } else { deprList = proc.getDeprecations(); } @@ -190,7 +190,7 @@ boolean doFileNames(Stream filenames) throws IOException { .filter(name -> !name.endsWith("module-info.class")) .map(s -> s.replaceAll("\\.class$", "")) .map(s -> s.replace(File.separatorChar, '.')) - .collect(toList())); + .toList()); } /** @@ -227,7 +227,7 @@ boolean doModularFileNames(Stream filenames) throws IOException { .filter(name -> !name.endsWith("module-info.class")) .map(s -> s.replaceAll("\\.class$", "")) .map(this::convertModularFileName) - .collect(toList())); + .toList()); } /** @@ -406,7 +406,7 @@ boolean processRelease(String release, Collection classes) throws IOExce types.values().stream() .flatMap(List::stream) .map(TypeElement::toString) - .collect(toList())); + .toList()); } else { JDKPlatformProvider pp = new JDKPlatformProvider(); if (StreamSupport.stream(pp.getSupportedPlatformNames().spliterator(), @@ -677,7 +677,7 @@ boolean run(String... argArray) { DeprDB db = DeprDB.loadFromList(deprList); List cp = classPath.stream() .map(File::toString) - .collect(toList()); + .toList(); Scan scan = new Scan(out, err, cp, db, verbose); for (String a : args) { diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java index 408e797..671c3a3 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/scan/Scan.java @@ -635,7 +635,7 @@ public boolean scanDir(String dirname) { .filter(path -> path.toString().endsWith(".class")) .filter(path -> !path.toString().endsWith("package-info.class")) .filter(path -> !path.toString().endsWith("module-info.class")) - .collect(Collectors.toList()); + .toList(); out.println(Messages.get("scan.head.dir", dirname)); diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Analyzer.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Analyzer.java index 952180a..2e93ea1 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Analyzer.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Analyzer.java @@ -405,6 +405,14 @@ private Jdk8Internals() { } } + /* + * Ignore the module name which should not be shown in the output + */ + @Override + public String name() { + return getName(); + } + public boolean contains(Location location) { String cn = location.getClassName(); int i = cn.lastIndexOf('.'); diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java index e0a3ec1..1c4df79 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ClassFileReader.java @@ -260,8 +260,8 @@ class DirectoryIterator implements Iterator { DirectoryIterator() throws IOException { List paths = null; try (Stream stream = Files.walk(path, Integer.MAX_VALUE)) { - paths = stream.filter(ClassFileReader::isClass) - .collect(Collectors.toList()); + paths = stream.filter(ClassFileReader::isClass).toList(); + } this.entries = paths; this.index = 0; diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsWriter.java index 0f73673..1d3f7f0 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsWriter.java @@ -312,7 +312,7 @@ public void printModuleDescriptor(Module module) { * For non-JDK archives, this method returns the file name of the archive. */ String toTag(Archive source, String name, Archive target) { - if (source == target || !target.getModule().isNamed()) { + if (source == target || !target.getModule().isNamed() || Analyzer.notFound(target)) { return target.getName(); } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java index 94fba26..f077b4a 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java @@ -78,7 +78,7 @@ public ModuleInfoBuilder(JdepsConfiguration configuration, // add targets to modulepath if it has module-info.class List paths = args.stream() .map(fn -> Paths.get(fn)) - .collect(toList()); + .toList(); // automatic module to convert to normal module this.automaticToNormalModule = ModuleFinder.of(paths.toArray(new Path[0])) diff --git a/src/jdk.jdeps/share/classes/java/lang/annotation/ElementType.java b/src/jdk.jdeps/share/classes/java/lang/annotation/ElementType.java index 9ae42e2..99fd766 100644 --- a/src/jdk.jdeps/share/classes/java/lang/annotation/ElementType.java +++ b/src/jdk.jdeps/share/classes/java/lang/annotation/ElementType.java @@ -117,23 +117,6 @@ public enum ElementType { */ MODULE, - /** - * {@preview Associated with records, a preview feature of the Java language. - * - * This constant is associated with records, a preview - * feature of the Java language. Programs can only use this - * constant when preview features are enabled. Preview features - * may be removed in a future release, or upgraded to permanent - * features of the Java language.} - * - * Record component - * - * @jls 8.10.3 Record Members - * @jls 9.7.4 Where Annotations May Appear - * - * @since 14 - */ - @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS, - essentialAPI=true) + RECORD_COMPONENT; } diff --git a/src/jdk.jdeps/share/classes/jdk/internal/PreviewFeature.java b/src/jdk.jdeps/share/classes/jdk/internal/PreviewFeature.java index d2ce991..117587a 100644 --- a/src/jdk.jdeps/share/classes/jdk/internal/PreviewFeature.java +++ b/src/jdk.jdeps/share/classes/jdk/internal/PreviewFeature.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 @@ -25,23 +25,28 @@ package jdk.internal; -//import java.lang.annotation.ElementType; import java.lang.annotation.Target; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; + /** * Indicates the API declaration in question is associated with a * preview feature. See JEP 12: "Preview Language and VM * Features" (http://openjdk.java.net/jeps/12). + * + * Note this internal annotation is handled specially by the javac compiler. + * To work properly with {@code --release older-release}, it requires special + * handling in {@code make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java} + * and {@code src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java}. + * * @since 14 */ // Match the meaningful targets of java.lang.Deprecated, omit local // variables and parameter declarations @Target({java.lang.annotation.ElementType.METHOD, - java.lang.annotation.ElementType.CONSTRUCTOR, - java.lang.annotation.ElementType.FIELD, + java.lang.annotation.ElementType.CONSTRUCTOR, + java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.PACKAGE, - //java.lang.annotation.ElementType.MODULE, java.lang.annotation.ElementType.TYPE}) // CLASS retention will hopefully be sufficient for the purposes at hand @Retention(RetentionPolicy.CLASS) @@ -53,13 +58,14 @@ */ public Feature feature(); - public boolean essentialAPI() default false; + public boolean reflective() default false; public enum Feature { - PATTERN_MATCHING_IN_INSTANCEOF, - TEXT_BLOCKS, - RECORDS, - SEALED_CLASSES + SWITCH_PATTERN_MATCHING, + /** + * A key for testing. + */ + TEST, ; } -} +} \ No newline at end of file diff --git a/src/jdk.jdeps/share/man/javap.1 b/src/jdk.jdeps/share/man/javap.1 index 153448b..e198239 100644 --- a/src/jdk.jdeps/share/man/javap.1 +++ b/src/jdk.jdeps/share/man/javap.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVAP" "1" "2021" "JDK 16" "JDK Commands" +.TH "JAVAP" "1" "2021" "JDK 17\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/jdeprscan.1 b/src/jdk.jdeps/share/man/jdeprscan.1 index 67f46c9..53db858 100644 --- a/src/jdk.jdeps/share/man/jdeprscan.1 +++ b/src/jdk.jdeps/share/man/jdeprscan.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDEPRSCAN" "1" "2021" "JDK 16" "JDK Commands" +.TH "JDEPRSCAN" "1" "2021" "JDK 17\-ea" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/jdeps.1 b/src/jdk.jdeps/share/man/jdeps.1 index 1ca6c7e..46056c7 100644 --- a/src/jdk.jdeps/share/man/jdeps.1 +++ b/src/jdk.jdeps/share/man/jdeps.1 @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDEPS" "1" "2021" "JDK 16" "JDK Commands" +.TH "JDEPS" "1" "2021" "JDK 17\-ea" "JDK Commands" .hy .SH NAME .PP