mirror of
https://github.com/openjdk/jdk.git
synced 2026-08-03 22:55:40 +00:00
Initial prototype for JDK-8348611.
This commit is contained in:
parent
6ff5e73044
commit
de2d3abe26
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, 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
|
||||
@ -412,6 +412,7 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
f.run(compiler.todo, classes);
|
||||
}
|
||||
} finally {
|
||||
compiler.log.reportOutstandingWarnings();
|
||||
compiler.log.flush();
|
||||
}
|
||||
return results;
|
||||
@ -483,8 +484,10 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (compiler != null)
|
||||
if (compiler != null) {
|
||||
compiler.log.reportOutstandingWarnings();
|
||||
compiler.log.flush();
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@ import com.sun.tools.javac.tree.JCTree.LetExpr;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.DefinedBy;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
import com.sun.tools.javac.util.LintMapper;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
|
||||
@ -268,12 +269,11 @@ public class JavacTaskPool {
|
||||
if (ht.get(Log.logKey) instanceof ReusableLog) {
|
||||
//log already inited - not first round
|
||||
Log.instance(this).clear();
|
||||
LintMapper.instance(this).clear();
|
||||
Enter.instance(this).newRound();
|
||||
((ReusableJavaCompiler)ReusableJavaCompiler.instance(this)).clear();
|
||||
Types.instance(this).newRound();
|
||||
Check.instance(this).newRound();
|
||||
Check.instance(this).clear(); //clear mandatory warning handlers
|
||||
Preview.instance(this).clear(); //clear mandatory warning handlers
|
||||
Modules.instance(this).newRound();
|
||||
Annotate.instance(this).newRound();
|
||||
CompileStates.instance(this).clear();
|
||||
|
||||
@ -360,9 +360,14 @@ public class JavacTrees extends DocTrees {
|
||||
Log.DeferredDiagnosticHandler deferredDiagnosticHandler = log.new DeferredDiagnosticHandler();
|
||||
try {
|
||||
Env<AttrContext> env = getAttrContext(path.getTreePath());
|
||||
Type t = attr.attribType(dcReference.qualifierExpression, env);
|
||||
if (t != null && !t.isErroneous()) {
|
||||
return t;
|
||||
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
Type t = attr.attribType(dcReference.qualifierExpression, env);
|
||||
if (t != null && !t.isErroneous()) {
|
||||
return t;
|
||||
}
|
||||
} finally {
|
||||
log.useSource(prevSource);
|
||||
}
|
||||
} catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
|
||||
return null;
|
||||
@ -388,6 +393,7 @@ public class JavacTrees extends DocTrees {
|
||||
return null;
|
||||
}
|
||||
Log.DeferredDiagnosticHandler deferredDiagnosticHandler = log.new DeferredDiagnosticHandler();
|
||||
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
final TypeSymbol tsym;
|
||||
final Name memberName;
|
||||
@ -509,6 +515,7 @@ public class JavacTrees extends DocTrees {
|
||||
} catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
|
||||
return null;
|
||||
} finally {
|
||||
log.useSource(prevSource);
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2025, 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.tools.javac.code;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.Tag;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
|
||||
/**
|
||||
* Holds pending {@link Lint} warnings until the {@lint Lint} instance associated with the containing
|
||||
* module, package, class, method, or variable declaration is known so that {@link @SupressWarnings}
|
||||
* suppressions may be applied.
|
||||
*
|
||||
* <p>
|
||||
* Warnings are regsistered at any time prior to attribution via {@link #report}. The warning will be
|
||||
* associated with the declaration placed in context by the most recent invocation of {@link #push push()}
|
||||
* not yet {@link #pop}'d. Warnings are actually emitted later, during attribution, via {@link #flush}.
|
||||
*
|
||||
* <p>
|
||||
* There is also an "immediate" mode, where warnings are emitted synchronously; see {@link #pushImmediate}.
|
||||
*
|
||||
* <p>
|
||||
* Deferred warnings are grouped by the innermost containing module, package, class, method, or variable
|
||||
* declaration (represented by {@link JCTree} nodes), so that the corresponding {@link Lint} configuration
|
||||
* can be applied when the warning is eventually generated.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class DeferredLintHandler {
|
||||
|
||||
protected static final Context.Key<DeferredLintHandler> deferredLintHandlerKey = new Context.Key<>();
|
||||
|
||||
public static DeferredLintHandler instance(Context context) {
|
||||
DeferredLintHandler instance = context.get(deferredLintHandlerKey);
|
||||
if (instance == null)
|
||||
instance = new DeferredLintHandler(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registered {@link LintLogger}s grouped by the innermost containing module, package, class,
|
||||
* method, or variable declaration.
|
||||
*/
|
||||
private final HashMap<JCTree, ArrayList<LintLogger>> deferralMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The current "reporter" stack, reflecting calls to {@link #push} and {@link #pop}.
|
||||
*
|
||||
* <p>
|
||||
* The top of the stack determines how calls to {@link #report} are handled.
|
||||
*/
|
||||
private final ArrayDeque<Consumer<LintLogger>> reporterStack = new ArrayDeque<>();
|
||||
|
||||
@SuppressWarnings("this-escape")
|
||||
protected DeferredLintHandler(Context context) {
|
||||
context.put(deferredLintHandlerKey, this);
|
||||
Lint rootLint = Lint.instance(context);
|
||||
pushImmediate(rootLint); // default to "immediate" mode
|
||||
}
|
||||
|
||||
// LintLogger
|
||||
|
||||
/**An interface for deferred lint reporting - loggers passed to
|
||||
* {@link #report(LintLogger) } will be called when
|
||||
* {@link #flush(DiagnosticPosition) } is invoked.
|
||||
*/
|
||||
public interface LintLogger {
|
||||
|
||||
/**
|
||||
* Generate a warning if appropriate.
|
||||
*
|
||||
* @param lint the applicable lint configuration
|
||||
*/
|
||||
void report(Lint lint);
|
||||
}
|
||||
|
||||
// Reporter Stack
|
||||
|
||||
/**
|
||||
* Defer {@link #report}ed warnings until the given declaration is flushed.
|
||||
*
|
||||
* @param decl module, package, class, method, or variable declaration
|
||||
* @see #pop
|
||||
*/
|
||||
public void push(JCTree decl) {
|
||||
Assert.check(decl.getTag() == Tag.MODULEDEF
|
||||
|| decl.getTag() == Tag.PACKAGEDEF
|
||||
|| decl.getTag() == Tag.CLASSDEF
|
||||
|| decl.getTag() == Tag.METHODDEF
|
||||
|| decl.getTag() == Tag.VARDEF);
|
||||
reporterStack.push(logger -> deferralMap
|
||||
.computeIfAbsent(decl, s -> new ArrayList<>())
|
||||
.add(logger));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter "immediate" mode so that {@link #report}ed warnings are emitted synchonously.
|
||||
*
|
||||
* @param lint lint configuration to use for reported warnings
|
||||
*/
|
||||
public void pushImmediate(Lint lint) {
|
||||
reporterStack.push(logger -> logger.report(lint));
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert to the previous configuration in effect prior to the most recent invocation
|
||||
* of {@link #push} or {@link #pushImmediate}.
|
||||
*
|
||||
* @see #pop
|
||||
*/
|
||||
public void pop() {
|
||||
Assert.check(reporterStack.size() > 1); // the bottom stack entry should never be popped
|
||||
reporterStack.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a warning.
|
||||
*
|
||||
* <p>
|
||||
* In immediate mode, the warning is emitted synchronously. Otherwise, the warning is emitted later
|
||||
* when the current declaration is flushed.
|
||||
*/
|
||||
public void report(LintLogger logger) {
|
||||
Assert.check(!reporterStack.isEmpty());
|
||||
reporterStack.peek().accept(logger);
|
||||
}
|
||||
|
||||
// Warning Flush
|
||||
|
||||
/**
|
||||
* Emit deferred warnings encompassed by the given declaration.
|
||||
*
|
||||
* @param decl module, package, class, method, or variable declaration
|
||||
* @param lint lint configuration corresponding to {@code decl}
|
||||
*/
|
||||
public void flush(JCTree decl, Lint lint) {
|
||||
Optional.of(decl)
|
||||
.map(deferralMap::remove)
|
||||
.stream()
|
||||
.flatMap(ArrayList::stream)
|
||||
.forEach(logger -> logger.report(lint));
|
||||
}
|
||||
}
|
||||
@ -370,11 +370,8 @@ public class Lint {
|
||||
|
||||
/**
|
||||
* Warn about issues relating to use of text blocks
|
||||
*
|
||||
* <p>
|
||||
* This category is not supported by {@code @SuppressWarnings} (yet - see JDK-8224228).
|
||||
*/
|
||||
TEXT_BLOCKS("text-blocks", false),
|
||||
TEXT_BLOCKS("text-blocks"),
|
||||
|
||||
/**
|
||||
* Warn about possible 'this' escapes before subclass instance is fully initialized.
|
||||
@ -458,27 +455,6 @@ public class Lint {
|
||||
return suppressedValues.contains(lc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method. Log a lint warning if its lint category is enabled.
|
||||
*
|
||||
* @param warning key for the localized warning message
|
||||
*/
|
||||
public void logIfEnabled(LintWarning warning) {
|
||||
logIfEnabled(null, warning);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method. Log a lint warning if its lint category is enabled.
|
||||
*
|
||||
* @param pos source position at which to report the warning
|
||||
* @param warning key for the localized warning message
|
||||
*/
|
||||
public void logIfEnabled(DiagnosticPosition pos, LintWarning warning) {
|
||||
if (isEnabled(warning.getLintCategory())) {
|
||||
log.warning(pos, warning);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the set of recognized lint warning categories suppressed at the given symbol's declaration.
|
||||
*
|
||||
|
||||
@ -34,13 +34,13 @@ import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Error;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Warning;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.MandatoryWarningHandler;
|
||||
import com.sun.tools.javac.util.Names;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
|
||||
@ -68,12 +68,6 @@ public class Preview {
|
||||
/** flag: are preview features enabled */
|
||||
private final boolean enabled;
|
||||
|
||||
/** flag: is the "preview" lint category enabled? */
|
||||
private final boolean verbose;
|
||||
|
||||
/** the diag handler to manage preview feature usage diagnostics */
|
||||
private final MandatoryWarningHandler previewHandler;
|
||||
|
||||
/** test flag: should all features be considered as preview features? */
|
||||
private final boolean forcePreview;
|
||||
|
||||
@ -104,8 +98,6 @@ public class Preview {
|
||||
enabled = options.isSet(PREVIEW);
|
||||
log = Log.instance(context);
|
||||
source = Source.instance(context);
|
||||
verbose = Lint.instance(context).isEnabled(LintCategory.PREVIEW);
|
||||
previewHandler = new MandatoryWarningHandler(log, source, verbose, true, LintCategory.PREVIEW);
|
||||
forcePreview = options.isSet("forcePreview");
|
||||
majorVersionToSource = initMajorVersionToSourceMap();
|
||||
}
|
||||
@ -178,9 +170,11 @@ public class Preview {
|
||||
Assert.check(isEnabled());
|
||||
Assert.check(isPreview(feature));
|
||||
markUsesPreview(pos);
|
||||
previewHandler.report(pos, feature.isPlural() ?
|
||||
log.mandatoryWarning(pos,
|
||||
feature.isPlural() ?
|
||||
LintWarnings.PreviewFeatureUsePlural(feature.nameFragment()) :
|
||||
LintWarnings.PreviewFeatureUse(feature.nameFragment()));
|
||||
LintWarnings.PreviewFeatureUse(feature.nameFragment()),
|
||||
DiagnosticFlag.AGGREGATE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,10 +184,8 @@ public class Preview {
|
||||
*/
|
||||
public void warnPreview(JavaFileObject classfile, int majorVersion) {
|
||||
Assert.check(isEnabled());
|
||||
if (verbose) {
|
||||
log.mandatoryWarning(null,
|
||||
LintWarnings.PreviewFeatureUseClassfile(classfile, majorVersionToSource.get(majorVersion).name));
|
||||
}
|
||||
log.warning(LintWarnings.PreviewFeatureUseClassfile(classfile, majorVersionToSource.get(majorVersion).name),
|
||||
DiagnosticFlag.MANDATORY); // make it mandatory but don't include DiagnosticFlag.DEFAULT_ENABLED
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,10 +197,6 @@ public class Preview {
|
||||
sourcesWithPreviewFeatures.add(log.currentSourceFile());
|
||||
}
|
||||
|
||||
public void reportPreviewWarning(DiagnosticPosition pos, LintWarning warnKey) {
|
||||
previewHandler.report(pos, warnKey);
|
||||
}
|
||||
|
||||
public boolean usesPreview(JavaFileObject file) {
|
||||
return sourcesWithPreviewFeatures.contains(file);
|
||||
}
|
||||
@ -275,25 +263,13 @@ public class Preview {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report any deferred diagnostics.
|
||||
*/
|
||||
public void reportDeferredDiagnostics() {
|
||||
previewHandler.reportDeferredDiagnostic();
|
||||
}
|
||||
|
||||
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));
|
||||
log.error(DiagnosticFlag.SOURCE_LEVEL, pos, disabledError(feature));
|
||||
} else {
|
||||
if (!feature.allowedInSource(source)) {
|
||||
log.error(JCDiagnostic.DiagnosticFlag.SOURCE_LEVEL, pos,
|
||||
feature.error(source.name));
|
||||
log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
|
||||
}
|
||||
if (isEnabled() && isPreview(feature)) {
|
||||
warnPreview(pos, feature);
|
||||
|
||||
@ -89,9 +89,7 @@ public class Annotate {
|
||||
private final Attr attr;
|
||||
private final Check chk;
|
||||
private final ConstFold cfolder;
|
||||
private final DeferredLintHandler deferredLintHandler;
|
||||
private final Enter enter;
|
||||
private final Lint lint;
|
||||
private final Log log;
|
||||
private final Names names;
|
||||
private final Resolve resolve;
|
||||
@ -110,10 +108,8 @@ public class Annotate {
|
||||
attr = Attr.instance(context);
|
||||
chk = Check.instance(context);
|
||||
cfolder = ConstFold.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
enter = Enter.instance(context);
|
||||
log = Log.instance(context);
|
||||
lint = Lint.instance(context);
|
||||
make = TreeMaker.instance(context);
|
||||
names = Names.instance(context);
|
||||
resolve = Resolve.instance(context);
|
||||
@ -230,10 +226,8 @@ public class Annotate {
|
||||
* @param annotations the list of JCAnnotations to attribute and enter
|
||||
* @param localEnv the enclosing env
|
||||
* @param s the Symbol on which to enter the annotations
|
||||
* @param deferDecl enclosing declaration for DeferredLintHandler, or null for no deferral
|
||||
*/
|
||||
public void annotateLater(List<JCAnnotation> annotations, Env<AttrContext> localEnv,
|
||||
Symbol s, JCTree deferDecl)
|
||||
public void annotateLater(List<JCAnnotation> annotations, Env<AttrContext> localEnv, Symbol s)
|
||||
{
|
||||
if (annotations.isEmpty()) {
|
||||
return;
|
||||
@ -251,8 +245,6 @@ public class Annotate {
|
||||
// been handled, meaning that the set of annotations pending completion is now empty.
|
||||
Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
|
||||
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
|
||||
Assert.check(deferDecl != null);
|
||||
deferredLintHandler.push(deferDecl);
|
||||
try {
|
||||
if (s.hasAnnotations() && annotations.nonEmpty())
|
||||
log.error(annotations.head.pos, Errors.AlreadyAnnotated(Kinds.kindName(s), s));
|
||||
@ -263,7 +255,6 @@ public class Annotate {
|
||||
// never called for a type parameter
|
||||
annotateNow(s, annotations, localEnv, false, false);
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
log.useSource(prev);
|
||||
}
|
||||
});
|
||||
@ -280,16 +271,13 @@ public class Annotate {
|
||||
|
||||
|
||||
/** Queue processing of an attribute default value. */
|
||||
public void annotateDefaultValueLater(JCExpression defaultValue, Env<AttrContext> localEnv,
|
||||
MethodSymbol m, JCTree deferDecl)
|
||||
public void annotateDefaultValueLater(JCExpression defaultValue, Env<AttrContext> localEnv, MethodSymbol m)
|
||||
{
|
||||
normal(() -> {
|
||||
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
|
||||
deferredLintHandler.push(deferDecl);
|
||||
try {
|
||||
enterDefaultValue(defaultValue, localEnv, m);
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
log.useSource(prev);
|
||||
}
|
||||
});
|
||||
@ -671,7 +659,7 @@ public class Annotate {
|
||||
|
||||
// Scan the annotation element value and then attribute nested annotations if present
|
||||
if (tree.type != null && tree.type.tsym != null) {
|
||||
queueScanTreeAndTypeAnnotate(tree, env, tree.type.tsym, null);
|
||||
queueScanTreeAndTypeAnnotate(tree, env, tree.type.tsym);
|
||||
}
|
||||
|
||||
result = cfolder.coerce(result, expectedElementType);
|
||||
@ -1023,20 +1011,14 @@ public class Annotate {
|
||||
/**
|
||||
* Attribute the list of annotations and enter them onto s.
|
||||
*/
|
||||
public void enterTypeAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env,
|
||||
Symbol s, JCTree deferDecl, boolean isTypeParam)
|
||||
public void enterTypeAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env, Symbol s, boolean isTypeParam)
|
||||
{
|
||||
Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/");
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
|
||||
if (deferDecl != null) {
|
||||
deferredLintHandler.push(deferDecl);
|
||||
}
|
||||
try {
|
||||
annotateNow(s, annotations, env, true, isTypeParam);
|
||||
} finally {
|
||||
if (deferDecl != null)
|
||||
deferredLintHandler.pop();
|
||||
log.useSource(prev);
|
||||
}
|
||||
}
|
||||
@ -1044,10 +1026,10 @@ public class Annotate {
|
||||
/**
|
||||
* Enqueue tree for scanning of type annotations, attaching to the Symbol sym.
|
||||
*/
|
||||
public void queueScanTreeAndTypeAnnotate(JCTree tree, Env<AttrContext> env, Symbol sym, JCTree deferDecl)
|
||||
public void queueScanTreeAndTypeAnnotate(JCTree tree, Env<AttrContext> env, Symbol sym)
|
||||
{
|
||||
Assert.checkNonNull(sym);
|
||||
normal(() -> tree.accept(new TypeAnnotate(env, sym, deferDecl)));
|
||||
normal(() -> tree.accept(new TypeAnnotate(env, sym)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1082,32 +1064,30 @@ public class Annotate {
|
||||
private class TypeAnnotate extends TreeScanner {
|
||||
private final Env<AttrContext> env;
|
||||
private final Symbol sym;
|
||||
private JCTree deferDecl;
|
||||
|
||||
public TypeAnnotate(Env<AttrContext> env, Symbol sym, JCTree deferDecl) {
|
||||
public TypeAnnotate(Env<AttrContext> env, Symbol sym) {
|
||||
|
||||
this.env = env;
|
||||
this.sym = sym;
|
||||
this.deferDecl = deferDecl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||
enterTypeAnnotations(tree.annotations, env, sym, deferDecl, false);
|
||||
enterTypeAnnotations(tree.annotations, env, sym, false);
|
||||
scan(tree.underlyingType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeParameter(JCTypeParameter tree) {
|
||||
enterTypeAnnotations(tree.annotations, env, sym, deferDecl, true);
|
||||
enterTypeAnnotations(tree.annotations, env, sym, true);
|
||||
scan(tree.bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewArray(JCNewArray tree) {
|
||||
enterTypeAnnotations(tree.annotations, env, sym, deferDecl, false);
|
||||
enterTypeAnnotations(tree.annotations, env, sym, false);
|
||||
for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
|
||||
enterTypeAnnotations(dimAnnos, env, sym, deferDecl, false);
|
||||
enterTypeAnnotations(dimAnnos, env, sym, false);
|
||||
scan(tree.elemtype);
|
||||
scan(tree.elems);
|
||||
}
|
||||
@ -1126,19 +1106,13 @@ public class Annotate {
|
||||
|
||||
@Override
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
JCTree prevDecl = deferDecl;
|
||||
deferDecl = tree;
|
||||
try {
|
||||
if (sym != null && sym.kind == VAR) {
|
||||
// Don't visit a parameter once when the sym is the method
|
||||
// and once when the sym is the parameter.
|
||||
scan(tree.mods);
|
||||
scan(tree.vartype);
|
||||
}
|
||||
scan(tree.init);
|
||||
} finally {
|
||||
deferDecl = prevDecl;
|
||||
if (sym != null && sym.kind == VAR) {
|
||||
// Don't visit a parameter once when the sym is the method
|
||||
// and once when the sym is the parameter.
|
||||
scan(tree.mods);
|
||||
scan(tree.vartype);
|
||||
}
|
||||
scan(tree.init);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -69,6 +69,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Error;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Warning;
|
||||
import com.sun.tools.javac.util.LintMapper;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
@ -99,6 +100,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
final Names names;
|
||||
final Log log;
|
||||
final LintMapper lintMapper;
|
||||
final Symtab syms;
|
||||
final Resolve rs;
|
||||
final Operators operators;
|
||||
@ -117,7 +119,6 @@ public class Attr extends JCTree.Visitor {
|
||||
final Preview preview;
|
||||
final JCDiagnostic.Factory diags;
|
||||
final TypeAnnotations typeAnnotations;
|
||||
final DeferredLintHandler deferredLintHandler;
|
||||
final TypeEnvs typeEnvs;
|
||||
final Dependencies dependencies;
|
||||
final Annotate annotate;
|
||||
@ -138,6 +139,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
names = Names.instance(context);
|
||||
log = Log.instance(context);
|
||||
lintMapper = LintMapper.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
rs = Resolve.instance(context);
|
||||
operators = Operators.instance(context);
|
||||
@ -157,7 +159,6 @@ public class Attr extends JCTree.Visitor {
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
annotate = Annotate.instance(context);
|
||||
typeAnnotations = TypeAnnotations.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
typeEnvs = TypeEnvs.instance(context);
|
||||
dependencies = Dependencies.instance(context);
|
||||
argumentAttr = ArgumentAttr.instance(context);
|
||||
@ -854,7 +855,6 @@ public class Attr extends JCTree.Visitor {
|
||||
Env<AttrContext> enclosingEnv,
|
||||
JCVariableDecl variable,
|
||||
Type type) {
|
||||
deferredLintHandler.push(variable);
|
||||
final JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
doQueueScanTreeAndTypeAnnotateForVarInit(variable, enclosingEnv);
|
||||
@ -870,7 +870,6 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
} finally {
|
||||
log.useSource(prevSource);
|
||||
deferredLintHandler.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -999,7 +998,6 @@ public class Attr extends JCTree.Visitor {
|
||||
Assert.check(!env.info.ctorPrologue);
|
||||
MethodSymbol prevMethod = chk.setMethod(m);
|
||||
try {
|
||||
deferredLintHandler.flush(tree, lint);
|
||||
chk.checkDeprecatedAnnotation(tree.pos(), m);
|
||||
|
||||
|
||||
@ -1232,7 +1230,7 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
// Attribute all type annotations in the body
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m);
|
||||
annotate.flush();
|
||||
|
||||
// Start of constructor prologue
|
||||
@ -1296,7 +1294,6 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
try {
|
||||
v.getConstValue(); // ensure compile-time constant initializer is evaluated
|
||||
deferredLintHandler.flush(tree, lint);
|
||||
chk.checkDeprecatedAnnotation(tree.pos(), v);
|
||||
|
||||
if (tree.init != null) {
|
||||
@ -1340,7 +1337,7 @@ public class Attr extends JCTree.Visitor {
|
||||
env.info.scope.owner.kind != MTH && env.info.scope.owner.kind != VAR) {
|
||||
tree.mods.flags |= Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED;
|
||||
// Field initializer expression need to be entered.
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.init, env, tree.sym, tree);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.init, env, tree.sym);
|
||||
annotate.flush();
|
||||
}
|
||||
}
|
||||
@ -1437,7 +1434,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
|
||||
// Attribute all type annotations in the block
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
|
||||
annotate.flush();
|
||||
attribStats(tree.stats, localEnv);
|
||||
|
||||
@ -1946,7 +1943,7 @@ public class Attr extends JCTree.Visitor {
|
||||
public void visitSynchronized(JCSynchronized tree) {
|
||||
chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
|
||||
if (isValueBased(tree.lock.type)) {
|
||||
env.info.lint.logIfEnabled(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
|
||||
log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
|
||||
}
|
||||
attribStat(tree.body, env);
|
||||
result = null;
|
||||
@ -2053,7 +2050,7 @@ public class Attr extends JCTree.Visitor {
|
||||
if (close.kind == MTH &&
|
||||
close.overrides(syms.autoCloseableClose, resource.tsym, types, true) &&
|
||||
chk.isHandled(syms.interruptedExceptionType, types.memberType(resource, close).getThrownTypes())) {
|
||||
env.info.lint.logIfEnabled(pos, LintWarnings.TryResourceThrowsInterruptedExc(resource));
|
||||
log.warning(pos, LintWarnings.TryResourceThrowsInterruptedExc(resource));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4214,9 +4211,9 @@ public class Attr extends JCTree.Visitor {
|
||||
setSyntheticVariableType(tree.var, type == Type.noType ? syms.errType
|
||||
: type);
|
||||
}
|
||||
annotate.annotateLater(tree.var.mods.annotations, env, v, tree.var);
|
||||
annotate.annotateLater(tree.var.mods.annotations, env, v);
|
||||
if (!tree.var.isImplicitlyTyped()) {
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.var.vartype, env, v, tree.var);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.var.vartype, env, v);
|
||||
}
|
||||
annotate.flush();
|
||||
result = tree.type;
|
||||
@ -4453,7 +4450,7 @@ public class Attr extends JCTree.Visitor {
|
||||
sym.kind == MTH &&
|
||||
sym.name.equals(names.close) &&
|
||||
sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true)) {
|
||||
env.info.lint.logIfEnabled(tree, LintWarnings.TryExplicitCloseCall);
|
||||
log.warning(tree, LintWarnings.TryExplicitCloseCall);
|
||||
}
|
||||
|
||||
// Disallow selecting a type from an expression
|
||||
@ -4480,9 +4477,9 @@ public class Attr extends JCTree.Visitor {
|
||||
// If the qualified item is not a type and the selected item is static, report
|
||||
// a warning. Make allowance for the class of an array type e.g. Object[].class)
|
||||
if (!sym.owner.isAnonymous()) {
|
||||
chk.lint.logIfEnabled(tree, LintWarnings.StaticNotQualifiedByType(sym.kind.kindName(), sym.owner));
|
||||
log.warning(tree, LintWarnings.StaticNotQualifiedByType(sym.kind.kindName(), sym.owner));
|
||||
} else {
|
||||
chk.lint.logIfEnabled(tree, LintWarnings.StaticNotQualifiedByType2(sym.kind.kindName()));
|
||||
log.warning(tree, LintWarnings.StaticNotQualifiedByType2(sym.kind.kindName()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5287,6 +5284,8 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
annotate.flush();
|
||||
|
||||
lintMapper.calculateLints(env.toplevel.sourcefile, env.tree, env.toplevel.endPositions);
|
||||
}
|
||||
|
||||
public void attribPackage(DiagnosticPosition pos, PackageSymbol p) {
|
||||
@ -5329,7 +5328,6 @@ public class Attr extends JCTree.Visitor {
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
|
||||
try {
|
||||
deferredLintHandler.flush(env.tree, lint);
|
||||
attrib.accept(env);
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
@ -5508,7 +5506,6 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
deferredLintHandler.flush(env.tree, env.info.lint);
|
||||
env.info.returnResult = null;
|
||||
// java.lang.Enum may not be subclassed by a non-enum
|
||||
if (st.tsym == syms.enumSym &&
|
||||
@ -5554,11 +5551,9 @@ public class Attr extends JCTree.Visitor {
|
||||
ModuleSymbol msym = tree.sym;
|
||||
Lint lint = env.outer.info.lint = env.outer.info.lint.augment(msym);
|
||||
Lint prevLint = chk.setLint(lint);
|
||||
chk.checkModuleName(tree);
|
||||
chk.checkDeprecatedAnnotation(tree, msym);
|
||||
|
||||
try {
|
||||
deferredLintHandler.flush(tree, lint);
|
||||
chk.checkModuleName(tree);
|
||||
chk.checkDeprecatedAnnotation(tree, msym);
|
||||
} finally {
|
||||
chk.setLint(prevLint);
|
||||
}
|
||||
|
||||
@ -162,20 +162,6 @@ public class Check {
|
||||
profile = Profile.instance(context);
|
||||
preview = Preview.instance(context);
|
||||
|
||||
boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
|
||||
boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
|
||||
boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
|
||||
boolean enforceMandatoryWarnings = true;
|
||||
|
||||
deprecationHandler = new MandatoryWarningHandler(log, null, verboseDeprecated,
|
||||
enforceMandatoryWarnings, LintCategory.DEPRECATION, "deprecated");
|
||||
removalHandler = new MandatoryWarningHandler(log, null, verboseRemoval,
|
||||
enforceMandatoryWarnings, LintCategory.REMOVAL);
|
||||
uncheckedHandler = new MandatoryWarningHandler(log, null, verboseUnchecked,
|
||||
enforceMandatoryWarnings, LintCategory.UNCHECKED);
|
||||
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
|
||||
allowModules = Feature.MODULES.allowedInSource(source);
|
||||
allowRecords = Feature.RECORDS.allowedInSource(source);
|
||||
allowSealed = Feature.SEALED_CLASSES.allowedInSource(source);
|
||||
@ -190,22 +176,6 @@ public class Check {
|
||||
*/
|
||||
private Map<Pair<ModuleSymbol, Name>,ClassSymbol> compiled = new HashMap<>();
|
||||
|
||||
/** A handler for messages about deprecated usage.
|
||||
*/
|
||||
private MandatoryWarningHandler deprecationHandler;
|
||||
|
||||
/** A handler for messages about deprecated-for-removal usage.
|
||||
*/
|
||||
private MandatoryWarningHandler removalHandler;
|
||||
|
||||
/** A handler for messages about unchecked or unsafe usage.
|
||||
*/
|
||||
private MandatoryWarningHandler uncheckedHandler;
|
||||
|
||||
/** A handler for deferred lint warnings.
|
||||
*/
|
||||
private DeferredLintHandler deferredLintHandler;
|
||||
|
||||
/** Are modules allowed
|
||||
*/
|
||||
private final boolean allowModules;
|
||||
@ -251,21 +221,15 @@ public class Check {
|
||||
* @param sym The deprecated symbol.
|
||||
*/
|
||||
void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
|
||||
if (sym.isDeprecatedForRemoval()) {
|
||||
if (!lint.isSuppressed(LintCategory.REMOVAL)) {
|
||||
if (sym.kind == MDL) {
|
||||
removalHandler.report(pos, LintWarnings.HasBeenDeprecatedForRemovalModule(sym));
|
||||
} else {
|
||||
removalHandler.report(pos, LintWarnings.HasBeenDeprecatedForRemoval(sym, sym.location()));
|
||||
}
|
||||
}
|
||||
} else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
|
||||
if (sym.kind == MDL) {
|
||||
deprecationHandler.report(pos, LintWarnings.HasBeenDeprecatedModule(sym));
|
||||
} else {
|
||||
deprecationHandler.report(pos, LintWarnings.HasBeenDeprecated(sym, sym.location()));
|
||||
}
|
||||
}
|
||||
Assert.check(!importSuppression);
|
||||
LintWarning warningKey = sym.isDeprecatedForRemoval() ?
|
||||
(sym.kind == MDL ?
|
||||
LintWarnings.HasBeenDeprecatedForRemovalModule(sym) :
|
||||
LintWarnings.HasBeenDeprecatedForRemoval(sym, sym.location())) :
|
||||
(sym.kind == MDL ?
|
||||
LintWarnings.HasBeenDeprecatedModule(sym) :
|
||||
LintWarnings.HasBeenDeprecated(sym, sym.location()));
|
||||
log.mandatoryWarning(pos, warningKey, DiagnosticFlag.AGGREGATE);
|
||||
}
|
||||
|
||||
/** Log a preview warning.
|
||||
@ -273,16 +237,9 @@ public class Check {
|
||||
* @param msg A Warning describing the problem.
|
||||
*/
|
||||
public void warnPreviewAPI(DiagnosticPosition pos, LintWarning warnKey) {
|
||||
if (!importSuppression && !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 warnRestrictedAPI(DiagnosticPosition pos, Symbol sym) {
|
||||
lint.logIfEnabled(pos, LintWarnings.RestrictedMethod(sym.enclClass(), sym));
|
||||
if (!importSuppression) {
|
||||
log.mandatoryWarning(pos, warnKey, DiagnosticFlag.AGGREGATE);
|
||||
}
|
||||
}
|
||||
|
||||
/** Warn about unchecked operation.
|
||||
@ -290,26 +247,15 @@ public class Check {
|
||||
* @param msg A string describing the problem.
|
||||
*/
|
||||
public void warnUnchecked(DiagnosticPosition pos, LintWarning warnKey) {
|
||||
if (!lint.isSuppressed(LintCategory.UNCHECKED))
|
||||
uncheckedHandler.report(pos, warnKey);
|
||||
log.mandatoryWarning(pos, warnKey, DiagnosticFlag.AGGREGATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report any deferred diagnostics.
|
||||
*/
|
||||
public void reportDeferredDiagnostics() {
|
||||
deprecationHandler.reportDeferredDiagnostic();
|
||||
removalHandler.reportDeferredDiagnostic();
|
||||
uncheckedHandler.reportDeferredDiagnostic();
|
||||
}
|
||||
|
||||
|
||||
/** Report a failure to complete a class.
|
||||
* @param pos Position to be used for error reporting.
|
||||
* @param ex The failure to report.
|
||||
*/
|
||||
public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
|
||||
log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, Errors.CantAccess(ex.sym, ex.getDetailValue()));
|
||||
log.error(DiagnosticFlag.NON_DEFERRABLE, pos, Errors.CantAccess(ex.sym, ex.getDetailValue()));
|
||||
return syms.errType;
|
||||
}
|
||||
|
||||
@ -472,12 +418,6 @@ public class Check {
|
||||
localClassNameIndexes.clear();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
deprecationHandler.clear();
|
||||
removalHandler.clear();
|
||||
uncheckedHandler.clear();
|
||||
}
|
||||
|
||||
public void putCompiled(ClassSymbol csym) {
|
||||
compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
|
||||
}
|
||||
@ -643,9 +583,7 @@ public class Check {
|
||||
&& types.isSameType(tree.expr.type, tree.clazz.type)
|
||||
&& !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
|
||||
&& !is292targetTypeCast(tree)) {
|
||||
deferredLintHandler.report(_l -> {
|
||||
lint.logIfEnabled(tree.pos(), LintWarnings.RedundantCast(tree.clazz.type));
|
||||
});
|
||||
log.warning(tree.pos(), LintWarnings.RedundantCast(tree.clazz.type));
|
||||
}
|
||||
}
|
||||
//where
|
||||
@ -949,7 +887,7 @@ public class Check {
|
||||
}
|
||||
} else if (hasTrustMeAnno && varargElemType != null &&
|
||||
types.isReifiable(varargElemType)) {
|
||||
lint.logIfEnabled(tree, LintWarnings.VarargsRedundantTrustmeAnno(
|
||||
log.warning(tree.pos(), LintWarnings.VarargsRedundantTrustmeAnno(
|
||||
syms.trustMeType.tsym,
|
||||
diags.fragment(Fragments.VarargsTrustmeOnReifiableVarargs(varargElemType))));
|
||||
}
|
||||
@ -1208,7 +1146,7 @@ public class Check {
|
||||
mask = MethodFlags;
|
||||
}
|
||||
if ((flags & STRICTFP) != 0) {
|
||||
warnOnExplicitStrictfp(tree);
|
||||
log.warning(tree.pos(), LintWarnings.Strictfp);
|
||||
}
|
||||
// Imply STRICTFP if owner has STRICTFP set.
|
||||
if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
|
||||
@ -1252,7 +1190,7 @@ public class Check {
|
||||
implicit |= FINAL;
|
||||
}
|
||||
if ((flags & STRICTFP) != 0) {
|
||||
warnOnExplicitStrictfp(tree);
|
||||
log.warning(tree.pos(), LintWarnings.Strictfp);
|
||||
}
|
||||
// Imply STRICTFP if owner has STRICTFP set.
|
||||
implicit |= sym.owner.flags_field & STRICTFP;
|
||||
@ -1316,16 +1254,6 @@ public class Check {
|
||||
return flags & (mask | ~ExtendedStandardFlags) | implicit;
|
||||
}
|
||||
|
||||
private void warnOnExplicitStrictfp(JCTree tree) {
|
||||
deferredLintHandler.push(tree);
|
||||
try {
|
||||
deferredLintHandler.report(_ -> lint.logIfEnabled(tree.pos(), LintWarnings.Strictfp));
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Determine if this enum should be implicitly final.
|
||||
*
|
||||
* If the enum has no specialized enum constants, it is final.
|
||||
@ -1538,7 +1466,7 @@ public class Check {
|
||||
!TreeInfo.isDiamond(tree) &&
|
||||
!withinAnonConstr(env) &&
|
||||
tree.type.isRaw()) {
|
||||
lint.logIfEnabled(tree.pos(), LintWarnings.RawClassUse(tree.type, tree.type.tsym.type));
|
||||
log.warning(tree.pos(), LintWarnings.RawClassUse(tree.type, tree.type.tsym.type));
|
||||
}
|
||||
}
|
||||
//where
|
||||
@ -1862,7 +1790,7 @@ public class Check {
|
||||
|
||||
// Optional warning if varargs don't agree
|
||||
if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)) {
|
||||
lint.logIfEnabled(TreeInfo.diagnosticPositionFor(m, tree),
|
||||
log.warning(TreeInfo.diagnosticPositionFor(m, tree),
|
||||
((m.flags() & Flags.VARARGS) != 0)
|
||||
? LintWarnings.OverrideVarargsMissing(varargsOverrides(m, other))
|
||||
: LintWarnings.OverrideVarargsExtra(varargsOverrides(m, other)));
|
||||
@ -2943,42 +2871,34 @@ public class Check {
|
||||
|
||||
// Apply special flag "-XDwarnOnAccessToMembers" which turns on just this particular warning for all types of access
|
||||
void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
|
||||
final Lint prevLint = setLint(warnOnAnyAccessToMembers ? lint.enable(LintCategory.SERIAL) : lint);
|
||||
try {
|
||||
if (warnOnAnyAccessToMembers || isLambda)
|
||||
checkAccessFromSerializableElementInner(tree, isLambda);
|
||||
} finally {
|
||||
setLint(prevLint);
|
||||
}
|
||||
if (warnOnAnyAccessToMembers || isLambda)
|
||||
checkAccessFromSerializableElementInner(tree, isLambda);
|
||||
}
|
||||
|
||||
private void checkAccessFromSerializableElementInner(final JCTree tree, boolean isLambda) {
|
||||
if (lint.isEnabled(LintCategory.SERIAL)) {
|
||||
Symbol sym = TreeInfo.symbol(tree);
|
||||
if (!sym.kind.matches(KindSelector.VAL_MTH)) {
|
||||
Symbol sym = TreeInfo.symbol(tree);
|
||||
if (!sym.kind.matches(KindSelector.VAL_MTH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sym.kind == VAR) {
|
||||
if ((sym.flags() & PARAMETER) != 0 ||
|
||||
sym.isDirectlyOrIndirectlyLocal() ||
|
||||
sym.name == names._this ||
|
||||
sym.name == names._super) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sym.kind == VAR) {
|
||||
if ((sym.flags() & PARAMETER) != 0 ||
|
||||
sym.isDirectlyOrIndirectlyLocal() ||
|
||||
sym.name == names._this ||
|
||||
sym.name == names._super) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
|
||||
isEffectivelyNonPublic(sym)) {
|
||||
if (isLambda) {
|
||||
if (belongsToRestrictedPackage(sym)) {
|
||||
log.warning(tree.pos(),
|
||||
LintWarnings.AccessToMemberFromSerializableLambda(sym));
|
||||
}
|
||||
} else {
|
||||
log.warning(tree.pos(),
|
||||
LintWarnings.AccessToMemberFromSerializableElement(sym));
|
||||
if (!types.isSubtype(sym.owner.type, syms.serializableType) && isEffectivelyNonPublic(sym)) {
|
||||
DiagnosticFlag[] flags = warnOnAnyAccessToMembers ?
|
||||
new DiagnosticFlag[] { DiagnosticFlag.DEFAULT_ENABLED } : new DiagnosticFlag[0];
|
||||
if (isLambda) {
|
||||
if (belongsToRestrictedPackage(sym)) {
|
||||
log.warning(tree.pos(), LintWarnings.AccessToMemberFromSerializableLambda(sym), flags);
|
||||
}
|
||||
} else {
|
||||
log.warning(tree.pos(), LintWarnings.AccessToMemberFromSerializableElement(sym), flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3765,8 +3685,7 @@ public class Check {
|
||||
// Note: @Deprecated has no effect on local variables, parameters and package decls.
|
||||
if (lint.isEnabled(LintCategory.DEPRECATION) && !s.isDeprecatableViaAnnotation()) {
|
||||
if (!syms.deprecatedType.isErroneous() && s.attribute(syms.deprecatedType.tsym) != null) {
|
||||
log.warning(pos,
|
||||
LintWarnings.DeprecatedAnnotationHasNoEffect(Kinds.kindName(s)));
|
||||
log.warning(pos, LintWarnings.DeprecatedAnnotationHasNoEffect(Kinds.kindName(s)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3780,15 +3699,13 @@ public class Check {
|
||||
&& (s.isDeprecatedForRemoval() || s.isDeprecated() && !other.isDeprecated())
|
||||
&& (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)
|
||||
&& s.kind != Kind.PCK) {
|
||||
deferredLintHandler.report(_l -> warnDeprecated(pos.get(), s));
|
||||
warnDeprecated(pos.get(), s);
|
||||
}
|
||||
}
|
||||
|
||||
void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
|
||||
if ((s.flags() & PROPRIETARY) != 0) {
|
||||
deferredLintHandler.report(_l -> {
|
||||
log.mandatoryWarning(pos, Warnings.SunProprietary(s));
|
||||
});
|
||||
log.mandatoryWarning(pos, Warnings.SunProprietary(s));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3845,7 +3762,7 @@ public class Check {
|
||||
|
||||
void checkRestricted(DiagnosticPosition pos, Symbol s) {
|
||||
if (s.kind == MTH && (s.flags() & RESTRICTED) != 0) {
|
||||
deferredLintHandler.report(_l -> warnRestrictedAPI(pos, s));
|
||||
log.warning(pos, LintWarnings.RestrictedMethod(s.enclClass(), s));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4117,7 +4034,7 @@ public class Check {
|
||||
int opc = ((OperatorSymbol)operator).opcode;
|
||||
if (opc == ByteCodes.idiv || opc == ByteCodes.imod
|
||||
|| opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
|
||||
deferredLintHandler.report(_ -> lint.logIfEnabled(pos, LintWarnings.DivZero));
|
||||
log.warning(pos, LintWarnings.DivZero);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4130,8 +4047,7 @@ public class Check {
|
||||
*/
|
||||
void checkLossOfPrecision(final DiagnosticPosition pos, Type found, Type req) {
|
||||
if (found.isNumeric() && req.isNumeric() && !types.isAssignable(found, req)) {
|
||||
deferredLintHandler.report(_ ->
|
||||
lint.logIfEnabled(pos, LintWarnings.PossibleLossOfPrecision(found, req)));
|
||||
log.warning(pos, LintWarnings.PossibleLossOfPrecision(found, req));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4140,7 +4056,7 @@ public class Check {
|
||||
*/
|
||||
void checkEmptyIf(JCIf tree) {
|
||||
if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null) {
|
||||
lint.logIfEnabled(tree.thenpart.pos(), LintWarnings.EmptyIf);
|
||||
log.warning(tree.thenpart.pos(), LintWarnings.EmptyIf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4287,8 +4203,7 @@ public class Check {
|
||||
rs.isAccessible(env, c) &&
|
||||
!fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
|
||||
{
|
||||
lint.logIfEnabled(pos,
|
||||
LintWarnings.AuxiliaryClassAccessedFromOutsideOfItsSourceFile(c, c.sourcefile));
|
||||
log.warning(pos, LintWarnings.AuxiliaryClassAccessedFromOutsideOfItsSourceFile(c, c.sourcefile));
|
||||
}
|
||||
}
|
||||
|
||||
@ -4330,8 +4245,7 @@ public class Check {
|
||||
// Warning may be suppressed by
|
||||
// annotations; check again for being
|
||||
// enabled in the deferred context.
|
||||
deferredLintHandler.report(_ ->
|
||||
lint.logIfEnabled(pos, LintWarnings.MissingExplicitCtor(c, pkg, modle)));
|
||||
log.warning(pos, LintWarnings.MissingExplicitCtor(c, pkg, modle));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -4367,7 +4281,7 @@ public class Check {
|
||||
method.attribute(syms.trustMeType.tsym) != null &&
|
||||
isTrustMeAllowedOnMethod(method) &&
|
||||
!types.isReifiable(method.type.getParameterTypes().last())) {
|
||||
Check.this.lint.logIfEnabled(pos(), LintWarnings.VarargsUnsafeUseVarargsParam(method.params.last()));
|
||||
log.warning(pos(), LintWarnings.VarargsUnsafeUseVarargsParam(method.params.last()));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -4665,28 +4579,24 @@ public class Check {
|
||||
|
||||
void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
|
||||
if (msym.kind != MDL) {
|
||||
deferredLintHandler.report(_ ->
|
||||
lint.logIfEnabled(pos, LintWarnings.ModuleNotFound(msym)));
|
||||
log.warning(pos, LintWarnings.ModuleNotFound(msym));
|
||||
}
|
||||
}
|
||||
|
||||
void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol packge) {
|
||||
if (packge.members().isEmpty() &&
|
||||
((packge.flags() & Flags.HAS_RESOURCE) == 0)) {
|
||||
deferredLintHandler.report(_ ->
|
||||
lint.logIfEnabled(pos, LintWarnings.PackageEmptyOrNotFound(packge)));
|
||||
log.warning(pos, LintWarnings.PackageEmptyOrNotFound(packge));
|
||||
}
|
||||
}
|
||||
|
||||
void checkModuleRequires(final DiagnosticPosition pos, final RequiresDirective rd) {
|
||||
if ((rd.module.flags() & Flags.AUTOMATIC_MODULE) != 0) {
|
||||
deferredLintHandler.report(_ -> {
|
||||
if (rd.isTransitive() && lint.isEnabled(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC)) {
|
||||
log.warning(pos, LintWarnings.RequiresTransitiveAutomatic);
|
||||
} else {
|
||||
lint.logIfEnabled(pos, LintWarnings.RequiresAutomatic);
|
||||
}
|
||||
});
|
||||
if (rd.isTransitive()) { // see comment in Log.applyLint() for special logic that applies
|
||||
log.warning(pos, LintWarnings.RequiresTransitiveAutomatic);
|
||||
} else {
|
||||
log.warning(pos, LintWarnings.RequiresAutomatic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -214,7 +214,6 @@ public class Flow {
|
||||
private final Resolve rs;
|
||||
private final JCDiagnostic.Factory diags;
|
||||
private Env<AttrContext> attrEnv;
|
||||
private Lint lint;
|
||||
private final Infer infer;
|
||||
|
||||
public static Flow instance(Context context) {
|
||||
@ -337,7 +336,6 @@ public class Flow {
|
||||
syms = Symtab.instance(context);
|
||||
types = Types.instance(context);
|
||||
chk = Check.instance(context);
|
||||
lint = Lint.instance(context);
|
||||
infer = Infer.instance(context);
|
||||
rs = Resolve.instance(context);
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
@ -566,10 +564,8 @@ public class Flow {
|
||||
if (tree.sym == null) return;
|
||||
Liveness alivePrev = alive;
|
||||
ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
|
||||
Lint lintPrev = lint;
|
||||
|
||||
pendingExits = new ListBuffer<>();
|
||||
lint = lint.augment(tree.sym);
|
||||
|
||||
try {
|
||||
// process all the nested classes
|
||||
@ -600,30 +596,22 @@ public class Flow {
|
||||
} finally {
|
||||
pendingExits = pendingExitsPrev;
|
||||
alive = alivePrev;
|
||||
lint = lintPrev;
|
||||
}
|
||||
}
|
||||
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
if (tree.body == null) return;
|
||||
Lint lintPrev = lint;
|
||||
|
||||
lint = lint.augment(tree.sym);
|
||||
|
||||
Assert.check(pendingExits.isEmpty());
|
||||
|
||||
try {
|
||||
alive = Liveness.ALIVE;
|
||||
scanStat(tree.body);
|
||||
tree.completesNormally = alive != Liveness.DEAD;
|
||||
alive = Liveness.ALIVE;
|
||||
scanStat(tree.body);
|
||||
tree.completesNormally = alive != Liveness.DEAD;
|
||||
|
||||
if (alive == Liveness.ALIVE && !tree.sym.type.getReturnType().hasTag(VOID))
|
||||
log.error(TreeInfo.diagEndPos(endPositions, tree.body), Errors.MissingRetStmt);
|
||||
if (alive == Liveness.ALIVE && !tree.sym.type.getReturnType().hasTag(VOID))
|
||||
log.error(TreeInfo.diagEndPos(endPositions, tree.body), Errors.MissingRetStmt);
|
||||
|
||||
clearPendingExits(true);
|
||||
} finally {
|
||||
lint = lintPrev;
|
||||
}
|
||||
clearPendingExits(true);
|
||||
}
|
||||
|
||||
private void clearPendingExits(boolean inMethod) {
|
||||
@ -638,15 +626,7 @@ public class Flow {
|
||||
}
|
||||
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
if (tree.init != null) {
|
||||
Lint lintPrev = lint;
|
||||
lint = lint.augment(tree.sym);
|
||||
try{
|
||||
scan(tree.init);
|
||||
} finally {
|
||||
lint = lintPrev;
|
||||
}
|
||||
}
|
||||
scan(tree.init);
|
||||
}
|
||||
|
||||
public void visitBlock(JCBlock tree) {
|
||||
@ -728,8 +708,7 @@ public class Flow {
|
||||
// Warn about fall-through if lint switch fallthrough enabled.
|
||||
if (alive == Liveness.ALIVE &&
|
||||
c.stats.nonEmpty() && l.tail.nonEmpty())
|
||||
lint.logIfEnabled(l.tail.head.pos(),
|
||||
LintWarnings.PossibleFallThroughIntoCase);
|
||||
log.warning(l.tail.head.pos(), LintWarnings.PossibleFallThroughIntoCase);
|
||||
}
|
||||
tree.isExhaustive = tree.hasUnconditionalPattern ||
|
||||
TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases);
|
||||
@ -1236,7 +1215,7 @@ public class Flow {
|
||||
scanStat(tree.finalizer);
|
||||
tree.finallyCanCompleteNormally = alive != Liveness.DEAD;
|
||||
if (alive == Liveness.DEAD) {
|
||||
lint.logIfEnabled(TreeInfo.diagEndPos(endPositions, tree.finalizer),
|
||||
log.warning(TreeInfo.diagEndPos(endPositions, tree.finalizer),
|
||||
LintWarnings.FinallyCannotComplete);
|
||||
} else {
|
||||
while (exits.nonEmpty()) {
|
||||
@ -1459,7 +1438,6 @@ public class Flow {
|
||||
List<Type> thrownPrev = thrown;
|
||||
List<Type> caughtPrev = caught;
|
||||
ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
|
||||
Lint lintPrev = lint;
|
||||
boolean anonymousClass = tree.name == names.empty;
|
||||
pendingExits = new ListBuffer<>();
|
||||
if (!anonymousClass) {
|
||||
@ -1467,7 +1445,6 @@ public class Flow {
|
||||
}
|
||||
classDef = tree;
|
||||
thrown = List.nil();
|
||||
lint = lint.augment(tree.sym);
|
||||
|
||||
try {
|
||||
// process all the nested classes
|
||||
@ -1516,7 +1493,6 @@ public class Flow {
|
||||
pendingExits = pendingExitsPrev;
|
||||
caught = caughtPrev;
|
||||
classDef = classDefPrev;
|
||||
lint = lintPrev;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1525,9 +1501,6 @@ public class Flow {
|
||||
|
||||
List<Type> caughtPrev = caught;
|
||||
List<Type> mthrown = tree.sym.type.getThrownTypes();
|
||||
Lint lintPrev = lint;
|
||||
|
||||
lint = lint.augment(tree.sym);
|
||||
|
||||
Assert.check(pendingExits.isEmpty());
|
||||
|
||||
@ -1560,20 +1533,11 @@ public class Flow {
|
||||
}
|
||||
} finally {
|
||||
caught = caughtPrev;
|
||||
lint = lintPrev;
|
||||
}
|
||||
}
|
||||
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
if (tree.init != null) {
|
||||
Lint lintPrev = lint;
|
||||
lint = lint.augment(tree.sym);
|
||||
try{
|
||||
scan(tree.init);
|
||||
} finally {
|
||||
lint = lintPrev;
|
||||
}
|
||||
}
|
||||
scan(tree.init);
|
||||
}
|
||||
|
||||
public void visitBlock(JCBlock tree) {
|
||||
@ -2395,82 +2359,76 @@ public class Flow {
|
||||
return;
|
||||
}
|
||||
|
||||
Lint lintPrev = lint;
|
||||
lint = lint.augment(tree.sym);
|
||||
JCClassDecl classDefPrev = classDef;
|
||||
int firstadrPrev = firstadr;
|
||||
int nextadrPrev = nextadr;
|
||||
ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
|
||||
|
||||
pendingExits = new ListBuffer<>();
|
||||
if (tree.name != names.empty) {
|
||||
firstadr = nextadr;
|
||||
}
|
||||
classDef = tree;
|
||||
try {
|
||||
JCClassDecl classDefPrev = classDef;
|
||||
int firstadrPrev = firstadr;
|
||||
int nextadrPrev = nextadr;
|
||||
ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
|
||||
|
||||
pendingExits = new ListBuffer<>();
|
||||
if (tree.name != names.empty) {
|
||||
firstadr = nextadr;
|
||||
// define all the static fields
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(VARDEF)) {
|
||||
JCVariableDecl def = (JCVariableDecl)l.head;
|
||||
if ((def.mods.flags & STATIC) != 0) {
|
||||
VarSymbol sym = def.sym;
|
||||
if (trackable(sym)) {
|
||||
newVar(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
classDef = tree;
|
||||
try {
|
||||
// define all the static fields
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(VARDEF)) {
|
||||
JCVariableDecl def = (JCVariableDecl)l.head;
|
||||
if ((def.mods.flags & STATIC) != 0) {
|
||||
VarSymbol sym = def.sym;
|
||||
if (trackable(sym)) {
|
||||
newVar(def);
|
||||
}
|
||||
|
||||
// process all the static initializers
|
||||
forEachInitializer(tree, true, def -> {
|
||||
scan(def);
|
||||
clearPendingExits(false);
|
||||
});
|
||||
|
||||
// verify all static final fields got initialized
|
||||
for (int i = firstadr; i < nextadr; i++) {
|
||||
JCVariableDecl vardecl = vardecls[i];
|
||||
VarSymbol var = vardecl.sym;
|
||||
if (var.owner == classDef.sym && var.isStatic()) {
|
||||
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), var);
|
||||
}
|
||||
}
|
||||
|
||||
// define all the instance fields
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(VARDEF)) {
|
||||
JCVariableDecl def = (JCVariableDecl)l.head;
|
||||
if ((def.mods.flags & STATIC) == 0) {
|
||||
VarSymbol sym = def.sym;
|
||||
if (trackable(sym)) {
|
||||
newVar(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process all the static initializers
|
||||
forEachInitializer(tree, true, def -> {
|
||||
scan(def);
|
||||
clearPendingExits(false);
|
||||
});
|
||||
|
||||
// verify all static final fields got initialized
|
||||
for (int i = firstadr; i < nextadr; i++) {
|
||||
JCVariableDecl vardecl = vardecls[i];
|
||||
VarSymbol var = vardecl.sym;
|
||||
if (var.owner == classDef.sym && var.isStatic()) {
|
||||
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), var);
|
||||
}
|
||||
// process all the methods
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(METHODDEF)) {
|
||||
scan(l.head);
|
||||
}
|
||||
}
|
||||
|
||||
// define all the instance fields
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(VARDEF)) {
|
||||
JCVariableDecl def = (JCVariableDecl)l.head;
|
||||
if ((def.mods.flags & STATIC) == 0) {
|
||||
VarSymbol sym = def.sym;
|
||||
if (trackable(sym)) {
|
||||
newVar(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
// process all the nested classes
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(CLASSDEF)) {
|
||||
scan(l.head);
|
||||
}
|
||||
|
||||
// process all the methods
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(METHODDEF)) {
|
||||
scan(l.head);
|
||||
}
|
||||
}
|
||||
|
||||
// process all the nested classes
|
||||
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
|
||||
if (l.head.hasTag(CLASSDEF)) {
|
||||
scan(l.head);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
pendingExits = pendingExitsPrev;
|
||||
nextadr = nextadrPrev;
|
||||
firstadr = firstadrPrev;
|
||||
classDef = classDefPrev;
|
||||
}
|
||||
} finally {
|
||||
lint = lintPrev;
|
||||
pendingExits = pendingExitsPrev;
|
||||
nextadr = nextadrPrev;
|
||||
firstadr = firstadrPrev;
|
||||
classDef = classDefPrev;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2485,87 +2443,81 @@ public class Flow {
|
||||
return;
|
||||
}
|
||||
|
||||
Lint lintPrev = lint;
|
||||
lint = lint.augment(tree.sym);
|
||||
final Bits initsPrev = new Bits(inits);
|
||||
final Bits uninitsPrev = new Bits(uninits);
|
||||
int nextadrPrev = nextadr;
|
||||
int firstadrPrev = firstadr;
|
||||
int returnadrPrev = returnadr;
|
||||
|
||||
Assert.check(pendingExits.isEmpty());
|
||||
boolean isConstructorPrev = isConstructor;
|
||||
try {
|
||||
final Bits initsPrev = new Bits(inits);
|
||||
final Bits uninitsPrev = new Bits(uninits);
|
||||
int nextadrPrev = nextadr;
|
||||
int firstadrPrev = firstadr;
|
||||
int returnadrPrev = returnadr;
|
||||
isConstructor = TreeInfo.isConstructor(tree);
|
||||
|
||||
Assert.check(pendingExits.isEmpty());
|
||||
boolean isConstructorPrev = isConstructor;
|
||||
try {
|
||||
isConstructor = TreeInfo.isConstructor(tree);
|
||||
// We only track field initialization inside constructors
|
||||
if (!isConstructor) {
|
||||
firstadr = nextadr;
|
||||
}
|
||||
|
||||
// We only track field initialization inside constructors
|
||||
if (!isConstructor) {
|
||||
firstadr = nextadr;
|
||||
}
|
||||
// Mark all method parameters as DA
|
||||
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
|
||||
JCVariableDecl def = l.head;
|
||||
scan(def);
|
||||
Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
|
||||
/* If we are executing the code from Gen, then there can be
|
||||
* synthetic or mandated variables, ignore them.
|
||||
*/
|
||||
initParam(def);
|
||||
}
|
||||
// else we are in an instance initializer block;
|
||||
// leave caught unchanged.
|
||||
scan(tree.body);
|
||||
|
||||
// Mark all method parameters as DA
|
||||
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
|
||||
JCVariableDecl def = l.head;
|
||||
scan(def);
|
||||
Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
|
||||
/* If we are executing the code from Gen, then there can be
|
||||
* synthetic or mandated variables, ignore them.
|
||||
*/
|
||||
initParam(def);
|
||||
}
|
||||
// else we are in an instance initializer block;
|
||||
// leave caught unchanged.
|
||||
scan(tree.body);
|
||||
|
||||
boolean isCompactOrGeneratedRecordConstructor = (tree.sym.flags() & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
|
||||
(tree.sym.flags() & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD);
|
||||
if (isConstructor) {
|
||||
boolean isSynthesized = (tree.sym.flags() &
|
||||
GENERATEDCONSTR) != 0;
|
||||
for (int i = firstadr; i < nextadr; i++) {
|
||||
JCVariableDecl vardecl = vardecls[i];
|
||||
VarSymbol var = vardecl.sym;
|
||||
if (var.owner == classDef.sym && !var.isStatic()) {
|
||||
// choose the diagnostic position based on whether
|
||||
// the ctor is default(synthesized) or not
|
||||
if (isSynthesized && !isCompactOrGeneratedRecordConstructor) {
|
||||
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
|
||||
var, Errors.VarNotInitializedInDefaultConstructor(var));
|
||||
} else if (isCompactOrGeneratedRecordConstructor) {
|
||||
boolean isInstanceRecordField = var.enclClass().isRecord() &&
|
||||
(var.flags_field & (Flags.PRIVATE | Flags.FINAL | Flags.GENERATED_MEMBER | Flags.RECORD)) != 0 &&
|
||||
var.owner.kind == TYP;
|
||||
if (isInstanceRecordField) {
|
||||
boolean notInitialized = !inits.isMember(var.adr);
|
||||
if (notInitialized && uninits.isMember(var.adr) && tree.completesNormally) {
|
||||
/* this way we indicate Lower that it should generate an initialization for this field
|
||||
* in the compact constructor
|
||||
*/
|
||||
var.flags_field |= UNINITIALIZED_FIELD;
|
||||
} else {
|
||||
checkInit(TreeInfo.diagEndPos(endPositions, tree.body), var);
|
||||
}
|
||||
boolean isCompactOrGeneratedRecordConstructor = (tree.sym.flags() & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0 ||
|
||||
(tree.sym.flags() & (GENERATEDCONSTR | RECORD)) == (GENERATEDCONSTR | RECORD);
|
||||
if (isConstructor) {
|
||||
boolean isSynthesized = (tree.sym.flags() &
|
||||
GENERATEDCONSTR) != 0;
|
||||
for (int i = firstadr; i < nextadr; i++) {
|
||||
JCVariableDecl vardecl = vardecls[i];
|
||||
VarSymbol var = vardecl.sym;
|
||||
if (var.owner == classDef.sym && !var.isStatic()) {
|
||||
// choose the diagnostic position based on whether
|
||||
// the ctor is default(synthesized) or not
|
||||
if (isSynthesized && !isCompactOrGeneratedRecordConstructor) {
|
||||
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
|
||||
var, Errors.VarNotInitializedInDefaultConstructor(var));
|
||||
} else if (isCompactOrGeneratedRecordConstructor) {
|
||||
boolean isInstanceRecordField = var.enclClass().isRecord() &&
|
||||
(var.flags_field & (Flags.PRIVATE | Flags.FINAL | Flags.GENERATED_MEMBER | Flags.RECORD)) != 0 &&
|
||||
var.owner.kind == TYP;
|
||||
if (isInstanceRecordField) {
|
||||
boolean notInitialized = !inits.isMember(var.adr);
|
||||
if (notInitialized && uninits.isMember(var.adr) && tree.completesNormally) {
|
||||
/* this way we indicate Lower that it should generate an initialization for this field
|
||||
* in the compact constructor
|
||||
*/
|
||||
var.flags_field |= UNINITIALIZED_FIELD;
|
||||
} else {
|
||||
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), var);
|
||||
checkInit(TreeInfo.diagEndPos(endPositions, tree.body), var);
|
||||
}
|
||||
} else {
|
||||
checkInit(TreeInfo.diagEndPos(endPositions, tree.body), var);
|
||||
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl), var);
|
||||
}
|
||||
} else {
|
||||
checkInit(TreeInfo.diagEndPos(endPositions, tree.body), var);
|
||||
}
|
||||
}
|
||||
}
|
||||
clearPendingExits(true);
|
||||
} finally {
|
||||
inits.assign(initsPrev);
|
||||
uninits.assign(uninitsPrev);
|
||||
nextadr = nextadrPrev;
|
||||
firstadr = firstadrPrev;
|
||||
returnadr = returnadrPrev;
|
||||
isConstructor = isConstructorPrev;
|
||||
}
|
||||
clearPendingExits(true);
|
||||
} finally {
|
||||
lint = lintPrev;
|
||||
inits.assign(initsPrev);
|
||||
uninits.assign(uninitsPrev);
|
||||
nextadr = nextadrPrev;
|
||||
firstadr = firstadrPrev;
|
||||
returnadr = returnadrPrev;
|
||||
isConstructor = isConstructorPrev;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2593,21 +2545,15 @@ public class Flow {
|
||||
}
|
||||
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
Lint lintPrev = lint;
|
||||
lint = lint.augment(tree.sym);
|
||||
try{
|
||||
boolean track = trackable(tree.sym);
|
||||
if (track && (tree.sym.owner.kind == MTH || tree.sym.owner.kind == VAR)) {
|
||||
newVar(tree);
|
||||
boolean track = trackable(tree.sym);
|
||||
if (track && (tree.sym.owner.kind == MTH || tree.sym.owner.kind == VAR)) {
|
||||
newVar(tree);
|
||||
}
|
||||
if (tree.init != null) {
|
||||
scanExpr(tree.init);
|
||||
if (track) {
|
||||
letInit(tree.pos(), tree.sym);
|
||||
}
|
||||
if (tree.init != null) {
|
||||
scanExpr(tree.init);
|
||||
if (track) {
|
||||
letInit(tree.pos(), tree.sym);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lint = lintPrev;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2859,8 +2805,7 @@ public class Flow {
|
||||
final Bits uninitsEnd = new Bits(uninits);
|
||||
int nextadrCatch = nextadr;
|
||||
|
||||
if (!resourceVarDecls.isEmpty() &&
|
||||
lint.isEnabled(Lint.LintCategory.TRY)) {
|
||||
if (!resourceVarDecls.isEmpty()) {
|
||||
for (JCVariableDecl resVar : resourceVarDecls) {
|
||||
if (unrefdResources.includes(resVar.sym) && !resVar.sym.isUnnamedVariable()) {
|
||||
log.warning(resVar.pos(),
|
||||
|
||||
@ -66,7 +66,6 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
private final Annotate annotate;
|
||||
private final Types types;
|
||||
private final Names names;
|
||||
private final DeferredLintHandler deferredLintHandler;
|
||||
|
||||
public static MemberEnter instance(Context context) {
|
||||
MemberEnter instance = context.get(memberEnterKey);
|
||||
@ -87,7 +86,6 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
types = Types.instance(context);
|
||||
source = Source.instance(context);
|
||||
names = Names.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
}
|
||||
|
||||
/** Construct method type from method signature.
|
||||
@ -194,16 +192,11 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
Env<AttrContext> localEnv = methodEnv(tree, env);
|
||||
deferredLintHandler.push(tree);
|
||||
try {
|
||||
// Compute the method type
|
||||
m.type = signature(m, tree.typarams, tree.params,
|
||||
tree.restype, tree.recvparam,
|
||||
tree.thrown,
|
||||
localEnv);
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
}
|
||||
// Compute the method type
|
||||
m.type = signature(m, tree.typarams, tree.params,
|
||||
tree.restype, tree.recvparam,
|
||||
tree.thrown,
|
||||
localEnv);
|
||||
|
||||
if (types.isSignaturePolymorphic(m)) {
|
||||
m.flags_field |= SIGNATURE_POLYMORPHIC;
|
||||
@ -227,14 +220,14 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
enclScope.enter(m);
|
||||
}
|
||||
|
||||
annotate.annotateLater(tree.mods.annotations, localEnv, m, tree);
|
||||
annotate.annotateLater(tree.mods.annotations, localEnv, m);
|
||||
// Visit the signature of the method. Note that
|
||||
// TypeAnnotate doesn't descend into the body.
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, m, tree);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, m);
|
||||
|
||||
if (tree.defaultValue != null) {
|
||||
m.defaultValue = annotate.unfinishedDefaultValue(); // set it to temporary sentinel for now
|
||||
annotate.annotateDefaultValueLater(tree.defaultValue, localEnv, m, tree);
|
||||
annotate.annotateDefaultValueLater(tree.defaultValue, localEnv, m);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,18 +256,13 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
localEnv = env.dup(tree, env.info.dup());
|
||||
localEnv.info.staticLevel++;
|
||||
}
|
||||
deferredLintHandler.push(tree);
|
||||
|
||||
try {
|
||||
if (TreeInfo.isEnumInit(tree)) {
|
||||
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
|
||||
} else if (!tree.isImplicitlyTyped()) {
|
||||
attr.attribType(tree.vartype, localEnv);
|
||||
if (TreeInfo.isReceiverParam(tree))
|
||||
checkReceiver(tree, localEnv);
|
||||
}
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
if (TreeInfo.isEnumInit(tree)) {
|
||||
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
|
||||
} else if (!tree.isImplicitlyTyped()) {
|
||||
attr.attribType(tree.vartype, localEnv);
|
||||
if (TreeInfo.isReceiverParam(tree))
|
||||
checkReceiver(tree, localEnv);
|
||||
}
|
||||
|
||||
if ((tree.mods.flags & VARARGS) != 0) {
|
||||
@ -315,9 +303,9 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
annotate.annotateLater(tree.mods.annotations, localEnv, v, tree);
|
||||
annotate.annotateLater(tree.mods.annotations, localEnv, v);
|
||||
if (!tree.isImplicitlyTyped()) {
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.vartype, localEnv, v, tree);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.vartype, localEnv, v);
|
||||
}
|
||||
|
||||
v.pos = tree.pos;
|
||||
|
||||
@ -52,7 +52,6 @@ import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.source.tree.ModuleTree.ModuleKind;
|
||||
import com.sun.tools.javac.code.DeferredLintHandler;
|
||||
import com.sun.tools.javac.code.Directive;
|
||||
import com.sun.tools.javac.code.Directive.ExportsDirective;
|
||||
import com.sun.tools.javac.code.Directive.ExportsFlag;
|
||||
@ -103,6 +102,7 @@ import com.sun.tools.javac.tree.JCTree.Tag;
|
||||
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.JCDiagnostic.DiagnosticFlag;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
@ -141,7 +141,6 @@ public class Modules extends JCTree.Visitor {
|
||||
private final Attr attr;
|
||||
private final Check chk;
|
||||
private final Preview preview;
|
||||
private final DeferredLintHandler deferredLintHandler;
|
||||
private final TypeEnvs typeEnvs;
|
||||
private final Types types;
|
||||
private final JavaFileManager fileManager;
|
||||
@ -169,8 +168,6 @@ public class Modules extends JCTree.Visitor {
|
||||
private final String moduleVersionOpt;
|
||||
private final boolean sourceLauncher;
|
||||
|
||||
private final boolean lintOptions;
|
||||
|
||||
private Set<ModuleSymbol> rootModules = null;
|
||||
private final Set<ModuleSymbol> warnedMissing = new HashSet<>();
|
||||
|
||||
@ -193,7 +190,6 @@ public class Modules extends JCTree.Visitor {
|
||||
attr = Attr.instance(context);
|
||||
chk = Check.instance(context);
|
||||
preview = Preview.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
typeEnvs = TypeEnvs.instance(context);
|
||||
moduleFinder = ModuleFinder.instance(context);
|
||||
types = Types.instance(context);
|
||||
@ -205,8 +201,6 @@ public class Modules extends JCTree.Visitor {
|
||||
|
||||
allowAccessIntoSystem = options.isUnset(Option.RELEASE);
|
||||
|
||||
lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
|
||||
|
||||
multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
classWriter.multiModuleMode = multiModuleMode;
|
||||
@ -746,7 +740,6 @@ public class Modules extends JCTree.Visitor {
|
||||
ModuleVisitor v = new ModuleVisitor();
|
||||
JavaFileObject prev = log.useSource(tree.sourcefile);
|
||||
JCModuleDecl moduleDecl = tree.getModuleDecl();
|
||||
deferredLintHandler.push(moduleDecl);
|
||||
|
||||
try {
|
||||
moduleDecl.accept(v);
|
||||
@ -754,7 +747,6 @@ public class Modules extends JCTree.Visitor {
|
||||
checkCyclicDependencies(moduleDecl);
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
deferredLintHandler.pop();
|
||||
msym.flags_field &= ~UNATTRIBUTED;
|
||||
}
|
||||
}
|
||||
@ -795,7 +787,12 @@ public class Modules extends JCTree.Visitor {
|
||||
sym.requires = List.nil();
|
||||
sym.exports = List.nil();
|
||||
sym.opens = List.nil();
|
||||
tree.directives.forEach(t -> t.accept(this));
|
||||
Lint prevLint = chk.setLint(lint.augment(sym));
|
||||
try {
|
||||
tree.directives.forEach(t -> t.accept(this));
|
||||
} finally {
|
||||
chk.setLint(prevLint);
|
||||
}
|
||||
sym.requires = sym.requires.reverse();
|
||||
sym.exports = sym.exports.reverse();
|
||||
sym.opens = sym.opens.reverse();
|
||||
@ -991,13 +988,11 @@ public class Modules extends JCTree.Visitor {
|
||||
UsesProvidesVisitor v = new UsesProvidesVisitor(msym, env);
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
JCModuleDecl decl = env.toplevel.getModuleDecl();
|
||||
deferredLintHandler.push(decl);
|
||||
|
||||
try {
|
||||
decl.accept(v);
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
deferredLintHandler.pop();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1263,12 +1258,9 @@ public class Modules extends JCTree.Visitor {
|
||||
}
|
||||
observable = computeTransitiveClosure(limitMods, rootModules, null);
|
||||
observable.addAll(rootModules);
|
||||
if (lintOptions) {
|
||||
for (ModuleSymbol msym : limitMods) {
|
||||
if (!observable.contains(msym)) {
|
||||
log.warning(
|
||||
LintWarnings.ModuleForOptionNotFound(Option.LIMIT_MODULES, msym));
|
||||
}
|
||||
for (ModuleSymbol msym : limitMods) {
|
||||
if (!observable.contains(msym)) {
|
||||
log.warning(LintWarnings.ModuleForOptionNotFound(Option.LIMIT_MODULES, msym), DiagnosticFlag.DEFAULT_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1721,10 +1713,7 @@ public class Modules extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
if (!unknownModules.contains(msym)) {
|
||||
if (lintOptions) {
|
||||
log.warning(
|
||||
LintWarnings.ModuleForOptionNotFound(Option.ADD_EXPORTS, msym));
|
||||
}
|
||||
log.warning(LintWarnings.ModuleForOptionNotFound(Option.ADD_EXPORTS, msym), DiagnosticFlag.DEFAULT_ENABLED);
|
||||
unknownModules.add(msym);
|
||||
}
|
||||
return false;
|
||||
@ -1760,9 +1749,7 @@ public class Modules extends JCTree.Visitor {
|
||||
|
||||
ModuleSymbol msym = syms.enterModule(names.fromString(sourceName));
|
||||
if (!allModules.contains(msym)) {
|
||||
if (lintOptions) {
|
||||
log.warning(LintWarnings.ModuleForOptionNotFound(Option.ADD_READS, msym));
|
||||
}
|
||||
log.warning(LintWarnings.ModuleForOptionNotFound(Option.ADD_READS, msym), DiagnosticFlag.DEFAULT_ENABLED);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1780,9 +1767,8 @@ public class Modules extends JCTree.Visitor {
|
||||
continue;
|
||||
targetModule = syms.enterModule(names.fromString(targetName));
|
||||
if (!allModules.contains(targetModule)) {
|
||||
if (lintOptions) {
|
||||
log.warning(LintWarnings.ModuleForOptionNotFound(Option.ADD_READS, targetModule));
|
||||
}
|
||||
log.warning(LintWarnings.ModuleForOptionNotFound(Option.ADD_READS, targetModule),
|
||||
DiagnosticFlag.DEFAULT_ENABLED);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +108,6 @@ public class TypeEnter implements Completer {
|
||||
private final Annotate annotate;
|
||||
private final TypeAnnotations typeAnnotations;
|
||||
private final Types types;
|
||||
private final DeferredLintHandler deferredLintHandler;
|
||||
private final Lint lint;
|
||||
private final TypeEnvs typeEnvs;
|
||||
private final Dependencies dependencies;
|
||||
@ -135,7 +134,6 @@ public class TypeEnter implements Completer {
|
||||
annotate = Annotate.instance(context);
|
||||
typeAnnotations = TypeAnnotations.instance(context);
|
||||
types = Types.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
lint = Lint.instance(context);
|
||||
typeEnvs = TypeEnvs.instance(context);
|
||||
dependencies = Dependencies.instance(context);
|
||||
@ -274,7 +272,6 @@ public class TypeEnter implements Completer {
|
||||
queue.add(env);
|
||||
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
deferredLintHandler.push(tree);
|
||||
try {
|
||||
dependencies.push(env.enclClass.sym, phaseName);
|
||||
runPhase(env);
|
||||
@ -282,7 +279,6 @@ public class TypeEnter implements Completer {
|
||||
chk.completionError(tree.pos(), ex);
|
||||
} finally {
|
||||
dependencies.pop();
|
||||
deferredLintHandler.pop();
|
||||
log.useSource(prev);
|
||||
}
|
||||
}
|
||||
@ -365,7 +361,6 @@ public class TypeEnter implements Completer {
|
||||
|
||||
ImportFilter prevStaticImportFilter = staticImportFilter;
|
||||
ImportFilter prevTypeImportFilter = typeImportFilter;
|
||||
deferredLintHandler.pushImmediate(lint);
|
||||
Lint prevLint = chk.setLint(lint);
|
||||
Env<AttrContext> prevEnv = this.env;
|
||||
try {
|
||||
@ -390,20 +385,14 @@ public class TypeEnter implements Completer {
|
||||
handleImports(tree.getImports());
|
||||
|
||||
if (decl != null) {
|
||||
deferredLintHandler.push(decl);
|
||||
try {
|
||||
//check @Deprecated:
|
||||
markDeprecated(decl.sym, decl.mods.annotations, env);
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
}
|
||||
//check for @Deprecated annotations
|
||||
markDeprecated(decl.sym, decl.mods.annotations, env);
|
||||
// process module annotations
|
||||
annotate.annotateLater(decl.mods.annotations, env, env.toplevel.modle, decl);
|
||||
annotate.annotateLater(decl.mods.annotations, env, env.toplevel.modle);
|
||||
}
|
||||
} finally {
|
||||
this.env = prevEnv;
|
||||
chk.setLint(prevLint);
|
||||
deferredLintHandler.pop();
|
||||
this.staticImportFilter = prevStaticImportFilter;
|
||||
this.typeImportFilter = prevTypeImportFilter;
|
||||
}
|
||||
@ -436,7 +425,7 @@ public class TypeEnter implements Completer {
|
||||
}
|
||||
}
|
||||
// process package annotations
|
||||
annotate.annotateLater(tree.annotations, env, env.toplevel.packge, tree);
|
||||
annotate.annotateLater(tree.annotations, env, env.toplevel.packge);
|
||||
}
|
||||
|
||||
private void doImport(JCImport tree, boolean fromModuleImport) {
|
||||
@ -928,9 +917,9 @@ public class TypeEnter implements Completer {
|
||||
Env<AttrContext> baseEnv = baseEnv(tree, env);
|
||||
|
||||
if (tree.extending != null)
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.extending, baseEnv, sym, tree);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tree.extending, baseEnv, sym);
|
||||
for (JCExpression impl : tree.implementing)
|
||||
annotate.queueScanTreeAndTypeAnnotate(impl, baseEnv, sym, tree);
|
||||
annotate.queueScanTreeAndTypeAnnotate(impl, baseEnv, sym);
|
||||
annotate.flush();
|
||||
|
||||
attribSuperTypes(env, baseEnv);
|
||||
@ -945,11 +934,11 @@ public class TypeEnter implements Completer {
|
||||
chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet);
|
||||
}
|
||||
|
||||
annotate.annotateLater(tree.mods.annotations, baseEnv, sym, tree);
|
||||
annotate.annotateLater(tree.mods.annotations, baseEnv, sym);
|
||||
attr.attribTypeVariables(tree.typarams, baseEnv, false);
|
||||
|
||||
for (JCTypeParameter tp : tree.typarams)
|
||||
annotate.queueScanTreeAndTypeAnnotate(tp, baseEnv, sym, tree);
|
||||
annotate.queueScanTreeAndTypeAnnotate(tp, baseEnv, sym);
|
||||
|
||||
// check that no package exists with same fully qualified name,
|
||||
// but admit classes in the unnamed package which have the same
|
||||
|
||||
@ -92,7 +92,7 @@ public abstract class BaseFileManager implements JavaFileManager {
|
||||
options = Options.instance(context);
|
||||
|
||||
// Initialize locations
|
||||
locations.update(log, lint, FSInfo.instance(context));
|
||||
locations.update(log, FSInfo.instance(context));
|
||||
|
||||
// Apply options
|
||||
options.whenReady(this::applyOptions);
|
||||
|
||||
@ -77,14 +77,11 @@ import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardJavaFileManager.PathFactory;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
|
||||
import jdk.internal.jmod.JmodFile;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Errors;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
|
||||
import com.sun.tools.javac.util.DefinedBy;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
@ -127,11 +124,6 @@ public class Locations {
|
||||
*/
|
||||
private FSInfo fsInfo;
|
||||
|
||||
/**
|
||||
* The root {@link Lint} instance.
|
||||
*/
|
||||
private Lint lint;
|
||||
|
||||
private ModuleNameReader moduleNameReader;
|
||||
|
||||
private PathFactory pathFactory = Paths::get;
|
||||
@ -172,9 +164,8 @@ public class Locations {
|
||||
}
|
||||
}
|
||||
|
||||
void update(Log log, Lint lint, FSInfo fsInfo) {
|
||||
void update(Log log, FSInfo fsInfo) {
|
||||
this.log = log;
|
||||
this.lint = lint;
|
||||
this.fsInfo = fsInfo;
|
||||
}
|
||||
|
||||
@ -225,7 +216,7 @@ public class Locations {
|
||||
try {
|
||||
entries.add(getPath(s));
|
||||
} catch (IllegalArgumentException e) {
|
||||
lint.logIfEnabled(LintWarnings.InvalidPath(s));
|
||||
log.warning(LintWarnings.InvalidPath(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,7 +310,7 @@ public class Locations {
|
||||
private void addDirectory(Path dir, boolean warn) {
|
||||
if (!Files.isDirectory(dir)) {
|
||||
if (warn) {
|
||||
lint.logIfEnabled(LintWarnings.DirPathElementNotFound(dir));
|
||||
log.warning(LintWarnings.DirPathElementNotFound(dir));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -364,7 +355,7 @@ public class Locations {
|
||||
if (!fsInfo.exists(file)) {
|
||||
/* No such file or directory exists */
|
||||
if (warn) {
|
||||
lint.logIfEnabled(LintWarnings.PathElementNotFound(file));
|
||||
log.warning(LintWarnings.PathElementNotFound(file));
|
||||
}
|
||||
super.add(file);
|
||||
return;
|
||||
@ -386,12 +377,12 @@ public class Locations {
|
||||
try {
|
||||
FileSystems.newFileSystem(file, (ClassLoader)null).close();
|
||||
if (warn) {
|
||||
lint.logIfEnabled(LintWarnings.UnexpectedArchiveFile(file));
|
||||
log.warning(LintWarnings.UnexpectedArchiveFile(file));
|
||||
}
|
||||
} catch (IOException | ProviderNotFoundException e) {
|
||||
// FIXME: include e.getLocalizedMessage in warning
|
||||
if (warn) {
|
||||
lint.logIfEnabled(LintWarnings.InvalidArchiveFile(file));
|
||||
log.warning(LintWarnings.InvalidArchiveFile(file));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1654,7 +1645,7 @@ public class Locations {
|
||||
|
||||
void add(Map<String, List<Path>> map, Path prefix, Path suffix) {
|
||||
if (!Files.isDirectory(prefix)) {
|
||||
lint.logIfEnabled(Files.exists(prefix) ?
|
||||
log.warning(Files.exists(prefix) ?
|
||||
LintWarnings.DirPathElementNotDirectory(prefix) :
|
||||
LintWarnings.DirPathElementNotFound(prefix));
|
||||
return;
|
||||
|
||||
@ -51,7 +51,6 @@ import com.sun.tools.javac.comp.Annotate;
|
||||
import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Directive.*;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
@ -139,9 +138,6 @@ public class ClassReader {
|
||||
/** The symbol table. */
|
||||
Symtab syms;
|
||||
|
||||
/** The root Lint config. */
|
||||
Lint lint;
|
||||
|
||||
Types types;
|
||||
|
||||
/** The name table. */
|
||||
@ -303,8 +299,6 @@ public class ClassReader {
|
||||
|
||||
typevars = WriteableScope.create(syms.noSymbol);
|
||||
|
||||
lint = Lint.instance(context);
|
||||
|
||||
initAttributeReaders();
|
||||
}
|
||||
|
||||
@ -854,8 +848,7 @@ public class ClassReader {
|
||||
if (!warnedAttrs.contains(name)) {
|
||||
JavaFileObject prev = log.useSource(currentClassFile);
|
||||
try {
|
||||
lint.logIfEnabled(
|
||||
LintWarnings.FutureAttr(name, version.major, version.minor, majorVersion, minorVersion));
|
||||
log.warning(LintWarnings.FutureAttr(name, version.major, version.minor, majorVersion, minorVersion));
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
}
|
||||
@ -1608,7 +1601,7 @@ public class ClassReader {
|
||||
} else if (parameterAnnotations.length != numParameters) {
|
||||
//the RuntimeVisibleParameterAnnotations and RuntimeInvisibleParameterAnnotations
|
||||
//provide annotations for a different number of parameters, ignore:
|
||||
lint.logIfEnabled(LintWarnings.RuntimeVisibleInvisibleParamAnnotationsMismatch(currentClassFile));
|
||||
log.warning(LintWarnings.RuntimeVisibleInvisibleParamAnnotationsMismatch(currentClassFile));
|
||||
for (int pnum = 0; pnum < numParameters; pnum++) {
|
||||
readAnnotations();
|
||||
}
|
||||
@ -2074,9 +2067,9 @@ public class ClassReader {
|
||||
JavaFileObject prevSource = log.useSource(requestingOwner.classfile);
|
||||
try {
|
||||
if (failure == null) {
|
||||
lint.logIfEnabled(LintWarnings.AnnotationMethodNotFound(container, name));
|
||||
log.warning(LintWarnings.AnnotationMethodNotFound(container, name));
|
||||
} else {
|
||||
lint.logIfEnabled(LintWarnings.AnnotationMethodNotFoundReason(container,
|
||||
log.warning(LintWarnings.AnnotationMethodNotFoundReason(container,
|
||||
name,
|
||||
failure.getDetailValue()));//diagnostic, if present
|
||||
}
|
||||
@ -2954,7 +2947,7 @@ public class ClassReader {
|
||||
|
||||
private void dropParameterAnnotations() {
|
||||
parameterAnnotations = null;
|
||||
lint.logIfEnabled(LintWarnings.RuntimeInvisibleParameterAnnotations(currentClassFile));
|
||||
log.warning(LintWarnings.RuntimeInvisibleParameterAnnotations(currentClassFile));
|
||||
}
|
||||
/**
|
||||
* Creates the parameter at the position {@code mpIndex} in the parameter list of the owning method.
|
||||
|
||||
@ -28,11 +28,12 @@ package com.sun.tools.javac.launcher;
|
||||
import com.sun.source.util.TaskEvent;
|
||||
import com.sun.source.util.TaskListener;
|
||||
import com.sun.tools.javac.api.JavacTool;
|
||||
import com.sun.tools.javac.code.Preview;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.resources.LauncherProperties.Errors;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Context.Factory;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
@ -120,8 +121,11 @@ final class MemoryContext {
|
||||
}
|
||||
var opts = options.forProgramCompilation();
|
||||
var context = new Context();
|
||||
MemoryPreview.registerInstance(context);
|
||||
var task = compiler.getTask(out, memoryFileManager, null, opts, null, units, context);
|
||||
|
||||
// This suppresses diagnostics like "Note: Recompile with -Xlint:preview for details."
|
||||
Log.instance(context).suppressAggregatedWarningNotes(LintCategory.PREVIEW);
|
||||
|
||||
var ok = task.call();
|
||||
if (!ok) {
|
||||
throw new Fault(Errors.CompilationFailed);
|
||||
@ -269,19 +273,4 @@ final class MemoryContext {
|
||||
controller.enableNativeAccess(module);
|
||||
}
|
||||
}
|
||||
|
||||
static class MemoryPreview extends Preview {
|
||||
static void registerInstance(Context context) {
|
||||
context.put(previewKey, (Factory<Preview>)MemoryPreview::new);
|
||||
}
|
||||
|
||||
MemoryPreview(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportDeferredDiagnostics() {
|
||||
// suppress diagnostics like "Note: Recompile with -Xlint:preview for details."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.JCDiagnostic;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
|
||||
import com.sun.tools.javac.util.List;
|
||||
@ -503,13 +504,9 @@ public class Arguments {
|
||||
}
|
||||
} else {
|
||||
// single-module or legacy mode
|
||||
boolean lintPaths = options.isUnset(Option.XLINT_CUSTOM,
|
||||
"-" + LintCategory.PATH.option);
|
||||
if (lintPaths) {
|
||||
Path outDirParent = outDir.getParent();
|
||||
if (outDirParent != null && Files.exists(outDirParent.resolve("module-info.class"))) {
|
||||
log.warning(LintWarnings.OutdirIsInExplodedModule(outDir));
|
||||
}
|
||||
Path outDirParent = outDir.getParent();
|
||||
if (outDirParent != null && Files.exists(outDirParent.resolve("module-info.class"))) {
|
||||
log.warning(LintWarnings.OutdirIsInExplodedModule(outDir), DiagnosticFlag.DEFAULT_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -577,15 +574,16 @@ public class Arguments {
|
||||
reportDiag(Errors.SourcepathModulesourcepathConflict);
|
||||
}
|
||||
|
||||
boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
|
||||
if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
|
||||
if (source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
|
||||
if (fm instanceof BaseFileManager baseFileManager) {
|
||||
if (source.compareTo(Source.JDK8) <= 0) {
|
||||
if (baseFileManager.isDefaultBootClassPath())
|
||||
log.warning(LintWarnings.SourceNoBootclasspath(source.name, releaseNote(source, targetString)));
|
||||
} else {
|
||||
if (baseFileManager.isDefaultSystemModulesPath())
|
||||
log.warning(LintWarnings.SourceNoSystemModulesPath(source.name, releaseNote(source, targetString)));
|
||||
if (baseFileManager.isDefaultBootClassPath()) {
|
||||
log.warning(LintWarnings.SourceNoBootclasspath(source.name, releaseNote(source, targetString)),
|
||||
DiagnosticFlag.DEFAULT_ENABLED);
|
||||
}
|
||||
} else if (baseFileManager.isDefaultSystemModulesPath()) {
|
||||
log.warning(LintWarnings.SourceNoSystemModulesPath(source.name, releaseNote(source, targetString)),
|
||||
DiagnosticFlag.DEFAULT_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -594,15 +592,15 @@ public class Arguments {
|
||||
|
||||
if (source.compareTo(Source.MIN) < 0) {
|
||||
log.error(Errors.OptionRemovedSource(source.name, Source.MIN.name));
|
||||
} else if (source == Source.MIN && lintOptions) {
|
||||
log.warning(LintWarnings.OptionObsoleteSource(source.name));
|
||||
} else if (source == Source.MIN) {
|
||||
log.warning(LintWarnings.OptionObsoleteSource(source.name), DiagnosticFlag.DEFAULT_ENABLED);
|
||||
obsoleteOptionFound = true;
|
||||
}
|
||||
|
||||
if (target.compareTo(Target.MIN) < 0) {
|
||||
log.error(Errors.OptionRemovedTarget(target, Target.MIN));
|
||||
} else if (target == Target.MIN && lintOptions) {
|
||||
log.warning(LintWarnings.OptionObsoleteTarget(target));
|
||||
} else if (target == Target.MIN) {
|
||||
log.warning(LintWarnings.OptionObsoleteTarget(target), DiagnosticFlag.DEFAULT_ENABLED);
|
||||
obsoleteOptionFound = true;
|
||||
}
|
||||
|
||||
@ -635,8 +633,8 @@ public class Arguments {
|
||||
log.error(Errors.ProcessorpathNoProcessormodulepath);
|
||||
}
|
||||
|
||||
if (obsoleteOptionFound && lintOptions) {
|
||||
log.warning(LintWarnings.OptionObsoleteSuppression);
|
||||
if (obsoleteOptionFound) {
|
||||
log.warning(LintWarnings.OptionObsoleteSuppression, DiagnosticFlag.DEFAULT_ENABLED);
|
||||
}
|
||||
|
||||
SourceVersion sv = Source.toSourceVersion(source);
|
||||
@ -646,8 +644,8 @@ public class Arguments {
|
||||
validateLimitModules(sv);
|
||||
validateDefaultModuleForCreatedFiles(sv);
|
||||
|
||||
if (lintOptions && options.isSet(Option.ADD_OPENS)) {
|
||||
log.warning(LintWarnings.AddopensIgnored);
|
||||
if (options.isSet(Option.ADD_OPENS)) {
|
||||
log.warning(LintWarnings.AddopensIgnored, DiagnosticFlag.DEFAULT_ENABLED);
|
||||
}
|
||||
|
||||
return !errors && (log.nerrors == 0);
|
||||
|
||||
@ -79,6 +79,7 @@ import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.Context.Key;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Factory;
|
||||
import com.sun.tools.javac.util.LintMapper;
|
||||
import com.sun.tools.javac.util.Log.DiagnosticHandler;
|
||||
import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
|
||||
import com.sun.tools.javac.util.Log.WriterKind;
|
||||
@ -262,6 +263,10 @@ public class JavaCompiler {
|
||||
*/
|
||||
protected JNIWriter jniWriter;
|
||||
|
||||
/** The Lint mapper.
|
||||
*/
|
||||
protected LintMapper lintMapper;
|
||||
|
||||
/** The module for the symbol table entry phases.
|
||||
*/
|
||||
protected Enter enter;
|
||||
@ -274,10 +279,6 @@ public class JavaCompiler {
|
||||
*/
|
||||
protected Source source;
|
||||
|
||||
/** The preview language version.
|
||||
*/
|
||||
protected Preview preview;
|
||||
|
||||
/** The module for code generation.
|
||||
*/
|
||||
protected Gen gen;
|
||||
@ -392,6 +393,7 @@ public class JavaCompiler {
|
||||
|
||||
names = Names.instance(context);
|
||||
log = Log.instance(context);
|
||||
lintMapper = LintMapper.instance(context);
|
||||
diagFactory = JCDiagnostic.Factory.instance(context);
|
||||
finder = ClassFinder.instance(context);
|
||||
reader = ClassReader.instance(context);
|
||||
@ -413,7 +415,6 @@ public class JavaCompiler {
|
||||
log.error(Errors.CantAccess(ex.sym, ex.getDetailValue()));
|
||||
}
|
||||
source = Source.instance(context);
|
||||
preview = Preview.instance(context);
|
||||
attr = Attr.instance(context);
|
||||
analyzer = Analyzer.instance(context);
|
||||
chk = Check.instance(context);
|
||||
@ -584,6 +585,7 @@ public class JavaCompiler {
|
||||
/** The number of errors reported so far.
|
||||
*/
|
||||
public int errorCount() {
|
||||
log.reportOutstandingWarnings();
|
||||
if (werror && log.nerrors == 0 && log.nwarnings > 0) {
|
||||
log.error(Errors.WarningsAndWerror);
|
||||
}
|
||||
@ -634,6 +636,7 @@ public class JavaCompiler {
|
||||
private JCCompilationUnit parse(JavaFileObject filename, CharSequence content, boolean silent) {
|
||||
long msec = now();
|
||||
JCCompilationUnit tree = make.TopLevel(List.nil());
|
||||
lintMapper.startParsingFile(filename);
|
||||
if (content != null) {
|
||||
if (verbose) {
|
||||
log.printVerbose("parsing.started", filename);
|
||||
@ -653,6 +656,7 @@ public class JavaCompiler {
|
||||
}
|
||||
|
||||
tree.sourcefile = filename;
|
||||
lintMapper.finishParsingFile(tree);
|
||||
|
||||
if (content != null && !taskListener.isEmpty() && !silent) {
|
||||
TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);
|
||||
@ -1852,8 +1856,8 @@ public class JavaCompiler {
|
||||
else
|
||||
log.warning(Warnings.ProcUseProcOrImplicit);
|
||||
}
|
||||
chk.reportDeferredDiagnostics();
|
||||
preview.reportDeferredDiagnostics();
|
||||
log.reportOutstandingWarnings();
|
||||
log.reportOutstandingNotes();
|
||||
if (log.compressedOutput) {
|
||||
log.mandatoryNote(null, Notes.CompressedDiags);
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
package com.sun.tools.javac.parser;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.code.Preview;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
@ -83,7 +82,7 @@ public class JavaTokenizer extends UnicodeReader {
|
||||
/**
|
||||
* The log to be used for error reporting. Copied from scanner factory.
|
||||
*/
|
||||
private final Log log;
|
||||
protected final Log log;
|
||||
|
||||
/**
|
||||
* The token factory. Copied from scanner factory.
|
||||
@ -135,13 +134,6 @@ public class JavaTokenizer extends UnicodeReader {
|
||||
*/
|
||||
protected boolean hasEscapeSequences;
|
||||
|
||||
/**
|
||||
* The set of lint options currently in effect. It is initialized
|
||||
* from the context, and then is set/reset as needed by Attr as it
|
||||
* visits all the various parts of the trees during attribution.
|
||||
*/
|
||||
protected final Lint lint;
|
||||
|
||||
/**
|
||||
* Construct a Java token scanner from the input character buffer.
|
||||
*
|
||||
@ -168,7 +160,6 @@ public class JavaTokenizer extends UnicodeReader {
|
||||
this.source = fac.source;
|
||||
this.preview = fac.preview;
|
||||
this.enableLineDocComments = fac.enableLineDocComments;
|
||||
this.lint = fac.lint;
|
||||
this.sb = new StringBuilder(256);
|
||||
}
|
||||
|
||||
@ -218,17 +209,6 @@ public class JavaTokenizer extends UnicodeReader {
|
||||
errPos = pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a warning at the given position using the provided arguments.
|
||||
*
|
||||
* @param pos position in input buffer.
|
||||
* @param key error key to report.
|
||||
*/
|
||||
protected void lexWarning(int pos, JCDiagnostic.LintWarning key) {
|
||||
DiagnosticPosition dp = new SimpleDiagnosticPosition(pos) ;
|
||||
log.warning(dp, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a character to the literal buffer.
|
||||
*
|
||||
@ -1069,17 +1049,13 @@ public class JavaTokenizer extends UnicodeReader {
|
||||
// If a text block.
|
||||
if (isTextBlock) {
|
||||
// Verify that the incidental indentation is consistent.
|
||||
if (lint.isEnabled(LintCategory.TEXT_BLOCKS)) {
|
||||
Set<TextBlockSupport.WhitespaceChecks> checks =
|
||||
TextBlockSupport.checkWhitespace(string);
|
||||
if (checks.contains(TextBlockSupport.WhitespaceChecks.INCONSISTENT)) {
|
||||
lexWarning(pos,
|
||||
LintWarnings.InconsistentWhiteSpaceIndentation);
|
||||
}
|
||||
if (checks.contains(TextBlockSupport.WhitespaceChecks.TRAILING)) {
|
||||
lexWarning(pos,
|
||||
LintWarnings.TrailingWhiteSpaceWillBeRemoved);
|
||||
}
|
||||
Set<TextBlockSupport.WhitespaceChecks> checks =
|
||||
TextBlockSupport.checkWhitespace(string);
|
||||
if (checks.contains(TextBlockSupport.WhitespaceChecks.INCONSISTENT)) {
|
||||
log.warning(pos, LintWarnings.InconsistentWhiteSpaceIndentation);
|
||||
}
|
||||
if (checks.contains(TextBlockSupport.WhitespaceChecks.TRAILING)) {
|
||||
log.warning(pos, LintWarnings.TrailingWhiteSpaceWillBeRemoved);
|
||||
}
|
||||
// Remove incidental indentation.
|
||||
try {
|
||||
|
||||
@ -113,12 +113,6 @@ public class JavacParser implements Parser {
|
||||
/** End position mappings container */
|
||||
protected final AbstractEndPosTable endPosTable;
|
||||
|
||||
/** A map associating "other nearby documentation comments"
|
||||
* with the preferred documentation comment for a declaration. */
|
||||
protected Map<Comment, List<Comment>> danglingComments = new HashMap<>();
|
||||
/** Handler for deferred diagnostics. */
|
||||
protected final DeferredLintHandler deferredLintHandler;
|
||||
|
||||
// Because of javac's limited lookahead, some contexts are ambiguous in
|
||||
// the presence of type annotations even though they are not ambiguous
|
||||
// in the absence of type annotations. Consider this code:
|
||||
@ -189,7 +183,6 @@ public class JavacParser implements Parser {
|
||||
this.names = fac.names;
|
||||
this.source = fac.source;
|
||||
this.preview = fac.preview;
|
||||
this.deferredLintHandler = fac.deferredLintHandler;
|
||||
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
|
||||
this.keepDocComments = keepDocComments;
|
||||
this.parseModuleInfo = parseModuleInfo;
|
||||
@ -214,7 +207,6 @@ public class JavacParser implements Parser {
|
||||
this.names = parser.names;
|
||||
this.source = parser.source;
|
||||
this.preview = parser.preview;
|
||||
this.deferredLintHandler = parser.deferredLintHandler;
|
||||
this.allowStringFolding = parser.allowStringFolding;
|
||||
this.keepDocComments = parser.keepDocComments;
|
||||
this.parseModuleInfo = false;
|
||||
@ -582,17 +574,8 @@ public class JavacParser implements Parser {
|
||||
* (using {@code token.getDocComment()}.
|
||||
* 3. At the end of the "signature" of the declaration
|
||||
* (that is, before any initialization or body for the
|
||||
* declaration) any other "recent" comments are saved
|
||||
* in a map using the primary comment as a key,
|
||||
* using this method, {@code saveDanglingComments}.
|
||||
* 4. When the tree node for the declaration is finally
|
||||
* available, and the primary comment, if any,
|
||||
* is "attached", (in {@link #attach}) any related
|
||||
* dangling comments are also attached to the tree node
|
||||
* by registering them using the {@link #deferredLintHandler}.
|
||||
* 5. (Later) Warnings may be generated for the dangling
|
||||
* comments, subject to the {@code -Xlint} and
|
||||
* {@code @SuppressWarnings}.
|
||||
* declaration) any other "recent" comments are
|
||||
* reported to the log as warnings.
|
||||
*
|
||||
* @param dc the primary documentation comment
|
||||
*/
|
||||
@ -612,21 +595,16 @@ public class JavacParser implements Parser {
|
||||
}
|
||||
}
|
||||
|
||||
var lb = new ListBuffer<Comment>();
|
||||
while (!recentComments.isEmpty()) {
|
||||
var c = recentComments.remove();
|
||||
if (c != dc) {
|
||||
lb.add(c);
|
||||
reportDanglingDocComment(c);
|
||||
}
|
||||
}
|
||||
danglingComments.put(dc, lb.toList());
|
||||
}
|
||||
|
||||
/** Make an entry into docComments hashtable,
|
||||
* provided flag keepDocComments is set and given doc comment is non-null.
|
||||
* If there are any related "dangling comments", register
|
||||
* diagnostics to be handled later, when @SuppressWarnings
|
||||
* can be taken into account.
|
||||
*
|
||||
* @param tree The tree to be used as index in the hashtable
|
||||
* @param dc The doc comment to associate with the tree, or null.
|
||||
@ -636,31 +614,11 @@ public class JavacParser implements Parser {
|
||||
if (keepDocComments && dc != null) {
|
||||
docComments.putComment(tree, dc);
|
||||
}
|
||||
reportDanglingComments(tree, dc);
|
||||
return tree;
|
||||
}
|
||||
|
||||
/** Reports all dangling comments associated with the
|
||||
* primary comment for a declaration against the position
|
||||
* of the tree node for a declaration.
|
||||
*
|
||||
* @param tree the tree node for the declaration
|
||||
* @param dc the primary comment for the declaration
|
||||
*/
|
||||
void reportDanglingComments(JCTree tree, Comment dc) {
|
||||
var list = danglingComments.remove(dc);
|
||||
if (list != null) {
|
||||
deferredLintHandler.push(tree);
|
||||
try {
|
||||
list.forEach(this::reportDanglingDocComment);
|
||||
} finally {
|
||||
deferredLintHandler.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports an individual dangling comment using the {@link #deferredLintHandler}.
|
||||
* Reports an individual dangling comment as a warning to the log.
|
||||
* The comment may or not may generate an actual diagnostic, depending on
|
||||
* the settings for {@code -Xlint} and/or {@code @SuppressWarnings}.
|
||||
*
|
||||
@ -668,14 +626,8 @@ public class JavacParser implements Parser {
|
||||
*/
|
||||
void reportDanglingDocComment(Comment c) {
|
||||
var pos = c.getPos();
|
||||
if (pos != null) {
|
||||
deferredLintHandler.report(lint -> {
|
||||
if (lint.isEnabled(Lint.LintCategory.DANGLING_DOC_COMMENTS) &&
|
||||
!shebang(c, pos)) {
|
||||
log.warning(
|
||||
pos, LintWarnings.DanglingDocComment);
|
||||
}
|
||||
});
|
||||
if (pos != null && !shebang(c, pos)) {
|
||||
S.lintWarning(pos, LintWarnings.DanglingDocComment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, 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,6 +28,8 @@ package com.sun.tools.javac.parser;
|
||||
import java.util.Queue;
|
||||
|
||||
import com.sun.tools.javac.parser.Tokens.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
|
||||
import com.sun.tools.javac.util.Position.LineMap;
|
||||
|
||||
/**
|
||||
@ -103,4 +105,12 @@ public interface Lexer {
|
||||
* token.
|
||||
*/
|
||||
Queue<Comment> getDocComments();
|
||||
|
||||
/**
|
||||
* Report a warning that is subject to possible suppression by {@code @SuppressWarnings}.
|
||||
*
|
||||
* @param pos the lexical position at which the warning occurs
|
||||
* @param key the warning to report
|
||||
*/
|
||||
void lintWarning(DiagnosticPosition pos, LintWarning key);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, 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,7 +28,6 @@ package com.sun.tools.javac.parser;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.sun.tools.javac.api.JavacTrees;
|
||||
import com.sun.tools.javac.code.DeferredLintHandler;
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Preview;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
@ -70,7 +69,6 @@ public class ParserFactory {
|
||||
final Options options;
|
||||
final ScannerFactory scannerFactory;
|
||||
final Locale locale;
|
||||
final DeferredLintHandler deferredLintHandler;
|
||||
|
||||
private final JavacTrees trees;
|
||||
|
||||
@ -88,7 +86,6 @@ public class ParserFactory {
|
||||
this.options = Options.instance(context);
|
||||
this.scannerFactory = ScannerFactory.instance(context);
|
||||
this.locale = context.get(Locale.class);
|
||||
this.deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
this.trees = JavacTrees.instance(context);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, 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
|
||||
@ -31,6 +31,8 @@ import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Queue;
|
||||
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
|
||||
import com.sun.tools.javac.util.Position.LineMap;
|
||||
import static com.sun.tools.javac.parser.Tokens.*;
|
||||
|
||||
@ -150,6 +152,11 @@ public class Scanner implements Lexer {
|
||||
return docComments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lintWarning(DiagnosticPosition pos, LintWarning key) {
|
||||
tokenizer.log.warning(pos, key);
|
||||
}
|
||||
|
||||
public int errPos() {
|
||||
return tokenizer.errPos();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, 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,7 +27,6 @@ package com.sun.tools.javac.parser;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Preview;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
@ -62,7 +61,6 @@ public class ScannerFactory {
|
||||
final Source source;
|
||||
final Preview preview;
|
||||
final Tokens tokens;
|
||||
final Lint lint;
|
||||
final boolean enableLineDocComments;
|
||||
|
||||
/** Create a new scanner factory. */
|
||||
@ -74,7 +72,6 @@ public class ScannerFactory {
|
||||
this.source = Source.instance(context);
|
||||
this.preview = Preview.instance(context);
|
||||
this.tokens = Tokens.instance(context);
|
||||
this.lint = Lint.instance(context);
|
||||
var options = Options.instance(context);
|
||||
this.enableLineDocComments = !options.isSet(Option.DISABLE_LINE_DOC_COMMENTS);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2025, 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 com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCErroneous;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.Error;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Position.LineMap;
|
||||
|
||||
@ -167,10 +168,9 @@ public class VirtualParser extends JavacParser {
|
||||
return S.getLineMap();
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
for (int i = 0 ; i < offset ; i++) {
|
||||
S.nextToken(); // advance underlying lexer until position matches
|
||||
}
|
||||
@Override
|
||||
public void lintWarning(DiagnosticPosition pos, LintWarning key) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,6 @@ import javax.tools.JavaFileManager.Location;
|
||||
import static javax.tools.StandardLocation.SOURCE_OUTPUT;
|
||||
import static javax.tools.StandardLocation.CLASS_OUTPUT;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
@ -62,7 +61,6 @@ import com.sun.tools.javac.resources.CompilerProperties.Warnings;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
|
||||
import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
|
||||
@ -338,7 +336,6 @@ public class JavacFiler implements Filer, Closeable {
|
||||
JavaFileManager fileManager;
|
||||
JavacElements elementUtils;
|
||||
Log log;
|
||||
Lint lint;
|
||||
Modules modules;
|
||||
Names names;
|
||||
Symtab syms;
|
||||
@ -421,8 +418,6 @@ public class JavacFiler implements Filer, Closeable {
|
||||
aggregateGeneratedClassNames = new LinkedHashSet<>();
|
||||
initialClassNames = new LinkedHashSet<>();
|
||||
|
||||
lint = Lint.instance(context);
|
||||
|
||||
Options options = Options.instance(context);
|
||||
|
||||
defaultTargetModule = options.get(Option.DEFAULT_MODULE_FOR_CREATED_FILES);
|
||||
@ -486,14 +481,12 @@ public class JavacFiler implements Filer, Closeable {
|
||||
private JavaFileObject createSourceOrClassFile(ModuleSymbol mod, boolean isSourceFile, String name, Element... originatingElements) throws IOException {
|
||||
Assert.checkNonNull(mod);
|
||||
|
||||
if (lint.isEnabled(PROCESSING)) {
|
||||
int periodIndex = name.lastIndexOf(".");
|
||||
if (periodIndex != -1) {
|
||||
String base = name.substring(periodIndex);
|
||||
String extn = (isSourceFile ? ".java" : ".class");
|
||||
if (base.equals(extn))
|
||||
log.warning(LintWarnings.ProcSuspiciousClassName(name, extn));
|
||||
}
|
||||
int periodIndex = name.lastIndexOf(".");
|
||||
if (periodIndex != -1) {
|
||||
String base = name.substring(periodIndex);
|
||||
String extn = (isSourceFile ? ".java" : ".class");
|
||||
if (base.equals(extn))
|
||||
log.warning(LintWarnings.ProcSuspiciousClassName(name, extn));
|
||||
}
|
||||
checkNameAndExistence(mod, name, isSourceFile);
|
||||
Location loc = (isSourceFile ? SOURCE_OUTPUT : CLASS_OUTPUT);
|
||||
@ -707,7 +700,7 @@ public class JavacFiler implements Filer, Closeable {
|
||||
|
||||
private void checkName(String name, boolean allowUnnamedPackageInfo) throws FilerException {
|
||||
if (!SourceVersion.isName(name) && !isPackageInfo(name, allowUnnamedPackageInfo)) {
|
||||
lint.logIfEnabled(LintWarnings.ProcIllegalFileName(name));
|
||||
log.warning(LintWarnings.ProcIllegalFileName(name));
|
||||
throw new FilerException("Illegal name " + name);
|
||||
}
|
||||
}
|
||||
@ -735,11 +728,11 @@ public class JavacFiler implements Filer, Closeable {
|
||||
initialClassNames.contains(typename) ||
|
||||
containedInInitialInputs(typename);
|
||||
if (alreadySeen) {
|
||||
lint.logIfEnabled(LintWarnings.ProcTypeRecreate(typename));
|
||||
log.warning(LintWarnings.ProcTypeRecreate(typename));
|
||||
throw new FilerException("Attempt to recreate a file for type " + typename);
|
||||
}
|
||||
if (existing != null) {
|
||||
lint.logIfEnabled(LintWarnings.ProcTypeAlreadyExists(typename));
|
||||
log.warning(LintWarnings.ProcTypeAlreadyExists(typename));
|
||||
}
|
||||
if (!mod.isUnnamed() && !typename.contains(".")) {
|
||||
throw new FilerException("Attempt to create a type in unnamed package of a named module: " + typename);
|
||||
@ -768,7 +761,7 @@ public class JavacFiler implements Filer, Closeable {
|
||||
*/
|
||||
private void checkFileReopening(FileObject fileObject, boolean forWriting) throws FilerException {
|
||||
if (isInFileObjectHistory(fileObject, forWriting)) {
|
||||
lint.logIfEnabled(LintWarnings.ProcFileReopening(fileObject.getName()));
|
||||
log.warning(LintWarnings.ProcFileReopening(fileObject.getName()));
|
||||
throw new FilerException("Attempt to reopen a file for path " + fileObject.getName());
|
||||
}
|
||||
if (forWriting)
|
||||
|
||||
@ -123,7 +123,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
private final Modules modules;
|
||||
private final Types types;
|
||||
private final Annotate annotate;
|
||||
private final Lint lint;
|
||||
|
||||
/**
|
||||
* Holds relevant state history of which processors have been
|
||||
@ -206,7 +205,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
printProcessorInfo = options.isSet(Option.XPRINTPROCESSORINFO);
|
||||
printRounds = options.isSet(Option.XPRINTROUNDS);
|
||||
verbose = options.isSet(Option.VERBOSE);
|
||||
lint = Lint.instance(context);
|
||||
compiler = JavaCompiler.instance(context);
|
||||
if (options.isSet(Option.PROC, "only") || options.isSet(Option.XPRINT)) {
|
||||
compiler.shouldStopPolicyIfNoError = CompileState.PROCESS;
|
||||
@ -626,7 +624,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
private Set<String> supportedOptionNames;
|
||||
|
||||
ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh,
|
||||
boolean allowModules, ProcessingEnvironment env, Lint lint) {
|
||||
boolean allowModules, ProcessingEnvironment env) {
|
||||
processor = p;
|
||||
contributed = false;
|
||||
|
||||
@ -647,10 +645,9 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
boolean patternAdded = supportedAnnotationStrings.add(annotationPattern);
|
||||
|
||||
supportedAnnotationPatterns.
|
||||
add(importStringToPattern(allowModules, annotationPattern,
|
||||
processor, log, lint));
|
||||
add(importStringToPattern(allowModules, annotationPattern, processor, log));
|
||||
if (!patternAdded) {
|
||||
lint.logIfEnabled(LintWarnings.ProcDuplicateSupportedAnnotation(annotationPattern,
|
||||
log.warning(LintWarnings.ProcDuplicateSupportedAnnotation(annotationPattern,
|
||||
p.getClass().getName()));
|
||||
}
|
||||
}
|
||||
@ -663,7 +660,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
// and "foo.bar.*".
|
||||
if (supportedAnnotationPatterns.contains(MatchingUtils.validImportStringToPattern("*")) &&
|
||||
supportedAnnotationPatterns.size() > 1) {
|
||||
lint.logIfEnabled(LintWarnings.ProcRedundantTypesWithWildcard(p.getClass().getName()));
|
||||
log.warning(LintWarnings.ProcRedundantTypesWithWildcard(p.getClass().getName()));
|
||||
}
|
||||
|
||||
supportedOptionNames = new LinkedHashSet<>();
|
||||
@ -671,8 +668,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
if (checkOptionName(optionName, log)) {
|
||||
boolean optionAdded = supportedOptionNames.add(optionName);
|
||||
if (!optionAdded) {
|
||||
lint.logIfEnabled(LintWarnings.ProcDuplicateOptionName(optionName,
|
||||
p.getClass().getName()));
|
||||
log.warning(LintWarnings.ProcDuplicateOptionName(optionName, p.getClass().getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -759,8 +755,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
|
||||
log, source, dcfh,
|
||||
Feature.MODULES.allowedInSource(source),
|
||||
JavacProcessingEnvironment.this,
|
||||
lint);
|
||||
JavacProcessingEnvironment.this);
|
||||
psi.procStateList.add(ps);
|
||||
return ps;
|
||||
} else
|
||||
@ -888,7 +883,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
unmatchedAnnotations.remove("");
|
||||
|
||||
if (lint.isEnabled(PROCESSING) && unmatchedAnnotations.size() > 0) {
|
||||
if (unmatchedAnnotations.size() > 0) {
|
||||
// Remove annotations processed by javac
|
||||
unmatchedAnnotations.keySet().removeAll(platformAnnotations);
|
||||
if (unmatchedAnnotations.size() > 0) {
|
||||
@ -1649,7 +1644,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
* regex matching that string. If the string is not a valid
|
||||
* import-style string, return a regex that won't match anything.
|
||||
*/
|
||||
private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log, Lint lint) {
|
||||
private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log) {
|
||||
String module;
|
||||
String pkg;
|
||||
int slash = s.indexOf('/');
|
||||
@ -1662,7 +1657,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
} else {
|
||||
String moduleName = s.substring(0, slash);
|
||||
if (!SourceVersion.isName(moduleName)) {
|
||||
return warnAndNoMatches(s, p, log, lint);
|
||||
return warnAndNoMatches(s, p, log);
|
||||
}
|
||||
module = Pattern.quote(moduleName + "/");
|
||||
// And warn if module is specified if modules aren't supported, conditional on -Xlint:proc?
|
||||
@ -1671,12 +1666,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
if (MatchingUtils.isValidImportString(pkg)) {
|
||||
return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg));
|
||||
} else {
|
||||
return warnAndNoMatches(s, p, log, lint);
|
||||
return warnAndNoMatches(s, p, log);
|
||||
}
|
||||
}
|
||||
|
||||
private static Pattern warnAndNoMatches(String s, Processor p, Log log, Lint lint) {
|
||||
lint.logIfEnabled(LintWarnings.ProcMalformedSupportedString(s, p.getClass().getName()));
|
||||
private static Pattern warnAndNoMatches(String s, Processor p, Log log) {
|
||||
log.warning(LintWarnings.ProcMalformedSupportedString(s, p.getClass().getName()));
|
||||
return noMatches; // won't match any valid identifier
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, 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,7 @@
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.tools.JavaFileObject;
|
||||
@ -159,35 +160,46 @@ public abstract class AbstractLog {
|
||||
* maximum number of warnings has been reached.
|
||||
*
|
||||
* @param warningKey The key for the localized warning message.
|
||||
* @param flags Any additional flags required
|
||||
*/
|
||||
public void warning(Warning warningKey) {
|
||||
report(diags.warning(source, null, warningKey));
|
||||
public void warning(Warning warningKey, DiagnosticFlag... flags) {
|
||||
warning(null, warningKey, flags);
|
||||
}
|
||||
|
||||
/** Report a warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param warningKey The key for the localized warning message.
|
||||
* @param flags Any additional flags required
|
||||
*/
|
||||
public void warning(DiagnosticPosition pos, Warning warningKey) {
|
||||
report(diags.warning(source, pos, warningKey));
|
||||
public void warning(int pos, Warning warningKey, DiagnosticFlag... flags) {
|
||||
warning(wrap(pos), warningKey, flags);
|
||||
}
|
||||
|
||||
/** Report a warning, unless suppressed by the -nowarn option or the
|
||||
* maximum number of warnings has been reached.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param warningKey The key for the localized warning message.
|
||||
* @param flags Any additional flags required
|
||||
*/
|
||||
public void warning(int pos, Warning warningKey) {
|
||||
report(diags.warning(source, wrap(pos), warningKey));
|
||||
public void warning(DiagnosticPosition pos, Warning warningKey, DiagnosticFlag... flags) {
|
||||
EnumSet<DiagnosticFlag> flagSet = EnumSet.noneOf(DiagnosticFlag.class);
|
||||
for (DiagnosticFlag flag : flags)
|
||||
flagSet.add(flag);
|
||||
report(diags.create(flagSet, source, pos, warningKey));
|
||||
}
|
||||
|
||||
/** Report a warning.
|
||||
/** Report a mandatory warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param warningKey The key for the localized warning message.
|
||||
* @param flags Any additional flags required
|
||||
*/
|
||||
public void mandatoryWarning(DiagnosticPosition pos, Warning warningKey) {
|
||||
report(diags.mandatoryWarning(source, pos, warningKey));
|
||||
public void mandatoryWarning(DiagnosticPosition pos, Warning warningKey, DiagnosticFlag... flags) {
|
||||
DiagnosticFlag[] flags2 = new DiagnosticFlag[flags.length + 2];
|
||||
System.arraycopy(flags, 0, flags2, 0, flags.length);
|
||||
flags2[flags.length + 0] = DiagnosticFlag.MANDATORY;
|
||||
flags2[flags.length + 1] = DiagnosticFlag.DEFAULT_ENABLED;
|
||||
warning(pos, warningKey, flags2);
|
||||
}
|
||||
|
||||
/** Provide a non-fatal notification, unless suppressed by the -nowarn option.
|
||||
|
||||
@ -115,33 +115,6 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
return diag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
|
||||
* @param lc The lint category for the diagnostic
|
||||
* @param source The source of the compilation unit, if any, in which to report the warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param key The key for the localized warning message.
|
||||
* @param args Fields of the warning message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic mandatoryWarning(
|
||||
LintCategory lc,
|
||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||
return mandatoryWarning(source, pos, warningKey(lc, key, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic that will not be hidden by the -nowarn or -Xlint:none options.
|
||||
* @param source The source of the compilation unit, if any, in which to report the warning.
|
||||
* @param pos The source position at which to report the warning.
|
||||
* @param warningKey The key for the localized warning message.
|
||||
* @see MandatoryWarningHandler
|
||||
*/
|
||||
public JCDiagnostic mandatoryWarning(
|
||||
DiagnosticSource source, DiagnosticPosition pos, Warning warningKey) {
|
||||
return create(EnumSet.of(DiagnosticFlag.MANDATORY), source, pos, warningKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a warning diagnostic.
|
||||
* @param lc The lint category for the diagnostic
|
||||
@ -447,6 +420,16 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
RECOVERABLE,
|
||||
NON_DEFERRABLE,
|
||||
COMPRESSED,
|
||||
/** Flag for lint diagnostics that should be emitted even when their category
|
||||
* is not explicitly enabled, as long as it is not explicitly suppressed.
|
||||
*/
|
||||
DEFAULT_ENABLED,
|
||||
/** Flags mandatory warnings that should pass through a mandatory warning aggregator.
|
||||
*/
|
||||
AGGREGATE,
|
||||
/** Flag that requests verbose logging through the mandatory warning aggregator.
|
||||
*/
|
||||
AGGREGATE_VERBOSE,
|
||||
/** Flag for diagnostics that were reported through API methods.
|
||||
*/
|
||||
API,
|
||||
|
||||
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.tools.javac.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.TreeInfo;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
* Maps source code positions to the applicable {@link Lint} instance based on {@link -Xlint}
|
||||
* command line flags and {@code @SuppressWarnings} annotations on containing declarations.
|
||||
*
|
||||
* <p>
|
||||
* This mapping can't be cannot be calculated until after attribution. As each top-level
|
||||
* declaration (class, package, or module) is attributed, this singleton is notified by
|
||||
* Attr and the {@link Lint}s contained in that declaration are calculated.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class LintMapper {
|
||||
|
||||
// The key for the context singleton
|
||||
private static final Context.Key<LintMapper> CONTEXT_KEY = new Context.Key<>();
|
||||
|
||||
// Per-source file lint information
|
||||
private final Map<JavaFileObject, FileInfo> fileInfoMap = new HashMap<>();
|
||||
|
||||
// Compiler context
|
||||
private final Context context;
|
||||
|
||||
// This calculates the Lint instances that apply to various source code ranges
|
||||
private final LintSpanCalculator lintSpanCalculator = new LintSpanCalculator();
|
||||
|
||||
// The root Lint instance, calculated on-demand to avoid init loops
|
||||
private Lint rootLint;
|
||||
|
||||
/**
|
||||
* Obtain the {@link LintMapper} context singleton.
|
||||
*/
|
||||
public static LintMapper instance(Context context) {
|
||||
LintMapper instance = context.get(CONTEXT_KEY);
|
||||
if (instance == null)
|
||||
instance = new LintMapper(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@SuppressWarnings("this-escape")
|
||||
protected LintMapper(Context context) {
|
||||
context.put(CONTEXT_KEY, this);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private Lint rootLint() {
|
||||
if (rootLint == null)
|
||||
rootLint = Lint.instance(context);
|
||||
return rootLint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given file is known to this instance.
|
||||
*
|
||||
* @param sourceFile source file
|
||||
* @return true if file is recognized
|
||||
*/
|
||||
public boolean isKnown(JavaFileObject sourceFile) {
|
||||
return fileInfoMap.containsKey(sourceFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the {@link Lint} configuration that applies at the given position, if known.
|
||||
*
|
||||
* @param sourceFile source file
|
||||
* @param pos source position
|
||||
* @return the applicable {@link Lint}, if known
|
||||
*/
|
||||
public Optional<Lint> lintAt(JavaFileObject sourceFile, DiagnosticPosition pos) {
|
||||
|
||||
// If the file is completely unknown, we don't know
|
||||
FileInfo fileInfo = fileInfoMap.get(sourceFile);
|
||||
if (fileInfo == null)
|
||||
return Optional.empty();
|
||||
|
||||
// If the file hasn't been fully parsed yet, we don't know what Lint applies yet
|
||||
if (!fileInfo.parsed)
|
||||
return Optional.empty();
|
||||
|
||||
// Find the top-level declaration that contains pos; if there is none, then the root lint applies
|
||||
Span declSpan = fileInfo.findDeclSpan(pos);
|
||||
if (declSpan == null)
|
||||
return Optional.of(rootLint());
|
||||
|
||||
// Have we attributed this top-level declaration? If not, we don't know what Lint applies yet
|
||||
List<LintSpan> lintSpans = fileInfo.lintSpanMap.get(declSpan);
|
||||
if (lintSpans == null)
|
||||
return Optional.empty();
|
||||
|
||||
// Find the narrowest containing LintSpan; if there is none, then the root lint applies
|
||||
return FileInfo.bestMatch(lintSpans, pos)
|
||||
.map(lintSpan -> lintSpan.lint)
|
||||
.or(() -> Optional.of(rootLint()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate {@lint Lint} configurations for all positions within the given top-level declaration.
|
||||
*
|
||||
* @param sourceFile source file
|
||||
* @param tree top-level declaration (class, package, or module)
|
||||
*/
|
||||
public void calculateLints(JavaFileObject sourceFile, JCTree tree, EndPosTable endPositions) {
|
||||
|
||||
// Get the info for this file
|
||||
FileInfo fileInfo = fileInfoMap.get(sourceFile);
|
||||
|
||||
// Sanity checks
|
||||
Assert.check(isTopLevelDecl(tree));
|
||||
Assert.check(fileInfo != null && fileInfo.parsed);
|
||||
Span declSpan = new Span(tree, endPositions);
|
||||
Assert.check(fileInfo.lintSpanMap.containsKey(declSpan), "unknown declaration");
|
||||
Assert.check(fileInfo.lintSpanMap.get(declSpan) == null, "duplicate calculateLints()");
|
||||
|
||||
// Build the list of lints for declarations within the top-level declaration
|
||||
fileInfo.lintSpanMap.put(declSpan, lintSpanCalculator.calculate(endPositions, tree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset this instance (except for listeners).
|
||||
*/
|
||||
public void clear() {
|
||||
fileInfoMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when file parsing starts to create an entry for the new file.
|
||||
*/
|
||||
public void startParsingFile(JavaFileObject sourceFile) {
|
||||
fileInfoMap.put(sourceFile, new FileInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when file parsing completes to identify the top-level declarations.
|
||||
*/
|
||||
public void finishParsingFile(JCCompilationUnit tree) {
|
||||
|
||||
// Get info for this file
|
||||
FileInfo fileInfo = fileInfoMap.get(tree.sourcefile);
|
||||
Assert.check(fileInfo != null, () -> "unknown source " + tree.sourcefile);
|
||||
Assert.check(!fileInfo.parsed, () -> "source already parsed: " + tree.sourcefile);
|
||||
Assert.check(fileInfo.lintSpanMap.isEmpty(), () -> "duplicate invocation for " + tree.sourcefile);
|
||||
|
||||
// Mark file as parsed
|
||||
fileInfo.parsed = true;
|
||||
|
||||
// Create an entry in lintSpanMap for each top-level declaration, with a null value for now
|
||||
tree.defs.stream()
|
||||
.filter(this::isTopLevelDecl)
|
||||
.map(decl -> new Span(decl, tree.endPositions))
|
||||
.forEach(span -> fileInfo.lintSpanMap.put(span, null));
|
||||
}
|
||||
|
||||
private boolean isTopLevelDecl(JCTree tree) {
|
||||
return tree.getTag() == Tag.MODULEDEF
|
||||
|| tree.getTag() == Tag.PACKAGEDEF
|
||||
|| tree.getTag() == Tag.CLASSDEF;
|
||||
}
|
||||
|
||||
// FileInfo
|
||||
|
||||
/**
|
||||
* Holds the calculated {@link Lint}s for top-level declarations in some source file.
|
||||
*
|
||||
* <p>
|
||||
* Instances evolve through these states:
|
||||
* <ul>
|
||||
* <li>Before the file has been completely parsed, {@code #parsed} is false and {@link #lintSpanMap} is empty.
|
||||
* <li>Immediately after the file has been parsed, {@code #parsed} is true and {@link #lintSpanMap} contains
|
||||
* zero or more entries corresponding to the top-level declarations in the file, but whose values are null.
|
||||
* <li>As each top-level declaration is attributed, the entries in {@link #lintSpanMap} are updated to non-null.
|
||||
* </ul>
|
||||
*/
|
||||
private static class FileInfo {
|
||||
|
||||
final Map<Span, List<LintSpan>> lintSpanMap = new HashMap<>();
|
||||
boolean parsed;
|
||||
|
||||
// Find the top-level declaration containing the given position
|
||||
Span findDeclSpan(DiagnosticPosition pos) {
|
||||
return lintSpanMap.keySet().stream()
|
||||
.filter(span -> span.contains(pos))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
// Find the narrowest span in the given list that contains the given position
|
||||
static Optional<LintSpan> bestMatch(List<LintSpan> lintSpans, DiagnosticPosition pos) {
|
||||
int position = pos.getStartPosition();
|
||||
Assert.check(position != Position.NOPOS);
|
||||
LintSpan bestSpan = null;
|
||||
for (LintSpan lintSpan : lintSpans) {
|
||||
if (lintSpan.contains(position) && (bestSpan == null || bestSpan.contains(lintSpan))) {
|
||||
bestSpan = lintSpan;
|
||||
}
|
||||
}
|
||||
return Optional.ofNullable(bestSpan);
|
||||
}
|
||||
}
|
||||
|
||||
// Span
|
||||
|
||||
/**
|
||||
* Represents a lexical range in a file.
|
||||
*/
|
||||
private static class Span {
|
||||
|
||||
final int startPos;
|
||||
final int endPos;
|
||||
|
||||
Span(int startPos, int endPos) {
|
||||
this.startPos = startPos;
|
||||
this.endPos = endPos;
|
||||
}
|
||||
|
||||
Span(JCTree tree, EndPosTable endPositions) {
|
||||
this(TreeInfo.getStartPos(tree), TreeInfo.endPos(endPositions, tree));
|
||||
}
|
||||
|
||||
boolean contains(int pos) {
|
||||
return pos == startPos || (pos > startPos && pos < endPos);
|
||||
}
|
||||
|
||||
boolean contains(DiagnosticPosition pos) {
|
||||
return contains(pos.getStartPosition());
|
||||
}
|
||||
|
||||
boolean contains(Span that) {
|
||||
return this.startPos <= that.startPos && this.endPos >= that.endPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Integer.hashCode(startPos) ^ Integer.hashCode(endPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj == null || obj.getClass() != this.getClass())
|
||||
return false;
|
||||
final Span that = (Span)obj;
|
||||
return this.startPos == that.startPos && this.endPos == that.endPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Span[%d-%d]", startPos, endPos);
|
||||
}
|
||||
}
|
||||
|
||||
// LintSpan
|
||||
|
||||
/**
|
||||
* Represents a lexical range and the {@link Lint} configuration that applies therein.
|
||||
*/
|
||||
private static class LintSpan extends Span {
|
||||
|
||||
final Lint lint;
|
||||
|
||||
LintSpan(int startPos, int endPos, Lint lint) {
|
||||
super(startPos, endPos);
|
||||
this.lint = lint;
|
||||
}
|
||||
|
||||
LintSpan(JCTree tree, EndPosTable endPositions, Lint lint) {
|
||||
super(tree, endPositions);
|
||||
this.lint = lint;
|
||||
}
|
||||
|
||||
// Note: no need for equals() or hashCode() here
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("LintSpan[%d-%d, lint=%s]", startPos, endPos, lint);
|
||||
}
|
||||
}
|
||||
|
||||
// LintSpanCalculator
|
||||
|
||||
private class LintSpanCalculator extends TreeScanner {
|
||||
|
||||
private EndPosTable endPositions;
|
||||
private Lint currentLint;
|
||||
private List<LintSpan> lintSpans;
|
||||
|
||||
List<LintSpan> calculate(EndPosTable endPositions, JCTree tree) {
|
||||
this.endPositions = endPositions;
|
||||
currentLint = rootLint();
|
||||
lintSpans = new ArrayList<>();
|
||||
try {
|
||||
scan(tree);
|
||||
return lintSpans;
|
||||
} finally {
|
||||
lintSpans = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitModuleDef(JCModuleDecl tree) {
|
||||
scanDecl(tree, tree.sym, super::visitModuleDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPackageDef(JCPackageDecl tree) {
|
||||
scanDecl(tree, tree.packge, super::visitPackageDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
scanDecl(tree, tree.sym, super::visitClassDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
scanDecl(tree, tree.sym, super::visitMethodDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
scanDecl(tree, tree.sym, super::visitVarDef);
|
||||
}
|
||||
|
||||
private <T extends JCTree> void scanDecl(T tree, Symbol symbol, Consumer<? super T> recursion) {
|
||||
Lint previousLint = currentLint;
|
||||
currentLint = Optional.ofNullable(symbol) // symbol can be null if there were earlier errors
|
||||
.map(currentLint::augment)
|
||||
.orElse(currentLint);
|
||||
recursion.accept(tree);
|
||||
if (currentLint != previousLint) { // Lint.augment() returns the same object if no change
|
||||
lintSpans.add(new LintSpan(tree, endPositions, currentLint));
|
||||
currentLint = previousLint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -30,26 +30,48 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.main.Main;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.TreeInfo;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
|
||||
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
|
||||
import static com.sun.tools.javac.code.Lint.LintCategory.*;
|
||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||
|
||||
/** A class for error logs. Reports errors and warnings, and
|
||||
* keeps track of error numbers and positions.
|
||||
@ -98,6 +120,11 @@ public class Log extends AbstractLog {
|
||||
*/
|
||||
protected final DiagnosticHandler prev;
|
||||
|
||||
/**
|
||||
* Diagnostics waiting for an applicable {@link Lint} instance.
|
||||
*/
|
||||
protected Map<JavaFileObject, List<JCDiagnostic>> lintWaitersMap = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Install this diagnostic handler as the current one,
|
||||
* recording the previous one.
|
||||
@ -111,6 +138,55 @@ public class Log extends AbstractLog {
|
||||
* Handle a diagnostic.
|
||||
*/
|
||||
public abstract void report(JCDiagnostic diag);
|
||||
|
||||
/**
|
||||
* Defer a lint warning because we don't know the {@link Lint} configuration yet.
|
||||
*
|
||||
* @param sourceFile the source file
|
||||
* @param diagnostic waiting diagnostic
|
||||
*/
|
||||
public void addLintWaiter(JavaFileObject sourceFile, JCDiagnostic diagnostic) {
|
||||
Assert.check(sourceFile != null);
|
||||
Assert.check(diagnostic.getDiagnosticPosition() != null);
|
||||
Assert.check(diagnostic.getLintCategory() != null);
|
||||
Assert.check(diagnostic.getLintCategory().annotationSuppression);
|
||||
lintWaitersMap.computeIfAbsent(sourceFile, s -> new LinkedList<>()).add(diagnostic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush any lint waiters whose {@link Lint} configurations are now known.
|
||||
*/
|
||||
public void flushLintWaiters() {
|
||||
for (Iterator<Map.Entry<JavaFileObject, List<JCDiagnostic>>> i = lintWaitersMap.entrySet().iterator(); i.hasNext(); ) {
|
||||
Map.Entry<JavaFileObject, List<JCDiagnostic>> entry = i.next();
|
||||
|
||||
// Is the file no longer recognized? If so, discard warnings (this can happen with JShell)
|
||||
JavaFileObject sourceFile = entry.getKey();
|
||||
if (!lintMapper.isKnown(sourceFile)) {
|
||||
i.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Flush those diagnostics for which we know the Lint that applies
|
||||
List<JCDiagnostic> diagnostics = entry.getValue();
|
||||
JavaFileObject prevSourceFile = useSource(sourceFile);
|
||||
try {
|
||||
for (Iterator<JCDiagnostic> j = diagnostics.iterator(); j.hasNext(); ) {
|
||||
JCDiagnostic diag = j.next();
|
||||
lintMapper.lintAt(sourceFile, diag.getDiagnosticPosition()).ifPresent(lint -> {
|
||||
applyLint(lint, diag, this::report);
|
||||
j.remove();
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
useSource(prevSourceFile);
|
||||
}
|
||||
|
||||
// Discard list if now empty
|
||||
if (diagnostics.isEmpty())
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,6 +196,9 @@ public class Log extends AbstractLog {
|
||||
|
||||
@Override
|
||||
public void report(JCDiagnostic diag) { }
|
||||
|
||||
@Override
|
||||
public void addLintWaiter(JavaFileObject sourceFile, JCDiagnostic diagnostic) { }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,7 +227,7 @@ public class Log extends AbstractLog {
|
||||
}
|
||||
|
||||
private boolean deferrable(JCDiagnostic diag) {
|
||||
return !(diag.isFlagSet(DiagnosticFlag.NON_DEFERRABLE) && passOnNonDeferrable) && filter.test(diag);
|
||||
return !(diag.isFlagSet(NON_DEFERRABLE) && passOnNonDeferrable) && filter.test(diag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -160,6 +239,15 @@ public class Log extends AbstractLog {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLintWaiter(JavaFileObject sourceFile, JCDiagnostic diag) {
|
||||
if (deferrable(diag)) {
|
||||
super.addLintWaiter(sourceFile, diag);
|
||||
} else {
|
||||
prev.addLintWaiter(sourceFile, diag);
|
||||
}
|
||||
}
|
||||
|
||||
public List<JCDiagnostic> getDiagnostics() {
|
||||
return deferred;
|
||||
}
|
||||
@ -177,6 +265,13 @@ public class Log extends AbstractLog {
|
||||
.filter(accepter)
|
||||
.forEach(prev::report);
|
||||
deferred = null; // prevent accidental ongoing use
|
||||
|
||||
// Flush matching Lint waiters to the previous handler
|
||||
lintWaitersMap.forEach(
|
||||
(sourceFile, diagnostics) -> diagnostics.stream()
|
||||
.filter(accepter)
|
||||
.forEach(diagnostic -> prev.addLintWaiter(sourceFile, diagnostic)));
|
||||
lintWaitersMap = null; // prevent accidental ongoing use
|
||||
}
|
||||
|
||||
/** Report all deferred diagnostics in the specified order. */
|
||||
@ -237,6 +332,26 @@ public class Log extends AbstractLog {
|
||||
*/
|
||||
private JavacMessages messages;
|
||||
|
||||
/**
|
||||
* The compilation context.
|
||||
*/
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* The {@link Options} singleton.
|
||||
*/
|
||||
private final Options options;
|
||||
|
||||
/**
|
||||
* The lint positions table.
|
||||
*/
|
||||
private final LintMapper lintMapper;
|
||||
|
||||
/**
|
||||
* The root {@link Lint} singleton.
|
||||
*/
|
||||
private Lint rootLint;
|
||||
|
||||
/**
|
||||
* Handler for initial dispatch of diagnostics.
|
||||
*/
|
||||
@ -334,6 +449,9 @@ public class Log extends AbstractLog {
|
||||
private Log(Context context, Map<WriterKind, PrintWriter> writers) {
|
||||
super(JCDiagnostic.Factory.instance(context));
|
||||
context.put(logKey, this);
|
||||
this.context = context;
|
||||
this.options = Options.instance(context);
|
||||
this.lintMapper = LintMapper.instance(context);
|
||||
this.writers = writers;
|
||||
|
||||
@SuppressWarnings("unchecked") // FIXME
|
||||
@ -353,7 +471,6 @@ public class Log extends AbstractLog {
|
||||
this.diagFormatter = new BasicDiagnosticFormatter(messages);
|
||||
|
||||
// Once Options is ready, complete the initialization
|
||||
final Options options = Options.instance(context);
|
||||
options.whenReady(this::initOptions);
|
||||
}
|
||||
// where
|
||||
@ -517,7 +634,7 @@ public class Log extends AbstractLog {
|
||||
if (!shouldReport(file, d.getIntPosition()))
|
||||
return false;
|
||||
|
||||
if (!d.isFlagSet(DiagnosticFlag.SOURCE_LEVEL))
|
||||
if (!d.isFlagSet(SOURCE_LEVEL))
|
||||
return true;
|
||||
|
||||
Pair<JavaFileObject, List<String>> coords = new Pair<>(file, getCode(d));
|
||||
@ -680,8 +797,22 @@ public class Log extends AbstractLog {
|
||||
*/
|
||||
@Override
|
||||
public void report(JCDiagnostic diagnostic) {
|
||||
diagnosticHandler.report(diagnostic);
|
||||
}
|
||||
LintCategory category = diagnostic.getLintCategory();
|
||||
if (category != null) {
|
||||
if (category.annotationSuppression && diagnostic.getDiagnosticPosition() != null)
|
||||
diagnosticHandler.addLintWaiter(currentSourceFile(), diagnostic); // subject to @SuppressWarnings
|
||||
else
|
||||
applyLint(rootLint(), diagnostic, diagnosticHandler::report);
|
||||
} else
|
||||
diagnosticHandler.report(diagnostic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report unreported lint warnings for which the applicable {@link Lint} configuration is now known.
|
||||
*/
|
||||
public void reportOutstandingWarnings() {
|
||||
diagnosticHandler.flushLintWaiters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the state of this instance.
|
||||
@ -695,8 +826,83 @@ public class Log extends AbstractLog {
|
||||
nsuppressedwarns = 0;
|
||||
while (diagnosticHandler.prev != null)
|
||||
popDiagnosticHandler(diagnosticHandler);
|
||||
aggregators.values().forEach(MandatoryWarningAggregator::clear);
|
||||
suppressedDeferredMandatory.clear();
|
||||
}
|
||||
|
||||
// Apply the given Lint configuration to the diagnostic and, if it survives, pass on downstream
|
||||
private void applyLint(Lint lint, JCDiagnostic diag, Consumer<? super JCDiagnostic> downstream) {
|
||||
LintCategory category = diag.getLintCategory();
|
||||
|
||||
// Fallback hackery for REQUIRES_TRANSITIVE_AUTOMATIC (see also Check.checkModuleRequires())
|
||||
if (diag.getCode().equals("compiler.warn.requires.transitive.automatic") &&
|
||||
!lint.isEnabled(REQUIRES_TRANSITIVE_AUTOMATIC)) {
|
||||
diag = diags.warning(diag.getDiagnosticSource(), diag.getDiagnosticPosition(), LintWarnings.RequiresAutomatic);
|
||||
category = diag.getLintCategory();
|
||||
}
|
||||
|
||||
// Determine whether this diagnostic should be emitted at all
|
||||
if (diag.isFlagSet(DEFAULT_ENABLED) ? isExplicitlySuppressed(lint, category) : !lint.isEnabled(category))
|
||||
return;
|
||||
|
||||
// Configure verbose logging (or not) for diagnostics going through a mandatory warning aggregator
|
||||
if (diag.isFlagSet(AGGREGATE) && lint.isEnabled(category))
|
||||
diag.setFlag(AGGREGATE_VERBOSE);
|
||||
|
||||
// Emit the warning
|
||||
downstream.accept(diag);
|
||||
}
|
||||
|
||||
private boolean isExplicitlySuppressed(Lint lint, LintCategory category) {
|
||||
return category.annotationSuppression ?
|
||||
lint.isSuppressed(category) : // suppression happens via @SuppressWarnings
|
||||
options.isSet(XLINT_CUSTOM, "-" + category.option); // suppression happens via -Xlint:-category
|
||||
}
|
||||
|
||||
// Obtain root Lint singleton lazily to avoid init loops
|
||||
private Lint rootLint() {
|
||||
if (rootLint == null)
|
||||
rootLint = Lint.instance(context);
|
||||
return rootLint;
|
||||
}
|
||||
|
||||
// Mandatory Warnings
|
||||
|
||||
private final EnumMap<LintCategory, MandatoryWarningAggregator> aggregators = new EnumMap<>(LintCategory.class);
|
||||
|
||||
private final EnumSet<LintCategory> suppressedDeferredMandatory = EnumSet.noneOf(LintCategory.class);
|
||||
|
||||
/**
|
||||
* Suppress aggregated mandatory warning notes for the specified category.
|
||||
*/
|
||||
public void suppressAggregatedWarningNotes(LintCategory category) {
|
||||
suppressedDeferredMandatory.add(category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report any remaining unreported aggregated mandatory warning notes.
|
||||
*/
|
||||
public void reportOutstandingNotes() {
|
||||
aggregators.entrySet().stream()
|
||||
.filter(entry -> !suppressedDeferredMandatory.contains(entry.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
.map(MandatoryWarningAggregator::aggregationNotes)
|
||||
.flatMap(List::stream)
|
||||
.forEach(this::report);
|
||||
aggregators.clear();
|
||||
}
|
||||
|
||||
private MandatoryWarningAggregator aggregatorFor(LintCategory lc) {
|
||||
return switch (lc) {
|
||||
case PREVIEW -> aggregators.computeIfAbsent(lc, c -> new MandatoryWarningAggregator(this, Source.instance(context), c));
|
||||
case DEPRECATION -> aggregators.computeIfAbsent(lc, c -> new MandatoryWarningAggregator(this, null, c, "deprecated"));
|
||||
case REMOVAL, UNCHECKED -> aggregators.computeIfAbsent(lc, c -> new MandatoryWarningAggregator(this, null, c));
|
||||
case null, default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
// DefaultDiagnosticHandler
|
||||
|
||||
/**
|
||||
* Common diagnostic handling.
|
||||
* The diagnostic is counted, and depending on the options and how many diagnostics have been
|
||||
@ -727,6 +933,15 @@ public class Log extends AbstractLog {
|
||||
break;
|
||||
|
||||
case WARNING:
|
||||
|
||||
// Apply the appropriate mandatory warning aggregator, if needed
|
||||
if (diagnostic.isFlagSet(AGGREGATE)) {
|
||||
boolean verbose = diagnostic.isFlagSet(AGGREGATE_VERBOSE);
|
||||
if (!aggregatorFor(diagnostic.getLintCategory()).aggregate(diagnostic, verbose))
|
||||
break;
|
||||
}
|
||||
|
||||
// Emit warning unless not mandatory and warnings are disabled
|
||||
if (emitWarnings || diagnostic.isMandatory()) {
|
||||
if (nwarnings < MaxWarnings) {
|
||||
writeDiagnostic(diagnostic);
|
||||
@ -738,8 +953,7 @@ public class Log extends AbstractLog {
|
||||
break;
|
||||
|
||||
case ERROR:
|
||||
if (diagnostic.isFlagSet(DiagnosticFlag.API) ||
|
||||
shouldReport(diagnostic)) {
|
||||
if (diagnostic.isFlagSet(API) || shouldReport(diagnostic)) {
|
||||
if (nerrors < MaxErrors) {
|
||||
writeDiagnostic(diagnostic);
|
||||
nerrors++;
|
||||
@ -749,7 +963,7 @@ public class Log extends AbstractLog {
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (diagnostic.isFlagSet(JCDiagnostic.DiagnosticFlag.COMPRESSED)) {
|
||||
if (diagnostic.isFlagSet(COMPRESSED)) {
|
||||
compressedOutput = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,11 +25,14 @@
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
@ -39,9 +42,10 @@ import com.sun.tools.javac.util.JCDiagnostic.Warning;
|
||||
|
||||
|
||||
/**
|
||||
* A handler to process mandatory warnings, setting up a deferred diagnostic
|
||||
* An aggregator for mandatory warnings, setting up a deferred diagnostic
|
||||
* to be printed at the end of the compilation if some warnings get suppressed
|
||||
* because too many warnings have already been generated.
|
||||
* because the lint category is not enabled or too many warnings have already
|
||||
* been generated.
|
||||
*
|
||||
* <p>
|
||||
* Note that the SuppressWarnings annotation can be used to suppress warnings
|
||||
@ -58,7 +62,7 @@ import com.sun.tools.javac.util.JCDiagnostic.Warning;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class MandatoryWarningHandler {
|
||||
class MandatoryWarningAggregator {
|
||||
|
||||
/**
|
||||
* The kinds of different deferred diagnostics that might be generated
|
||||
@ -105,64 +109,51 @@ public class MandatoryWarningHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Create a handler for mandatory warnings.
|
||||
* Create an aggregator for mandatory warnings.
|
||||
*
|
||||
* @param log The log on which to generate any diagnostics
|
||||
* @param source Associated source file, or null for none
|
||||
* @param verbose Specify whether or not detailed messages about
|
||||
* individual instances should be given, or whether an aggregate
|
||||
* message should be generated at the end of the compilation.
|
||||
* Typically set via -Xlint:option.
|
||||
* @param enforceMandatory
|
||||
* True if mandatory warnings and notes are being enforced.
|
||||
* @param lc The lint category for all warnings
|
||||
*/
|
||||
public MandatoryWarningHandler(Log log, Source source, boolean verbose, boolean enforceMandatory, LintCategory lc) {
|
||||
this(log, source, verbose, enforceMandatory, lc, null);
|
||||
public MandatoryWarningAggregator(Log log, Source source, LintCategory lc) {
|
||||
this(log, source, lc, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a handler for mandatory warnings.
|
||||
* Create an aggregator for mandatory warnings.
|
||||
*
|
||||
* @param log The log on which to generate any diagnostics
|
||||
* @param source Associated source file, or null for none
|
||||
* @param verbose Specify whether or not detailed messages about
|
||||
* individual instances should be given, or whether an aggregate
|
||||
* message should be generated at the end of the compilation.
|
||||
* Typically set via -Xlint:option.
|
||||
* @param enforceMandatory
|
||||
* True if mandatory warnings and notes are being enforced.
|
||||
* @param lc The lint category for all warnings
|
||||
* @param prefix A common prefix for the set of message keys for the messages
|
||||
* that may be generated, or null to infer from the lint category.
|
||||
*/
|
||||
public MandatoryWarningHandler(Log log, Source source, boolean verbose, boolean enforceMandatory, LintCategory lc, String prefix) {
|
||||
public MandatoryWarningAggregator(Log log, Source source, LintCategory lc, String prefix) {
|
||||
this.log = log;
|
||||
this.source = source;
|
||||
this.verbose = verbose;
|
||||
this.prefix = prefix != null ? prefix : lc.option;
|
||||
this.enforceMandatory = enforceMandatory;
|
||||
this.lintCategory = lc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a mandatory warning.
|
||||
* Aggregate a mandatory warning and determine whether to emit it.
|
||||
*
|
||||
* @param pos source code position
|
||||
* @param warnKey lint warning
|
||||
* @param diagnostic the mandatory warning
|
||||
* @param verbose whether the warning's lint category is enabled
|
||||
* @return true if diagnostic should be emitted, otherwise false
|
||||
*/
|
||||
public void report(DiagnosticPosition pos, LintWarning warnKey) {
|
||||
public boolean aggregate(JCDiagnostic diagnostic, boolean verbose) {
|
||||
Assert.check(diagnostic.isMandatory());
|
||||
Assert.check(diagnostic.getLintCategory() == lintCategory);
|
||||
JavaFileObject currentSource = log.currentSourceFile();
|
||||
Assert.check(warnKey.getLintCategory() == lintCategory);
|
||||
|
||||
if (verbose) {
|
||||
if (sourcesWithReportedWarnings == null)
|
||||
sourcesWithReportedWarnings = new HashSet<>();
|
||||
|
||||
if (log.nwarnings < log.MaxWarnings) {
|
||||
// generate message and remember the source file
|
||||
logMandatoryWarning(pos, warnKey);
|
||||
sourcesWithReportedWarnings.add(currentSource);
|
||||
anyWarningEmitted = true;
|
||||
return true;
|
||||
} else if (deferredDiagnosticKind == null) {
|
||||
// set up deferred message
|
||||
if (sourcesWithReportedWarnings.contains(currentSource)) {
|
||||
@ -194,30 +185,36 @@ public class MandatoryWarningHandler {
|
||||
deferredDiagnosticArg = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report any diagnostic that might have been deferred by previous calls of report().
|
||||
* Build and return any accumulated aggregation notes.
|
||||
*/
|
||||
public void reportDeferredDiagnostic() {
|
||||
public List<JCDiagnostic> aggregationNotes() {
|
||||
List<JCDiagnostic> list = new ArrayList<>(2);
|
||||
if (deferredDiagnosticKind != null) {
|
||||
if (deferredDiagnosticArg == null) {
|
||||
if (source != null) {
|
||||
logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), source);
|
||||
addNote(list, deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), source);
|
||||
} else {
|
||||
logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
|
||||
addNote(list, deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
|
||||
}
|
||||
} else {
|
||||
if (source != null) {
|
||||
logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg, source);
|
||||
addNote(list, deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg, source);
|
||||
} else {
|
||||
logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
|
||||
addNote(list, deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!verbose)
|
||||
logMandatoryNote(deferredDiagnosticSource, prefix + ".recompile");
|
||||
if (!anyWarningEmitted)
|
||||
addNote(list, deferredDiagnosticSource, prefix + ".recompile");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void addNote(List<JCDiagnostic> list, JavaFileObject file, String msg, Object... args) {
|
||||
list.add(log.diags.mandatoryNote(log.getSource(file), new Note("compiler", msg, args)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,12 +223,6 @@ public class MandatoryWarningHandler {
|
||||
private final Log log;
|
||||
private final Source source;
|
||||
|
||||
/**
|
||||
* Whether or not to report individual warnings, or simply to report a
|
||||
* single aggregate warning at the end of the compilation.
|
||||
*/
|
||||
private final boolean verbose;
|
||||
|
||||
/**
|
||||
* The common prefix for all I18N message keys generated by this handler.
|
||||
*/
|
||||
@ -268,9 +259,10 @@ public class MandatoryWarningHandler {
|
||||
private Object deferredDiagnosticArg;
|
||||
|
||||
/**
|
||||
* True if mandatory warnings and notes are being enforced.
|
||||
* Whether we have actually emitted a warning or just deferred everything.
|
||||
* In the latter case, the "recompile" notice is included in the summary.
|
||||
*/
|
||||
private final boolean enforceMandatory;
|
||||
private boolean anyWarningEmitted;
|
||||
|
||||
/**
|
||||
* A LintCategory to be included in point-of-use diagnostics to indicate
|
||||
@ -278,28 +270,6 @@ public class MandatoryWarningHandler {
|
||||
*/
|
||||
private final LintCategory lintCategory;
|
||||
|
||||
/**
|
||||
* Reports a mandatory warning to the log. If mandatory warnings
|
||||
* are not being enforced, treat this as an ordinary warning.
|
||||
*/
|
||||
private void logMandatoryWarning(DiagnosticPosition pos, LintWarning warnKey) {
|
||||
if (enforceMandatory)
|
||||
log.mandatoryWarning(pos, warnKey);
|
||||
else
|
||||
log.warning(pos, warnKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a mandatory note to the log. If mandatory notes are
|
||||
* not being enforced, treat this as an ordinary note.
|
||||
*/
|
||||
private void logMandatoryNote(JavaFileObject file, String msg, Object... args) {
|
||||
if (enforceMandatory)
|
||||
log.mandatoryNote(file, new Note("compiler", msg, args));
|
||||
else
|
||||
log.note(file, new Note("compiler", msg, args));
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
sourcesWithReportedWarnings = null;
|
||||
deferredDiagnosticKind = null;
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, 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,7 +41,7 @@ import javax.tools.SimpleJavaFileObject;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.parser.Parser;
|
||||
import com.sun.tools.javac.parser.ParserFactory;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
@ -130,10 +130,10 @@ public class TestLog
|
||||
log.error(tree.pos(), Errors.NotStmt);
|
||||
log.error(nil, Errors.NotStmt);
|
||||
|
||||
log.warning(LintWarnings.DivZero);
|
||||
log.warning(tree.pos, LintWarnings.DivZero);
|
||||
log.warning(tree.pos(), LintWarnings.DivZero);
|
||||
log.warning(nil, LintWarnings.DivZero);
|
||||
log.warning(Warnings.ExtraneousSemicolon);
|
||||
log.warning(tree.pos, Warnings.ExtraneousSemicolon);
|
||||
log.warning(tree.pos(), Warnings.ExtraneousSemicolon);
|
||||
log.warning(nil, Warnings.ExtraneousSemicolon);
|
||||
}
|
||||
|
||||
private Log log;
|
||||
|
||||
@ -87,8 +87,6 @@ public class ErrorRecovery extends TestRunner {
|
||||
.getOutputLines(OutputKind.DIRECT);
|
||||
List<String> expected = List.of(
|
||||
"Test.java:1:1: compiler.err.invalid.meth.decl.ret.type.req",
|
||||
"- compiler.note.preview.filename: Test.java, DEFAULT",
|
||||
"- compiler.note.preview.recompile",
|
||||
"1 error"
|
||||
);
|
||||
if (!Objects.equals(expected, log)) {
|
||||
|
||||
@ -1,4 +1,2 @@
|
||||
ImplicitClassRecovery.java:7:33: compiler.err.expected: ';'
|
||||
- compiler.note.preview.filename: ImplicitClassRecovery.java, DEFAULT
|
||||
- compiler.note.preview.recompile
|
||||
1 error
|
||||
|
||||
@ -770,8 +770,8 @@ public class ImportModule extends TestRunner {
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
List<String> expectedErrors = List.of(
|
||||
"module-info.java:3:18: compiler.warn.module.not.found: M1",
|
||||
"module-info.java:6:9: compiler.err.cant.resolve: kindname.class, A, , ",
|
||||
"module-info.java:3:18: compiler.warn.module.not.found: M1",
|
||||
"- compiler.note.preview.filename: module-info.java, DEFAULT",
|
||||
"- compiler.note.preview.recompile",
|
||||
"1 error",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
T6400189a.java:14:35: compiler.warn.unchecked.call.mbr.of.raw.type: <T>getAnnotation(java.lang.Class<T>), java.lang.reflect.Constructor
|
||||
T6400189a.java:14:35: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.annotation.Annotation, java.lang.annotation.Documented)
|
||||
T6400189a.java:14:35: compiler.warn.unchecked.call.mbr.of.raw.type: <T>getAnnotation(java.lang.Class<T>), java.lang.reflect.Constructor
|
||||
1 error
|
||||
1 warning
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
T6400189b.java:24:24: compiler.warn.unchecked.call.mbr.of.raw.type: <T>m(T6400189b<T>), T6400189b.B
|
||||
T6400189b.java:24:24: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer)
|
||||
T6400189b.java:24:24: compiler.warn.unchecked.call.mbr.of.raw.type: <T>m(T6400189b<T>), T6400189b.B
|
||||
1 error
|
||||
1 warning
|
||||
|
||||
@ -22,8 +22,6 @@
|
||||
*/
|
||||
|
||||
// key: compiler.err.bad.file.name
|
||||
// key: compiler.note.preview.filename
|
||||
// key: compiler.note.preview.recompile
|
||||
// options: -source ${jdk.version} --enable-preview
|
||||
|
||||
public static void main(String... args) {
|
||||
|
||||
@ -22,8 +22,6 @@
|
||||
*/
|
||||
|
||||
// key: compiler.err.implicit.class.should.not.have.package.declaration
|
||||
// key: compiler.note.preview.filename
|
||||
// key: compiler.note.preview.recompile
|
||||
// options: -source ${jdk.version} --enable-preview
|
||||
|
||||
package implicit.classes;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
T7188968.java:20:20: compiler.err.cant.resolve.location: kindname.variable, unknown, , , (compiler.misc.location: kindname.class, T7188968, null)
|
||||
T7188968.java:20:9: compiler.warn.unchecked.call.mbr.of.raw.type: T7188968.Foo(java.util.List<X>,java.lang.Object), T7188968.Foo
|
||||
T7188968.java:21:20: compiler.err.cant.resolve.location: kindname.variable, unknown, , , (compiler.misc.location: kindname.class, T7188968, null)
|
||||
T7188968.java:21:29: compiler.warn.unchecked.call.mbr.of.raw.type: T7188968.Foo(java.util.List<X>,java.lang.Object), T7188968.Foo
|
||||
T7188968.java:22:22: compiler.err.cant.resolve.location: kindname.variable, unknown, , , (compiler.misc.location: kindname.class, T7188968, null)
|
||||
T7188968.java:23:24: compiler.err.cant.resolve.location: kindname.variable, unknown, , , (compiler.misc.location: kindname.class, T7188968, null)
|
||||
T7188968.java:20:9: compiler.warn.unchecked.call.mbr.of.raw.type: T7188968.Foo(java.util.List<X>,java.lang.Object), T7188968.Foo
|
||||
T7188968.java:21:29: compiler.warn.unchecked.call.mbr.of.raw.type: T7188968.Foo(java.util.List<X>,java.lang.Object), T7188968.Foo
|
||||
T7188968.java:22:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.util.List<X>,java.lang.Object, java.util.List,unknown, kindname.class, T7188968.Foo
|
||||
T7188968.java:22:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<X>
|
||||
T7188968.java:23:24: compiler.err.cant.resolve.location: kindname.variable, unknown, , , (compiler.misc.location: kindname.class, T7188968, null)
|
||||
T7188968.java:23:20: compiler.warn.unchecked.meth.invocation.applied: kindname.method, makeFoo, java.util.List<Z>,java.lang.Object, java.util.List,unknown, kindname.class, T7188968.Foo
|
||||
T7188968.java:23:21: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<Z>
|
||||
4 errors
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
TargetType22.java:29:21: compiler.warn.unchecked.varargs.non.reifiable.type: A
|
||||
TargetType22.java:40:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType22.Sam1<java.lang.String>), TargetType22, kindname.method, call(TargetType22.SamX<java.lang.String>), TargetType22
|
||||
TargetType22.java:29:21: compiler.warn.unchecked.varargs.non.reifiable.type: A
|
||||
1 error
|
||||
1 warning
|
||||
|
||||
170
test/langtools/tools/javac/lint/LexicalLintNesting.java
Normal file
170
test/langtools/tools/javac/lint/LexicalLintNesting.java
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8224228
|
||||
* @summary Verify lexical lint warnings handle nested declarations with SuppressWarnings correctly
|
||||
* @compile/fail/ref=LexicalLintNesting.out -XDrawDiagnostics -Xlint:text-blocks -Werror LexicalLintNesting.java
|
||||
*/
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
public class LexicalLintNesting {
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s1 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s2 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
public static class Nested1 {
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s3 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s4 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
public static class Nested1A {
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
String s5 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s6 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s7 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s8 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
public static class Nested1B {
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s9 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s10 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s11 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s12 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s13 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s14 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
public static class Nested2 {
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s15 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
String s16 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
public static class Nested2A {
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
String s17 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s18 = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD NOT get a warning here
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s19 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
String s20 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
public static class Nested2B {
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s21 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
String s22 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s23 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
String s24 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
}
|
||||
|
||||
//@SuppressWarnings("text-blocks")
|
||||
/* WARNING HERE */ String s25 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s26 = """
|
||||
trailing space here:\u0020
|
||||
""";
|
||||
}
|
||||
10
test/langtools/tools/javac/lint/LexicalLintNesting.out
Normal file
10
test/langtools/tools/javac/lint/LexicalLintNesting.out
Normal file
@ -0,0 +1,10 @@
|
||||
LexicalLintNesting.java:12:36: compiler.warn.trailing.white.space.will.be.removed
|
||||
LexicalLintNesting.java:30:40: compiler.warn.trailing.white.space.will.be.removed
|
||||
LexicalLintNesting.java:55:40: compiler.warn.trailing.white.space.will.be.removed
|
||||
LexicalLintNesting.java:68:45: compiler.warn.trailing.white.space.will.be.removed
|
||||
LexicalLintNesting.java:80:41: compiler.warn.trailing.white.space.will.be.removed
|
||||
LexicalLintNesting.java:92:37: compiler.warn.trailing.white.space.will.be.removed
|
||||
LexicalLintNesting.java:162:37: compiler.warn.trailing.white.space.will.be.removed
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
7 warnings
|
||||
61
test/langtools/tools/javac/lint/TextBlockSuppress.java
Normal file
61
test/langtools/tools/javac/lint/TextBlockSuppress.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8224228
|
||||
* @summary Verify SuppressWarnings works for LintCategore.TEXT_BLOCKS
|
||||
* @compile/fail/ref=TextBlockSuppress.out -XDrawDiagnostics -Xlint:text-blocks -Werror TextBlockSuppress.java
|
||||
*/
|
||||
|
||||
public class TextBlockSuppress {
|
||||
|
||||
public static class Example1 {
|
||||
public void method() {
|
||||
String s = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
public static class Example2 {
|
||||
public void method() {
|
||||
String s = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
public static class Example3 {
|
||||
@SuppressWarnings("text-blocks")
|
||||
public void method() {
|
||||
String s = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
public static class Example4 {
|
||||
{
|
||||
String s = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("text-blocks")
|
||||
public static class Example5 {
|
||||
{
|
||||
String s = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
public static class Example6 {
|
||||
public void method() {
|
||||
@SuppressWarnings("text-blocks")
|
||||
String s = """
|
||||
trailing space here:\u0020
|
||||
"""; // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
}
|
||||
5
test/langtools/tools/javac/lint/TextBlockSuppress.out
Normal file
5
test/langtools/tools/javac/lint/TextBlockSuppress.out
Normal file
@ -0,0 +1,5 @@
|
||||
TextBlockSuppress.java:12:24: compiler.warn.trailing.white.space.will.be.removed
|
||||
TextBlockSuppress.java:38:24: compiler.warn.trailing.white.space.will.be.removed
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
2 warnings
|
||||
@ -1,4 +1,4 @@
|
||||
Q.java:7:10: compiler.warn.has.been.deprecated: bar(), Q2
|
||||
P.java:10:18: compiler.warn.has.been.deprecated: foo(), Q
|
||||
Q.java:7:10: compiler.warn.has.been.deprecated: bar(), Q2
|
||||
Q.java:17:25: compiler.warn.has.been.deprecated: foo(), Q
|
||||
3 warnings
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Q.java:7:10: compiler.warn.has.been.deprecated: bar(), Q2
|
||||
P.java:10:18: compiler.warn.has.been.deprecated: foo(), Q
|
||||
Q.java:7:10: compiler.warn.has.been.deprecated: bar(), Q2
|
||||
- compiler.note.deprecated.filename.additional: Q.java
|
||||
2 warnings
|
||||
|
||||
@ -599,8 +599,8 @@ public class AnnotationsOnModules extends ModuleTestBase {
|
||||
"1 warning");
|
||||
} else if (suppress.equals(DEPRECATED_JAVADOC)) {
|
||||
expected = Arrays.asList(
|
||||
"module-info.java:1:19: compiler.warn.missing.deprecated.annotation",
|
||||
"module-info.java:2:14: compiler.warn.has.been.deprecated.module: m1x",
|
||||
"module-info.java:1:19: compiler.warn.missing.deprecated.annotation",
|
||||
"2 warnings");
|
||||
} else {
|
||||
expected = Arrays.asList("");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2025, 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
|
||||
@ -324,7 +324,9 @@ public class PreviewErrors extends ComboInstance<PreviewErrors> {
|
||||
ok = true;
|
||||
switch (elementType) {
|
||||
case LANGUAGE -> {
|
||||
if (lint == Lint.ENABLE_PREVIEW) {
|
||||
if (suppress == Suppress.YES) {
|
||||
expected = Set.of();
|
||||
} else if (lint == Lint.ENABLE_PREVIEW) {
|
||||
expected = Set.of("5:41:compiler.warn.preview.feature.use");
|
||||
} else {
|
||||
expected = Set.of("-1:-1:compiler.note.preview.filename",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2025, 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
|
||||
@ -587,12 +587,12 @@ public class PreviewTest extends TestRunner {
|
||||
"Test.java:19:11: compiler.err.is.preview: test()",
|
||||
"Test.java:20:11: compiler.err.is.preview: test()",
|
||||
"Test.java:21:11: compiler.err.is.preview: test()",
|
||||
"Test.java:24:11: compiler.warn.is.preview.reflective: test()",
|
||||
"Test.java:29:16: compiler.err.is.preview: preview.api.Preview",
|
||||
"Test.java:32:21: compiler.err.is.preview: test()",
|
||||
"Test.java:36:21: compiler.err.is.preview: test()",
|
||||
"Test.java:40:13: compiler.err.is.preview: test()",
|
||||
"Test.java:41:21: compiler.err.is.preview: FIELD",
|
||||
"Test.java:24:11: compiler.warn.is.preview.reflective: test()",
|
||||
"17 errors",
|
||||
"1 warning");
|
||||
|
||||
@ -792,6 +792,99 @@ public class PreviewTest extends TestRunner {
|
||||
throw new Exception("expected output not found" + log);
|
||||
}
|
||||
|
||||
@Test //JDK-8224228:
|
||||
public void testSuppressWarnings(Path base) throws Exception {
|
||||
Path apiSrc = base.resolve("api-src");
|
||||
tb.writeJavaFiles(apiSrc,
|
||||
"""
|
||||
package preview.api;
|
||||
@jdk.internal.javac.PreviewFeature(feature=jdk.internal.javac.PreviewFeature.Feature.TEST)
|
||||
public class Preview {
|
||||
public static int test() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
""");
|
||||
Path apiClasses = base.resolve("api-classes");
|
||||
|
||||
new JavacTask(tb, Task.Mode.CMDLINE)
|
||||
.outdir(apiClasses)
|
||||
.options("--patch-module", "java.base=" + apiSrc.toString(),
|
||||
"-Werror")
|
||||
.files(tb.findJavaFiles(apiSrc))
|
||||
.run()
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
Path testSrc = base.resolve("test-src");
|
||||
tb.writeJavaFiles(testSrc,
|
||||
"""
|
||||
package test;
|
||||
import preview.api.Preview;
|
||||
public class Test {
|
||||
|
||||
public static class Example1 {
|
||||
public void method() {
|
||||
Preview.test(); // SHOULD get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public static class Example2 {
|
||||
public void method() {
|
||||
Preview.test(); // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
public static class Example3 {
|
||||
@SuppressWarnings("preview")
|
||||
public void method() {
|
||||
Preview.test(); // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
public static class Example4 {
|
||||
{
|
||||
Preview.test(); // SHOULD get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public static class Example5 {
|
||||
{
|
||||
Preview.test(); // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
|
||||
public static class Example6 {
|
||||
@SuppressWarnings("preview")
|
||||
int x = Preview.test(); // SHOULD NOT get a warning here
|
||||
}
|
||||
}
|
||||
""");
|
||||
Path testClasses = base.resolve("test-classes");
|
||||
List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
|
||||
.outdir(testClasses)
|
||||
.options("--patch-module", "java.base=" + apiClasses.toString(),
|
||||
"--add-exports", "java.base/preview.api=ALL-UNNAMED",
|
||||
"--enable-preview",
|
||||
"-Xlint:preview",
|
||||
"-source", String.valueOf(Runtime.version().feature()),
|
||||
"-XDrawDiagnostics")
|
||||
.files(tb.findJavaFiles(testSrc))
|
||||
.run(Task.Expect.SUCCESS)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
List<String> expected =
|
||||
List.of("Test.java:7:11: compiler.warn.is.preview: preview.api.Preview",
|
||||
"Test.java:27:11: compiler.warn.is.preview: preview.api.Preview",
|
||||
"2 warnings");
|
||||
|
||||
if (!log.equals(expected))
|
||||
throw new Exception("expected output not found: " + log);
|
||||
}
|
||||
|
||||
@Test //JDK-8343540:
|
||||
public void nonPreviewImplementsPreview5(Path base) throws Exception {
|
||||
Path apiSrc = base.resolve("api-src");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2025, 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,7 +25,7 @@
|
||||
* @test
|
||||
* @bug 8173609
|
||||
* @summary printing of modules
|
||||
* @compile/ref=module-info.out -Xprint p/P.java module-info.java
|
||||
* @compile/ref=module-info.out -Xprint p/P.java -Xlint:-module module-info.java
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
T7097436.java:13:20: compiler.warn.varargs.unsafe.use.varargs.param: ls
|
||||
T7097436.java:14:25: compiler.warn.varargs.unsafe.use.varargs.param: ls
|
||||
T7097436.java:15:20: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List<java.lang.String>[], java.lang.String)
|
||||
T7097436.java:16:26: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List<java.lang.String>[], java.lang.Integer[])
|
||||
T7097436.java:13:20: compiler.warn.varargs.unsafe.use.varargs.param: ls
|
||||
T7097436.java:14:25: compiler.warn.varargs.unsafe.use.varargs.param: ls
|
||||
2 errors
|
||||
2 warnings
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
T6594914a.java:11:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6594914a.java:16:16: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6594914a.java:16:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6594914a.java:17:20: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6594914a.java:24:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
6 warnings
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
T7090499.java:26:10: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:27:10: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:28:17: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:28:10: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:18:5: compiler.warn.raw.class.use: T7090499, T7090499<E>
|
||||
T7090499.java:18:22: compiler.warn.raw.class.use: T7090499, T7090499<E>
|
||||
T7090499.java:20:10: compiler.warn.raw.class.use: T7090499.A.X, T7090499<E>.A<X>.X
|
||||
T7090499.java:21:10: compiler.warn.raw.class.use: T7090499.A.Z, T7090499<E>.A<X>.Z<Y>
|
||||
T7090499.java:24:17: compiler.warn.raw.class.use: T7090499.B, T7090499.B<X>
|
||||
T7090499.java:26:10: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:27:10: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:28:18: compiler.warn.raw.class.use: T7090499.B, T7090499.B<X>
|
||||
T7090499.java:28:17: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:28:11: compiler.warn.raw.class.use: T7090499.B, T7090499.B<X>
|
||||
T7090499.java:28:10: compiler.err.improperly.formed.type.inner.raw.param
|
||||
T7090499.java:30:32: compiler.warn.raw.class.use: T7090499.B, T7090499.B<X>
|
||||
T7090499.java:33:13: compiler.warn.raw.class.use: T7090499.A, T7090499<E>.A<X>
|
||||
T7090499.java:33:24: compiler.warn.raw.class.use: T7090499.A, T7090499<E>.A<X>
|
||||
|
||||
@ -116,8 +116,8 @@ public class UnneededStrictfpWarningToolBox extends TestRunner {
|
||||
var expected = List.of("UnneededStrictfpWarning1.java:1:17: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:10:10: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:12:29: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:16:28: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:18:21: compiler.warn.strictfp",
|
||||
"UnneededStrictfpWarning1.java:16:28: compiler.warn.strictfp",
|
||||
"5 warnings");
|
||||
checkLog(log, expected);
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
T6480588.java:16:24: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:16:51: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
|
||||
T6480588.java:15:2: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
|
||||
T6480588.java:18:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:18:12: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:18:65: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:30:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:33:25: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:33:52: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
|
||||
T6480588.java:32:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
|
||||
T6480588.java:17:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
|
||||
T6480588.java:18:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:29:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
|
||||
T6480588.java:19:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:19:34: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:21:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:21:25: compiler.warn.deprecated.annotation.has.no.effect: kindname.variable
|
||||
T6480588.java:21:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:30:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:29:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
|
||||
T6480588.java:30:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:33:25: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
|
||||
T6480588.java:33:52: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
|
||||
T6480588.java:32:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
|
||||
18 warnings
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user