8295184: Printing messages with a RecordComponentElement does not include position
Reviewed-by: vromero
This commit is contained in:
parent
ba2d28e911
commit
ee9ba74564
@ -1519,14 +1519,14 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
|
||||
/* creates a record component if non is related to the given variable and recreates a brand new one
|
||||
* in other case
|
||||
*/
|
||||
public RecordComponent createRecordComponent(RecordComponent existing, JCVariableDecl var, List<JCAnnotation> annotations) {
|
||||
public RecordComponent createRecordComponent(RecordComponent existing, JCVariableDecl rcDecl, VarSymbol varSym) {
|
||||
RecordComponent rc = null;
|
||||
if (existing != null) {
|
||||
recordComponents = List.filter(recordComponents, existing);
|
||||
recordComponents = recordComponents.append(rc = new RecordComponent(var.sym, existing.originalAnnos, existing.isVarargs));
|
||||
recordComponents = recordComponents.append(rc = new RecordComponent(varSym, existing.ast, existing.isVarargs));
|
||||
} else {
|
||||
// Didn't find the record component: create one.
|
||||
recordComponents = recordComponents.append(rc = new RecordComponent(var.sym, annotations));
|
||||
recordComponents = recordComponents.append(rc = new RecordComponent(varSym, rcDecl));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -1786,9 +1786,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
|
||||
public static class RecordComponent extends VarSymbol implements RecordComponentElement {
|
||||
public MethodSymbol accessor;
|
||||
public JCTree.JCMethodDecl accessorMeth;
|
||||
/* the original annotations applied to the record component
|
||||
*/
|
||||
private final List<JCAnnotation> originalAnnos;
|
||||
|
||||
/* if the user happens to erroneously declare two components with the same name, we need a way to differentiate
|
||||
* them, the code will fail anyway but we need to keep the information for better error recovery
|
||||
*/
|
||||
@ -1796,23 +1794,25 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
|
||||
|
||||
private final boolean isVarargs;
|
||||
|
||||
private JCVariableDecl ast;
|
||||
|
||||
/**
|
||||
* Construct a record component, given its flags, name, type and owner.
|
||||
*/
|
||||
public RecordComponent(Name name, Type type, Symbol owner) {
|
||||
super(PUBLIC, name, type, owner);
|
||||
pos = -1;
|
||||
originalAnnos = List.nil();
|
||||
ast = null;
|
||||
isVarargs = false;
|
||||
}
|
||||
|
||||
public RecordComponent(VarSymbol field, List<JCAnnotation> annotations) {
|
||||
this(field, annotations, field.type.hasTag(TypeTag.ARRAY) && ((ArrayType)field.type).isVarargs());
|
||||
public RecordComponent(VarSymbol field, JCVariableDecl ast) {
|
||||
this(field, ast, field.type.hasTag(TypeTag.ARRAY) && ((ArrayType)field.type).isVarargs());
|
||||
}
|
||||
|
||||
public RecordComponent(VarSymbol field, List<JCAnnotation> annotations, boolean isVarargs) {
|
||||
public RecordComponent(VarSymbol field, JCVariableDecl ast, boolean isVarargs) {
|
||||
super(PUBLIC, field.name, field.type, field.owner);
|
||||
this.originalAnnos = annotations;
|
||||
this.ast = ast;
|
||||
this.pos = field.pos;
|
||||
/* it is better to store the original information for this one, instead of relying
|
||||
* on the info in the type of the symbol. This is because on the presence of APs
|
||||
@ -1822,7 +1822,9 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
|
||||
this.isVarargs = isVarargs;
|
||||
}
|
||||
|
||||
public List<JCAnnotation> getOriginalAnnos() { return originalAnnos; }
|
||||
public List<JCAnnotation> getOriginalAnnos() { return this.ast == null ? List.nil() : this.ast.mods.annotations; }
|
||||
|
||||
public JCVariableDecl declarationFor() { return this.ast; }
|
||||
|
||||
public boolean isVarargs() {
|
||||
return isVarargs;
|
||||
|
@ -3006,6 +3006,16 @@ public class Check {
|
||||
Arrays.stream(getTargetNames(anno.type.tsym)).anyMatch(name -> name == names.RECORD_COMPONENT)
|
||||
).collect(List.collector()));
|
||||
|
||||
JCVariableDecl fieldAST = (JCVariableDecl) declarationTree;
|
||||
for (JCAnnotation fieldAnnot : fieldAST.mods.annotations) {
|
||||
for (JCAnnotation rcAnnot : rc.declarationFor().mods.annotations) {
|
||||
if (rcAnnot.pos == fieldAnnot.pos) {
|
||||
rcAnnot.setType(fieldAnnot.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point, we used to carry over any type annotations from the VARDEF to the record component, but
|
||||
* that is problematic, since we get here only when *some* annotation is applied to the SE5 (declaration)
|
||||
* annotation location, inadvertently failing to carry over the type annotations when the VarDef has no
|
||||
|
@ -996,10 +996,8 @@ public class TypeEnter implements Completer {
|
||||
|
||||
memberEnter.memberEnter(field, env);
|
||||
|
||||
sym.createRecordComponent(rc, field,
|
||||
field.mods.annotations.isEmpty() ?
|
||||
List.nil() :
|
||||
new TreeCopier<JCTree>(make.at(field.pos)).copy(field.mods.annotations));
|
||||
JCVariableDecl rcDecl = new TreeCopier<JCTree>(make.at(field.pos)).copy(field);
|
||||
sym.createRecordComponent(rc, rcDecl, field.sym);
|
||||
}
|
||||
|
||||
enterThisAndSuper(sym, env);
|
||||
|
@ -30,6 +30,7 @@ package com.sun.tools.javac.tree;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.RecordComponent;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
@ -46,6 +47,7 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||
import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
|
||||
import static com.sun.tools.javac.tree.JCTree.Tag.SYNCHRONIZED;
|
||||
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
@ -792,6 +794,12 @@ public class TreeInfo {
|
||||
result = that;
|
||||
return true;
|
||||
}
|
||||
if (this.sym.getKind() == ElementKind.RECORD_COMPONENT) {
|
||||
if (thatSym != null && thatSym.getKind() == ElementKind.FIELD && (thatSym.flags_field & RECORD) != 0) {
|
||||
RecordComponent rc = thatSym.enclClass().getRecordComponent((VarSymbol)thatSym);
|
||||
return checkMatch(rc.declarationFor(), rc);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 8295184
|
||||
* @summary Printing messages with a RecordComponentElement does not include position
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @compile TestWarning.java
|
||||
* @compile ReproducingAP.java
|
||||
* @run main RecordComponentSourcePositionTest
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import toolbox.JavacTask;
|
||||
import toolbox.TestRunner;
|
||||
import toolbox.ToolBox;
|
||||
import toolbox.Task;
|
||||
|
||||
public class RecordComponentSourcePositionTest extends TestRunner {
|
||||
|
||||
ToolBox tb;
|
||||
|
||||
public RecordComponentSourcePositionTest() {
|
||||
super(System.err);
|
||||
tb = new ToolBox();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
RecordComponentSourcePositionTest t = new RecordComponentSourcePositionTest();
|
||||
t.runTests();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecordComponentPositionInDiagnostics() throws Exception {
|
||||
String code = """
|
||||
@TestWarning(includeAnnotation = true)
|
||||
public record Test(
|
||||
@TestWarning(includeAnnotation = true) int first,
|
||||
@TestWarning int second) {
|
||||
}
|
||||
|
||||
@TestWarning
|
||||
record Test2() {}
|
||||
""";
|
||||
|
||||
Path curPath = Path.of(".");
|
||||
|
||||
List<String> output = new JavacTask(tb)
|
||||
.sources(code)
|
||||
.outdir(curPath)
|
||||
.options("-XDrawDiagnostics", "-processor", "ReproducingAP")
|
||||
.run()
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
List<String> expected = Arrays.asList(
|
||||
"Test.java:1:1: compiler.warn.proc.messager: Reporting Test with an annotation",
|
||||
"Test.java:3:9: compiler.warn.proc.messager: Reporting first with an annotation",
|
||||
"Test.java:4:26: compiler.warn.proc.messager: Reporting second",
|
||||
"Test.java:8:1: compiler.warn.proc.messager: Reporting Test2",
|
||||
"4 warnings");
|
||||
tb.checkEqual(expected, output);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
public class ReproducingAP extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public Set<String> getSupportedAnnotationTypes() {
|
||||
return Set.of(TestWarning.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
roundEnv.getElementsAnnotatedWith(TestWarning.class).forEach(e -> {
|
||||
var annotation = e.getAnnotation(TestWarning.class);
|
||||
if (annotation.includeAnnotation()) {
|
||||
processingEnv.getMessager().printMessage(
|
||||
javax.tools.Diagnostic.Kind.WARNING,
|
||||
"Reporting " + e.getSimpleName() + " with an annotation",
|
||||
e,
|
||||
e.getAnnotationMirrors().get(0));
|
||||
} else {
|
||||
processingEnv.getMessager().printMessage(
|
||||
javax.tools.Diagnostic.Kind.WARNING,
|
||||
"Reporting " + e.getSimpleName(),
|
||||
e);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Direct {@link ReproducingAP} to emit a warning.
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.RECORD_COMPONENT})
|
||||
public @interface TestWarning {
|
||||
/**
|
||||
* {@return {@code true} to include the relevant mirror in the warning message}
|
||||
*/
|
||||
boolean includeAnnotation() default false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user