Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ public void run(ResultIterator it) throws Exception {
scan(text, scanner.scan((ParserResult) result), structure -> {
int start = (int) structure.getPosition();
int end = (int) structure.getEndPosition();
String[] startLines = text.substring(0, start).split("\n");
String[] endLines = text.substring(0, end).split("\n");
diags.add(Diagnostic.Builder.create(() -> start, () -> end, Bundle.ERR_PropertyWithoutValue())
.setSeverity(Diagnostic.Severity.Warning)
.setCode(ERR_CODE_PREFIX + text.substring(0, start).split("\n").length)
.setCode(ERR_CODE_PREFIX + startLines.length + ',' + (startLines[startLines.length - 1].length() + 1) + '-' + endLines.length + ',' + (endLines[endLines.length - 1].length() + 1))
.build());
});
}
Expand All @@ -135,7 +137,7 @@ public void run(ResultIterator it) throws Exception {
int end = offset + line.length();
diags.add(Diagnostic.Builder.create(() -> start, () -> end, Bundle.ERR_PropertyWithoutValue())
.setSeverity(Diagnostic.Severity.Warning)
.setCode(ERR_CODE_PREFIX + (i + 1))
.setCode(ERR_CODE_PREFIX + (i + 1) + ",1-" + (i + 1) + "," + line.length() + 1)
.build());
}
}
Expand Down Expand Up @@ -205,7 +207,19 @@ public ErrorsCache.ErrorKind getKind(Diagnostic t) {
}
@Override
public int getLineNumber(Diagnostic t) {
return Integer.parseInt(t.getCode().substring(ERR_CODE_PREFIX.length()));
String text = t.getCode().substring(ERR_CODE_PREFIX.length());
int idx = text.indexOf(',');
return Integer.parseInt(text.substring(0, idx));
}
@Override
public ErrorsCache.Range getRange(Diagnostic t) {
String text = t.getCode().substring(ERR_CODE_PREFIX.length());
int idx1 = text.indexOf(',');
int idx2 = text.indexOf('-');
int idx3 = text.indexOf(',', idx2);
ErrorsCache.Position start = new ErrorsCache.Position(Integer.parseInt(text.substring(0, idx1)), Integer.parseInt(text.substring(idx1 + 1, idx2)));
ErrorsCache.Position end = new ErrorsCache.Position(Integer.parseInt(text.substring(idx2 + 1, idx3)), Integer.parseInt(text.substring(idx3 + 1, text.length())));
return new ErrorsCache.Range(start, end);
}
@Override
public String getMessage(Diagnostic t) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,29 @@ public int getLineNumber(SimpleError error) {
return lineNumber;
}
@Override
public ErrorsCache.Range getRange(SimpleError error) {
int originalOffset = error.getStartPosition(); //snapshot offset
int lineNumber = 1;
int colNumber = 1;
if (originalOffset >= 0) {
int idx = Collections.binarySearch(lineStartOffsets, originalOffset);
if (idx < 0) {
// idx == (-(insertion point) - 1) -> (insertion point) == -idx - 1
int ln = -idx - 1;
assert ln >= 1 && ln <= lineStartOffsets.size() :
"idx=" + idx + ", lineNumber=" + ln + ", lineStartOffsets.size()=" + lineStartOffsets.size(); //NOI18N
if (ln >= 1 && ln <= lineStartOffsets.size()) {
lineNumber = ln;
colNumber = originalOffset - lineStartOffsets.get(ln - 1);
}
} else {
lineNumber = idx + 1;
}
}

return new ErrorsCache.Range(new ErrorsCache.Position(lineNumber, colNumber), null);
}
@Override
public String getMessage(SimpleError error) {
return error.getDisplayName();
}
Expand Down
14 changes: 14 additions & 0 deletions ide/parsing.indexing/apichanges.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,20 @@ is the proper place.
<!-- ACTUAL CHANGES BEGIN HERE: -->

