Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JDK-8273244: Improve diagnostic output related to ErroneousTree #5510

Closed
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -256,79 +256,16 @@ public long getEndPosition(CompilationUnitTree file, Tree tree) {

@Override @DefinedBy(Api.COMPILER_TREE)
public long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
return ((DCTree) tree).getSourcePosition((DCDocComment) comment);
DCDocComment dcComment = (DCDocComment) comment;
DCTree dcTree = (DCTree) tree;
return dcComment.getSourcePosition(dcTree.getStartPosition());
}
@Override @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("fallthrough")

@Override @DefinedBy(Api.COMPILER_TREE)
public long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
DCDocComment dcComment = (DCDocComment) comment;
if (tree instanceof DCEndPosTree<?> dcEndPosTree) {
int endPos = dcEndPosTree.getEndPos(dcComment);

if (endPos != Position.NOPOS) {
return endPos;
}
}
int correction = 0;
switch (tree.getKind()) {
case TEXT:
DCText text = (DCText) tree;

return dcComment.comment.getSourcePos(text.pos + text.text.length());
case ERRONEOUS:
DCErroneous err = (DCErroneous) tree;

return dcComment.comment.getSourcePos(err.pos + err.body.length());
case IDENTIFIER:
DCIdentifier ident = (DCIdentifier) tree;

return dcComment.comment.getSourcePos(ident.pos + (ident.name != names.error ? ident.name.length() : 0));
case PARAM:
DCParam param = (DCParam) tree;

if (param.isTypeParameter && param.getDescription().isEmpty()) {
correction = 1;
}
case AUTHOR: case DEPRECATED: case RETURN: case SEE:
case SERIAL: case SERIAL_DATA: case SERIAL_FIELD: case SINCE:
case THROWS: case UNKNOWN_BLOCK_TAG: case VERSION: {
DocTree last = getLastChild(tree);

if (last != null) {
return getEndPosition(file, comment, last) + correction;
}

int pos;
String name;
if (tree.getKind() == DocTree.Kind.RETURN) {
DCTree.DCReturn dcReturn = (DCTree.DCReturn) tree;
pos = dcReturn.pos;
name = dcReturn.getTagName();
} else {
DCBlockTag block = (DCBlockTag) tree;
pos = block.pos;
name = block.getTagName();
}

return dcComment.comment.getSourcePos(pos + name.length() + 1);
}
case ENTITY: {
DCEntity endEl = (DCEntity) tree;
return dcComment.comment.getSourcePos(endEl.pos + (endEl.name != names.error ? endEl.name.length() : 0) + 2);
}
case COMMENT: {
DCComment endEl = (DCComment) tree;
return dcComment.comment.getSourcePos(endEl.pos + endEl.body.length());
}
default:
DocTree last = getLastChild(tree);

if (last != null) {
return getEndPosition(file, comment, last);
}
break;
}

return Position.NOPOS;
DCTree dcTree = (DCTree) tree;
return dcComment.getSourcePosition(dcTree.getEndPosition());
}
};
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
import com.sun.tools.javac.tree.DCTree.DCText;
import com.sun.tools.javac.tree.DocTreeMaker;
import com.sun.tools.javac.util.DiagnosticSource;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
@@ -62,14 +63,21 @@
public class DocCommentParser {
static class ParseException extends Exception {
private static final long serialVersionUID = 0;
final int pos;

ParseException(String key) {
this(Position.NOPOS, key);
}
ParseException(int pos, String key) {
super(key);
this.pos = pos;
}
}

private enum Phase {PREAMBLE, BODY, POSTAMBLE}
private enum Phase { PREAMBLE, BODY, POSTAMBLE }

private final ParserFactory fac;
private final JCDiagnostic.Factory diags;
private final DiagnosticSource diagSource;
private final Comment comment;
private final DocTreeMaker m;
@@ -96,6 +104,7 @@ private enum Phase {PREAMBLE, BODY, POSTAMBLE}
public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource,
Comment comment, boolean isFileContent) {
this.fac = fac;
this.diags = fac.log.diags;
this.diagSource = diagSource;
this.comment = comment;
names = fac.names;
@@ -126,18 +135,13 @@ public DCDocComment parse() {
List<DCTree> tags = blockTags();
List<DCTree> postamble = isFileContent ? blockContent(Phase.POSTAMBLE) : List.nil();

int pos = Position.NOPOS;
if (!preamble.isEmpty())
pos = preamble.head.pos;
else if (!body.isEmpty())
pos = body.head.pos;
else if (!tags.isEmpty())
pos = tags.head.pos;
else if (!postamble.isEmpty())
pos = postamble.head.pos;

DCDocComment dc = m.at(pos).newDocCommentTree(comment, body, tags, preamble, postamble);
return dc;
int pos = !preamble.isEmpty() ? preamble.head.pos
: !body.isEmpty() ? body.head.pos
: !tags.isEmpty() ? tags.head.pos
: !postamble.isEmpty() ? postamble.head.pos
: 0;

return m.at(pos).newDocCommentTree(comment, body, tags, preamble, postamble);
}

void nextChar() {
@@ -281,7 +285,7 @@ protected DCTree blockTag() {
return erroneous("dc.no.tag.name", p);
} catch (ParseException e) {
blockContent();
return erroneous(e.getMessage(), p);
return erroneous(e.getMessage(), p, e.pos);
}
}

@@ -334,7 +338,7 @@ protected DCTree inlineTag() {
}
}
} catch (ParseException e) {
return erroneous(e.getMessage(), p);
return erroneous(e.getMessage(), p, e.pos);
}
}

