8268312: Compilation error with nested generic functional interface
Reviewed-by: mcimadamore
This commit is contained in:
parent
92deab5465
commit
f3abb82989
src/jdk.compiler/share/classes/com/sun/tools/javac
test/langtools/tools/javac/diags
@ -68,6 +68,7 @@ import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@ -4174,16 +4175,11 @@ public class Resolve {
|
||||
return null;
|
||||
|
||||
Pair<Symbol, JCDiagnostic> c = errCandidate();
|
||||
if (compactMethodDiags) {
|
||||
JCDiagnostic simpleDiag =
|
||||
MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd);
|
||||
if (simpleDiag != null) {
|
||||
return simpleDiag;
|
||||
}
|
||||
}
|
||||
Symbol ws = c.fst.asMemberOf(site, types);
|
||||
return diags.create(dkind, log.currentSource(), pos,
|
||||
"cant.apply.symbol",
|
||||
compactMethodDiags ?
|
||||
d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null,
|
||||
kindName(ws),
|
||||
ws.name == names.init ? ws.owner.name : ws.name,
|
||||
methodArguments(ws.type.getParameterTypes()),
|
||||
@ -4244,8 +4240,8 @@ public class Resolve {
|
||||
JCDiagnostic err = diags.create(dkind,
|
||||
null,
|
||||
truncatedDiag ?
|
||||
EnumSet.of(DiagnosticFlag.COMPRESSED) :
|
||||
EnumSet.noneOf(DiagnosticFlag.class),
|
||||
EnumSet.of(DiagnosticFlag.COMPRESSED) :
|
||||
EnumSet.noneOf(DiagnosticFlag.class),
|
||||
log.currentSource(),
|
||||
pos,
|
||||
"cant.apply.symbols",
|
||||
|
@ -182,7 +182,11 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
String s = null;
|
||||
depth++;
|
||||
try {
|
||||
s = formatMessage(diagnostic, l);
|
||||
JCDiagnostic rewrittenDiagnostic = null;
|
||||
if (diagnostic.hasRewriter()) {
|
||||
rewrittenDiagnostic = diagnostic.rewrite();
|
||||
}
|
||||
s = formatMessage(rewrittenDiagnostic != null ? rewrittenDiagnostic : diagnostic, l);
|
||||
}
|
||||
finally {
|
||||
depth--;
|
||||
|
@ -26,6 +26,7 @@
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
@ -243,6 +244,21 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
return create(null, EnumSet.noneOf(DiagnosticFlag.class), source, pos, DiagnosticInfo.of(kind, prefix, key, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new diagnostic of the given kind, which is not mandatory and which has
|
||||
* no lint category.
|
||||
* @param kind The diagnostic kind
|
||||
* @param source The source of the compilation unit, if any, in which to report the message.
|
||||
* @param pos The source position at which to report the message.
|
||||
* @param key The key for the localized message.
|
||||
* @param rewriter A rewriter function used if this diagnostic needs to be rewritten
|
||||
* @param args Fields of the message.
|
||||
*/
|
||||
public JCDiagnostic create(
|
||||
DiagnosticType kind, DiagnosticSource source, DiagnosticPosition pos, String key, UnaryOperator<JCDiagnostic> rewriter, Object... args) {
|
||||
return create(null, EnumSet.noneOf(DiagnosticFlag.class), source, pos, DiagnosticInfo.of(kind, prefix, key, args), rewriter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new diagnostic of the given kind, which is not mandatory and which has
|
||||
* no lint category.
|
||||
@ -282,6 +298,11 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
LintCategory lc, Set<DiagnosticFlag> flags, DiagnosticSource source, DiagnosticPosition pos, DiagnosticInfo diagnosticInfo) {
|
||||
return new JCDiagnostic(formatter, normalize(diagnosticInfo), lc, flags, source, pos);
|
||||
}
|
||||
|
||||
public JCDiagnostic create(
|
||||
LintCategory lc, Set<DiagnosticFlag> flags, DiagnosticSource source, DiagnosticPosition pos, DiagnosticInfo diagnosticInfo, UnaryOperator<JCDiagnostic> rewriter) {
|
||||
return new JCDiagnostic(formatter, normalize(diagnosticInfo), lc, flags, source, pos, rewriter);
|
||||
}
|
||||
//where
|
||||
DiagnosticInfo normalize(DiagnosticInfo diagnosticInfo) {
|
||||
//replace all nested FragmentKey with full-blown JCDiagnostic objects
|
||||
@ -446,6 +467,8 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
/** source line position (set lazily) */
|
||||
private SourcePosition sourcePosition;
|
||||
|
||||
private final UnaryOperator<JCDiagnostic> rewriter;
|
||||
|
||||
/**
|
||||
* This class is used to defer the line/column position fetch logic after diagnostic construction.
|
||||
*/
|
||||
@ -596,6 +619,25 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
Set<DiagnosticFlag> flags,
|
||||
DiagnosticSource source,
|
||||
DiagnosticPosition pos) {
|
||||
this(formatter, diagnosticInfo, lc, flags, source, pos, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a diagnostic object.
|
||||
* @param formatter the formatter to use for the diagnostic
|
||||
* @param diagnosticInfo the diagnostic key
|
||||
* @param lc the lint category for the diagnostic
|
||||
* @param source the name of the source file, or null if none.
|
||||
* @param pos the character offset within the source file, if given.
|
||||
* @param rewriter the rewriter function used if this diagnostic needs to be rewritten
|
||||
*/
|
||||
protected JCDiagnostic(DiagnosticFormatter<JCDiagnostic> formatter,
|
||||
DiagnosticInfo diagnosticInfo,
|
||||
LintCategory lc,
|
||||
Set<DiagnosticFlag> flags,
|
||||
DiagnosticSource source,
|
||||
DiagnosticPosition pos,
|
||||
UnaryOperator<JCDiagnostic> rewriter) {
|
||||
if (source == null && pos != null && pos.getPreferredPosition() != Position.NOPOS)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
@ -605,6 +647,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
this.flags = flags;
|
||||
this.source = source;
|
||||
this.position = pos;
|
||||
this.rewriter = rewriter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -807,6 +850,14 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
||||
return flags.contains(flag);
|
||||
}
|
||||
|
||||
boolean hasRewriter() {
|
||||
return rewriter != null;
|
||||
}
|
||||
|
||||
JCDiagnostic rewrite() {
|
||||
return rewriter.apply(this);
|
||||
}
|
||||
|
||||
public static class MultilineDiagnostic extends JCDiagnostic {
|
||||
|
||||
private final List<JCDiagnostic> subdiagnostics;
|
||||
|
@ -28,7 +28,6 @@ package com.sun.tools.javac.util;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
@ -671,6 +670,11 @@ public class Log extends AbstractLog {
|
||||
if (expectDiagKeys != null)
|
||||
expectDiagKeys.remove(diagnostic.getCode());
|
||||
|
||||
if (diagnostic.hasRewriter()) {
|
||||
JCDiagnostic rewrittenDiag = diagnostic.rewrite();
|
||||
diagnostic = rewrittenDiag != null ? rewrittenDiag : diagnostic;
|
||||
}
|
||||
|
||||
switch (diagnostic.getType()) {
|
||||
case FRAGMENT:
|
||||
throw new IllegalArgumentException();
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8268312
|
||||
* @summary Compilation error with nested generic functional interface
|
||||
* @compile DiagnosticRewriterTest3.java
|
||||
*/
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
class DiagnosticRewriterTest3 {
|
||||
void m() {
|
||||
Optional.of("").map(outer -> {
|
||||
Optional.of("")
|
||||
.map(inner -> returnGeneric(outer))
|
||||
.ifPresent(String::toString);
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
<T> T returnGeneric(T generic) {
|
||||
return generic;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user