<changes>
<change id="ErrorsCache.getErrors">
<api name="IndexingAPI"/>
<summary>Added method to ErrorsCache to return all errors or warnings for the given file</summary>
<version major="9" minor="40"/>
<date day="6" month="9" year="2024"/>
<author login="dbalek"/>
<compatibility source="compatible" binary="compatible" semantic="compatible" addition="yes"/>
<description>
<p>
Added the <a href="@TOP@/org/netbeans/modules/parsing/spi/indexing/ErrorsCache.html#getErrors-org.openide.filesystems.FileObject-org.netbeans.modules.parsing.spi.indexing.ErrorsCache.ReverseConvertor-">getErrors()</a> method to return errors or warnings for the given file.
</p>
</description>
<class package="org.netbeans.modules.parsing.spi.indexing" name="ErrorsCache"/>
</change>
<change id="ErrorsCache.getAllFilesWithRecord">
<api name="IndexingAPI"/>
<summary>Added method to ErrorsCache to return all files with error or warning</summary>
Expand Down
4 changes: 2 additions & 2 deletions ide/parsing.indexing/nbproject/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
javac.source=1.8
javac.release=17
javac.compilerargs=-Xlint -Xlint:-serial
spec.version.base=9.39.0
spec.version.base=9.40.0
is.autoload=true
javadoc.apichanges=${basedir}/apichanges.xml
javadoc.arch=${basedir}/arch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.project.FileOwnerQuery;
Expand All @@ -53,8 +55,10 @@
import org.netbeans.modules.parsing.impl.indexing.PathRegistry;
import org.netbeans.modules.parsing.impl.indexing.URLCache;
import org.netbeans.modules.parsing.impl.indexing.implspi.CacheFolderProvider;
import org.netbeans.modules.parsing.spi.indexing.ErrorsCache;
import org.netbeans.modules.parsing.spi.indexing.ErrorsCache.Convertor;
import org.netbeans.modules.parsing.spi.indexing.ErrorsCache.ErrorKind;
import org.netbeans.modules.parsing.spi.indexing.ErrorsCache.ReverseConvertor;
import org.netbeans.modules.parsing.spi.indexing.Indexable;
import org.netbeans.spi.tasklist.Task;
import org.openide.filesystems.FileObject;
Expand All @@ -77,6 +81,10 @@ public class TaskCache {

private static final Logger LOG = Logger.getLogger(TaskCache.class.getName());

// Matches the diagnostic range with both the start and the end positions specified (e.g. 1,2-1,7)
// or with only the start position specified (e.g. 1,2) where positions are written in a form line,column
private static final Pattern PATTERN = Pattern.compile("(\\d*),(\\d*)(?:-(\\d*),(\\d*))?");

static {
// LOG.setLevel(Level.FINEST);
}
Expand All @@ -103,17 +111,31 @@ private String getTaskType( ErrorKind k ) {
}
return null;
}


private ReverseConvertor<Task> getTaskConvertor(FileObject file) {
return (kind, range, message) -> {
String severity = getTaskType(kind);
if (null != severity) {
return Task.create(file, severity, message, range.start().line());
}
return null;
};
}

public List<Task> getErrors(FileObject file) {
List<Task> result = new LinkedList<Task>();
return getErrors(file, getTaskConvertor(file));
}

public <T> List<T> getErrors(FileObject file, ReverseConvertor<T> convertor) {
List<T> result = new LinkedList<>();

result.addAll(getErrors(file, ERR_EXT));
result.addAll(getErrors(file, WARN_EXT));
result.addAll(getErrors(file, convertor, ERR_EXT));
result.addAll(getErrors(file, convertor, WARN_EXT));

return result;
}