@@ -471,18 +475,15 @@ protected DCReference reference(boolean allowMember) throws ParseException {
ref.moduleName, ref.qualExpr,
ref.member, ref.paramTypes)
.setEndPos(bp);
} catch (ReferenceParser.ParseException parseException) {
throw new ParseException(parseException.getMessage());
} catch (ReferenceParser.ParseException pe) {
throw new ParseException(pos + pe.pos, pe.getMessage());
}

}

/**
* Read Java identifier
* Matching pairs of { } are skipped; the text is terminated by the first
* unmatched }. It is an error if the beginning of the next tag is detected.
* Reads a Java identifier.
*/
@SuppressWarnings("fallthrough")
protected DCIdentifier identifier() throws ParseException {
skipWhitespace();
int pos = bp;
@@ -496,10 +497,9 @@ protected DCIdentifier identifier() throws ParseException {
}

/**
* Read a quoted string.
* Reads a quoted string.
* It is an error if the beginning of the next tag is detected.
*/
@SuppressWarnings("fallthrough")
protected DCText quotedString() {
int pos = bp;
nextChar();
@@ -530,7 +530,7 @@ protected DCText quotedString() {
}

/**
* Read a term (that is, one word).
* Reads a term (that is, one word).
* It is an error if the beginning of the next tag is detected.
*/
@SuppressWarnings("fallthrough")
@@ -567,7 +567,7 @@ protected DCText inlineWord() {
}

/**
* Read general text content of an inline tag, including HTML entities and elements.
* Reads general text content of an inline tag, including HTML entities and elements.
* Matching pairs of { } are skipped; the text is terminated by the first
* unmatched }. It is an error if the beginning of the next tag is detected.
*/
@@ -656,7 +656,7 @@ protected void entity(ListBuffer<DCTree> list) {
}

/**
* Read an HTML entity.
* Reads an HTML entity.
* {@literal &identifier; } or {@literal &#digits; } or {@literal &#xhex-digits; }
*/
protected DCTree entity() {
@@ -966,7 +966,33 @@ protected void addPendingText(ListBuffer<DCTree> list, int textEnd) {
}
}

/**
* Creates an {@code ErroneousTree} node, for a range of text starting at a given position,
* ending at the last non-whitespace character before the current position,
* and with the preferred position set to the last character within that range.
*
* @param code the resource key for the error message
* @param pos the starting position
*
* @return the {@code ErroneousTree} node
*/
protected DCErroneous erroneous(String code, int pos) {
return erroneous(code, pos, Position.NOPOS);
}

/**
* Creates an {@code ErroneousTree} node, for a range of text starting at a given position,
* ending at the last non-whitespace character before the current position,
* and with a given preferred position.
*
* @param code the resource key for the error message
* @param pos the starting position
* @param pref the preferred position for the node, or {@code NOPOS} to use the default value
* as the last character of the range
*
* @return the {@code ErroneousTree} node
*/
protected DCErroneous erroneous(String code, int pos, int pref) {
int i = bp - 1;
loop:
while (i > pos) {
@@ -981,8 +1007,14 @@ protected DCErroneous erroneous(String code, int pos) {
}
i--;
}
if (pref == Position.NOPOS) {
pref = i;
}
int end = i + 1;
textStart = -1;
return m.at(pos).newErroneousTree(newString(pos, i + 1), diagSource, code);
JCDiagnostic.DiagnosticPosition dp = DCTree.createDiagnosticPosition(comment, pos, pref, end);
JCDiagnostic diag = diags.error(null, diagSource, dp, code);
return m.at(pos).newErroneousTree(newString(pos, end), diag).setPrefPos(pref);
}

protected boolean isIdentifierStart(char ch) {
@@ -1162,7 +1194,7 @@ public DCTree parse(int pos) throws ParseException {
}
inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
nextChar();
throw new ParseException("dc.unexpected.content");
throw new ParseException(pos, "dc.unexpected.content");
}
},

@@ -1219,7 +1251,7 @@ public DCTree parse(int pos) throws ParseException {
}
inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
nextChar();
throw new ParseException("dc.unexpected.content");
throw new ParseException(pos, "dc.unexpected.content");
}
},