提交 82c8d34d 编写于 作者: K ksrini

8017216: javac doesn't fill in end position for some errors of type not found

8019421: Javac doesn't fill in end position for some annotation related errors
8019422: Javac doesn't fill in end position for uninitialized variable errors
Reviewed-by: jjg, mcimadamore
上级 99e664af
......@@ -273,7 +273,7 @@ public class Annotate {
continue;
}
JCIdent left = (JCIdent)assign.lhs;
Symbol method = rs.resolveQualifiedMethod(left.pos(),
Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(),
env,
a.type,
left.name,
......
......@@ -1948,6 +1948,8 @@ public class Attr extends JCTree.Visitor {
clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
((JCIdent) clazzid).name);
EndPosTable endPosTable = this.env.toplevel.endPositions;
endPosTable.storeEnd(clazzid1, tree.getEndPosition(endPosTable));
if (clazz.hasTag(ANNOTATED_TYPE)) {
JCAnnotatedType annoType = (JCAnnotatedType) clazz;
List<JCAnnotation> annos = annoType.annotations;
......
......@@ -1339,7 +1339,7 @@ public class Flow {
/** A mapping from addresses to variable symbols.
*/
VarSymbol[] vars;
JCVariableDecl[] vardecls;
/** The current class being defined.
*/
......@@ -1417,13 +1417,14 @@ public class Flow {
* to the next available sequence number and entering it under that
* index into the vars array.
*/
void newVar(VarSymbol sym) {
vars = ArrayUtils.ensureCapacity(vars, nextadr);
void newVar(JCVariableDecl varDecl) {
VarSymbol sym = varDecl.sym;
vardecls = ArrayUtils.ensureCapacity(vardecls, nextadr);
if ((sym.flags() & FINAL) == 0) {
sym.flags_field |= EFFECTIVELY_FINAL;
}
sym.adr = nextadr;
vars[nextadr] = sym;
vardecls[nextadr] = varDecl;
inits.excl(nextadr);
uninits.incl(nextadr);
nextadr++;
......@@ -1493,11 +1494,13 @@ public class Flow {
/** Check that trackable variable is initialized.
*/
void checkInit(DiagnosticPosition pos, VarSymbol sym) {
checkInit(pos, sym, "var.might.not.have.been.initialized");
}
void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
trackable(sym) &&
!inits.isMember(sym.adr)) {
log.error(pos, "var.might.not.have.been.initialized",
sym);
log.error(pos, errkey, sym);
inits.incl(sym.adr);
}
}
......@@ -1599,7 +1602,7 @@ public class Flow {
if ((def.mods.flags & STATIC) != 0) {
VarSymbol sym = def.sym;
if (trackable(sym))
newVar(sym);
newVar(def);
}
}
}
......@@ -1619,7 +1622,7 @@ public class Flow {
if ((def.mods.flags & STATIC) == 0) {
VarSymbol sym = def.sym;
if (trackable(sym))
newVar(sym);
newVar(def);
}
}
}
......@@ -1678,9 +1681,22 @@ public class Flow {
scan(tree.body);
if (isInitialConstructor) {
for (int i = firstadr; i < nextadr; i++)
if (vars[i].owner == classDef.sym)
checkInit(TreeInfo.diagEndPos(tree.body), vars[i]);
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) {
// choose the diagnostic position based on whether
// the ctor is default(synthesized) or not
if (isSynthesized) {
checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
var, "var.not.initialized.in.default.constructor");
} else {
checkInit(TreeInfo.diagEndPos(tree.body), var);
}
}
}
}
List<AssignPendingExit> exits = pendingExits.toList();
pendingExits = new ListBuffer<AssignPendingExit>();
......@@ -1691,7 +1707,7 @@ public class Flow {
if (isInitialConstructor) {
inits.assign(exit.exit_inits);
for (int i = firstadr; i < nextadr; i++)
checkInit(exit.tree.pos(), vars[i]);
checkInit(exit.tree.pos(), vardecls[i].sym);
}
}
} finally {
......@@ -1706,7 +1722,7 @@ public class Flow {
public void visitVarDef(JCVariableDecl tree) {
boolean track = trackable(tree.sym);
if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
if (track && tree.sym.owner.kind == MTH) newVar(tree);
if (tree.init != null) {
Lint lintPrev = lint;
lint = lint.augment(tree.sym);
......@@ -2239,11 +2255,11 @@ public class Flow {
Flow.this.make = make;
startPos = tree.pos().getStartPosition();
if (vars == null)
vars = new VarSymbol[32];
if (vardecls == null)
vardecls = new JCVariableDecl[32];
else
for (int i=0; i<vars.length; i++)
vars[i] = null;
for (int i=0; i<vardecls.length; i++)
vardecls[i] = null;
firstadr = 0;
nextadr = 0;
pendingExits = new ListBuffer<AssignPendingExit>();
......@@ -2255,8 +2271,8 @@ public class Flow {
startPos = -1;
resetBits(inits, uninits, uninitsTry, initsWhenTrue,
initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse);
if (vars != null) for (int i=0; i<vars.length; i++)
vars[i] = null;
if (vardecls != null) for (int i=0; i<vardecls.length; i++)
vardecls[i] = null;
firstadr = 0;
nextadr = 0;
pendingExits = null;
......
......@@ -4053,7 +4053,7 @@ public class JavacParser implements Parser {
endPosMap = new HashMap<JCTree, Integer>();
}
protected void storeEnd(JCTree tree, int endpos) {
public void storeEnd(JCTree tree, int endpos) {
endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
}
......@@ -4091,7 +4091,7 @@ public class JavacParser implements Parser {
super(parser);
}
protected void storeEnd(JCTree tree, int endpos) { /* empty */ }
public void storeEnd(JCTree tree, int endpos) { /* empty */ }
protected <T extends JCTree> T to(T t) {
return t;
......@@ -4126,14 +4126,6 @@ public class JavacParser implements Parser {
this.parser = parser;
}
/**
* Store ending position for a tree, the value of which is the greater
* of last error position and the given ending position.
* @param tree The tree.
* @param endpos The ending position to associate with the tree.
*/
protected abstract void storeEnd(JCTree tree, int endpos);
/**
* Store current token's ending position for a tree, the value of which
* will be the greater of last error position and the ending position of
......
......@@ -1068,6 +1068,10 @@ compiler.err.var.might.already.be.assigned=\
compiler.err.var.might.not.have.been.initialized=\
variable {0} might not have been initialized
# 0: symbol
compiler.err.var.not.initialized.in.default.constructor=\
variable {0} not initialized in the default constructor
# 0: symbol
compiler.err.var.might.be.assigned.in.loop=\
variable {0} might be assigned in loop
......
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -42,11 +42,18 @@ public interface EndPosTable {
*/
public int getEndPos(JCTree tree);
/**
* Store ending position for a tree, the value of which is the greater of
* last error position and the given ending position.
* @param tree The tree.
* @param endpos The ending position to associate with the tree.
*/
public abstract void storeEnd(JCTree tree, int endpos);
/**
* Give an old tree and a new tree, the old tree will be replaced with
* the new tree, the position of the new tree will be that of the old
* tree.
* not exist.
* @param oldtree a JCTree to be replaced
* @param newtree a JCTree to be replaced with
* @return position of the old tree or Positions.NOPOS for non-existent mapping
......
/*
* Copyright (c) 2013, 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.
*/
// key: compiler.err.var.not.initialized.in.default.constructor
class X {
final int j;
}
/*
* Copyright (c) 2013, 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 8017216 8019422 8019421
* @summary verify start and end positions
* @run main TreeEndPosTest
*/
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class TreeEndPosTest {
private static JavaFileManager getJavaFileManager(JavaCompiler compiler,
DiagnosticCollector dc) {
return compiler.getStandardFileManager(dc, null, null);
}
static class JavaSource extends SimpleJavaFileObject {
final String source;
int startPos;
int endPos;
private JavaSource(String filename, String source) {
super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
this.source = source;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
static JavaSource createJavaSource(String preamble, String body,
String postamble, String expected) {
JavaSource js = createJavaSource(preamble, body, postamble, -1, -1);
js.startPos = js.source.indexOf(expected);
js.endPos = js.startPos + expected.length();
return js;
}
static JavaSource createJavaSource(String body, String expected) {
return createJavaSource(null, body, null, expected);
}
private static JavaSource createJavaSource(String preamble, String body,
String postamble, int start, int end) {
final String name = "Bug";
StringBuilder code = new StringBuilder();
if (preamble != null) {
code.append(preamble);
}
code.append("public class " + name + "{");
if (body != null) {
code.append(body);
}
code.append("}");
if (postamble != null) {
code.append(postamble);
}
JavaSource js = new JavaSource(name + ".java", code.toString());
js.startPos = start;
js.endPos = end;
return js;
}
}
public static void main(String... args) throws IOException {
testUninitializedVariable();
testMissingAnnotationValue();
testFinalVariableWithDefaultConstructor();
testFinalVariableWithConstructor();
}
static void testUninitializedVariable() throws IOException {
compile(JavaSource.createJavaSource("Object o = new A().new B(); class A { }",
"B()"));
}
static void testMissingAnnotationValue() throws IOException {
compile(JavaSource.createJavaSource("@Foo(\"vvvv\")",
null, "@interface Foo { }", "\"vvvv\""));
}
static void testFinalVariableWithDefaultConstructor() throws IOException {
compile(JavaSource.createJavaSource("private static final String Foo; public void bar() { }",
"private static final String Foo;"));
}
static void testFinalVariableWithConstructor() throws IOException {
compile(JavaSource.createJavaSource("public Bug (){} private static final String Foo; public void bar() { }",
"{}"));
}
static void compile(JavaSource src) throws IOException {
ByteArrayOutputStream ba = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(ba);
File tempDir = new File(".");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector dc = new DiagnosticCollector();
JavaFileManager javaFileManager = getJavaFileManager(compiler, dc);
List<String> options = new ArrayList<>();
options.add("-cp");
options.add(tempDir.getPath());
options.add("-d");
options.add(tempDir.getPath());
options.add("-XDshouldStopPolicy=GENERATE");
List<JavaFileObject> sources = new ArrayList<>();
sources.add(src);
JavaCompiler.CompilationTask task =
compiler.getTask(writer, javaFileManager,
dc, options, null,
sources);
task.call();
for (Diagnostic diagnostic : (List<Diagnostic>) dc.getDiagnostics()) {
long actualStart = diagnostic.getStartPosition();
long actualEnd = diagnostic.getEndPosition();
System.out.println("Source: " + src.source);
System.out.println("Diagnostic: " + diagnostic);
System.out.print("Start position: Expected: " + src.startPos);
System.out.println(", Actual: " + actualStart);
System.out.print("End position: Expected: " + src.endPos);
System.out.println(", Actual: " + actualEnd);
if (src.startPos != actualStart || src.endPos != actualEnd) {
throw new RuntimeException("error: trees don't match");
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册