private List<Task> getErrors(FileObject file, String ext) {
private <T> List<T> getErrors(FileObject file, ReverseConvertor<T> convertor, String ext) {
LOG.log(Level.FINE, "getErrors, file={0}, ext={1}", new Object[] {FileUtil.getFileDisplayName(file), ext}); //NOI18N

try {
Expand All @@ -122,16 +144,16 @@ private List<Task> getErrors(FileObject file, String ext) {
LOG.log(Level.FINE, "getErrors, error file={0}", input == null ? "null" : input.getAbsolutePath()); //NOI18N

if (input == null || !input.canRead())
return Collections.<Task>emptyList();
return Collections.emptyList();

input.getParentFile().mkdirs();

return loadErrors(input, file);
return loadErrors(input, convertor);
} catch (IOException e) {
LOG.log(Level.FINE, null, e);
}

return Collections.<Task>emptyList();
return Collections.emptyList();
}

private <T> boolean dumpErrors(File output, Iterable<? extends T> errors, Convertor<T> convertor, boolean interestedInReturnValue) throws IOException {
Expand All @@ -144,7 +166,15 @@ private <T> boolean dumpErrors(File output, Iterable<? extends T> errors, Conver
for (T err : errors) {
pw.print(convertor.getKind(err).name());
pw.print(':'); //NOI18N
pw.print(convertor.getLineNumber(err));
ErrorsCache.Range range = convertor.getRange(err);
if (range != null) {
pw.print(String.format("%d,%d", range.start().line(), range.start().column()));
if (range.end() != null) {
pw.print(String.format("-%d,%d", range.end().line(), range.end().column()));
}
} else {
pw.print(convertor.getLineNumber(err));
}
pw.print(':'); //NOI18N

String description = convertor.getMessage(err);
Expand Down Expand Up @@ -200,6 +230,7 @@ public <T> void dumpErrors(final URL root, final Indexable i, final Iterable<? e
}
});
} catch (IOException ex) {
Exceptions.attachMessage(ex, "can't dump errors for: " + String.valueOf(i));
Exceptions.printStackTrace(ex);
}
}
Expand Down Expand Up @@ -255,8 +286,8 @@ private <T> void dumpErrors(TransactionContext c, URL root, Indexable i, Iterabl
c.rootsToRefresh.add(root);
}

private List<Task> loadErrors(File input, FileObject file) throws IOException {
List<Task> result = new LinkedList<Task>();
private <T> List<T> loadErrors(File input, ReverseConvertor<T> convertor) throws IOException {
List<T> result = new LinkedList<>();
BufferedReader pw = new BufferedReader(new InputStreamReader(new FileInputStream(input), StandardCharsets.UTF_8));
String line;

Expand All @@ -277,18 +308,26 @@ private List<Task> loadErrors(File input, FileObject file) throws IOException {
continue;
}

int lineNumber = Integer.parseInt(parts[1]);
String message = parts[2];
ErrorsCache.Range range;
Matcher matcher = PATTERN.matcher(parts[1]);
if (matcher.matches()) {
ErrorsCache.Position start = new ErrorsCache.Position(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)));
ErrorsCache.Position end = matcher.group(3) != null && matcher.group(4) != null ? new ErrorsCache.Position(Integer.parseInt(matcher.group(3)), Integer.parseInt(matcher.group(4))) : null;
range = new ErrorsCache.Range(start, end);
} else {
int lineNumber = Integer.parseInt(parts[1]);
range = new ErrorsCache.Range(new ErrorsCache.Position(lineNumber, 1), null);
}

message = message.replaceAll("\\\\d", ":"); //NOI18N
message = message.replaceAll("\\\\n", " "); //NOI18N
message = message.replaceAll("\\\\\\\\", "\\\\"); //NOI18N
String message = parts[2];

String severity = getTaskType(kind);
message = message.replace("\\d", ":") //NOI18N
.replace("\\n", "\n") //NOI18N
.replace("\\\\", "\\"); //NOI18N

if (null != severity) {
Task err = Task.create(file, severity, message, lineNumber);
result.add(err);
T item = convertor.get(kind, range, message);
if (null != item) {
result.add(item);
}
}

Expand Down Expand Up @@ -351,12 +390,12 @@ private List<URL> getAllFilesWithRecord(URL root, boolean onlyErrors) throws IOE
public List<URL> getAllFilesInError(URL root) throws IOException {
return getAllFilesWithRecord(root, true);
}

public boolean isInError(FileObject file, boolean recursive) {
LOG.log(Level.FINE, "file={0}, recursive={1}", new Object[] {file, Boolean.valueOf(recursive)}); //NOI18N

if (file.isData()) {
return !getErrors(file, ERR_EXT).isEmpty();
return !getErrors(file, getTaskConvertor(file), ERR_EXT).isEmpty();
} else {
try {
ClassPath cp = Utilities.getSourceClassPathFor (file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.netbeans.modules.parsing.impl.indexing.errors.TaskCache;
import org.openide.filesystems.FileObject;

Expand Down Expand Up @@ -74,12 +75,46 @@ public static Collection<? extends URL> getAllFilesWithRecord(URL root) throws I
return Collections.unmodifiableCollection(TaskCache.getDefault().getAllFilesWithRecord(root));
}

/**Getter for properties of the given error description.
/**Return all errors or warnings for the given file
*
* @param file file for which the errors are being retrieved
* @param convertor constructor of {@code T} instances from error description properties
* @return errors or warnings
* @since 9.40
*/
public static <T> List<T> getErrors(FileObject file, ReverseConvertor<T> convertor) throws IOException {
return Collections.unmodifiableList(TaskCache.getDefault().getErrors(file, convertor));
}

/**Position in a text expressed as 1-based line and character offset.
* @since 9.40
*/
public record Position(int line, int column) {}

/**Range in a text expressed as (1-based) start and end positions.
* @since 9.40
*/
public record Range(Position start, Position end) {}

/**Getter for properties of the given error description including the range.
*/
public static interface Convertor<T> {
public ErrorKind getKind(T t);
public int getLineNumber(T t);
public String getMessage(T t);
/**
* @since 9.40
*/
public default Range getRange(T t) {
return null;
}
}

/**Constructor of error description from the properties.
* @since 9.40
*/
public static interface ReverseConvertor<T> {
public T get(ErrorKind kind, Range range, String message);
}

public static enum ErrorKind {
Expand Down
Loading
Loading