blob: 07922cd30eed62396bdf483bba97aaac7e6a0322 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2005, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ltk.issues.core.impl;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.ltk.core.source.SourceContent;
import org.eclipse.statet.ltk.issues.core.IssueRequestor;
import org.eclipse.statet.ltk.issues.core.TaskIssueConfig;
import org.eclipse.statet.ltk.issues.core.TaskPriority;
import org.eclipse.statet.ltk.issues.core.TaskTag;
@NonNullByDefault
public abstract class TaskTagReporter {
private ImList<TaskTag> taskTags= ImCollections.emptyList();
private @Nullable Pattern taskTagPattern;
private final Map<String, TaskPriority> taskTagMap= new HashMap<>();
private SourceContent sourceContent= nonNullLateInit();
private IssueRequestor requestor= nonNullLateInit();
private @Nullable Matcher taskTagMatcher;
public TaskTagReporter() {
}
public void configure(final TaskIssueConfig config) {
initTaskPattern(config.getTaskTags());
}
protected void initTaskPattern(final ImList<TaskTag> taskTags) {
if (taskTags.equals(this.taskTags)) {
return;
}
this.taskTags= taskTags;
this.taskTagPattern= null;
this.taskTagMap.clear();
if (taskTags.isEmpty()) {
return;
}
final String separatorRegex= "[^\\p{L}\\p{N}]"; //$NON-NLS-1$
final StringBuilder regex= new StringBuilder(separatorRegex);
regex.append('(');
for (final TaskTag taskTag : taskTags) {
regex.append(Pattern.quote(taskTag.getKeyword()));
regex.append('|');
this.taskTagMap.put(taskTag.getKeyword(), taskTag.getPriority());
}
regex.setCharAt(regex.length() - 1, ')');
regex.append("(?:\\z|").append(separatorRegex).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
this.taskTagPattern= Pattern.compile(regex.toString());
}
public void setup(final SourceContent sourceContent, final IssueRequestor requestor) {
this.sourceContent= nonNullAssert(sourceContent);
this.requestor= nonNullAssert(requestor);
final Pattern taskTagPattern= this.taskTagPattern;
this.taskTagMatcher= (taskTagPattern != null && sourceContent.getStartOffset() == 0) ?
taskTagPattern.matcher(sourceContent.getString()) :
null;
}
public void addTask(final String match, final String message,
final int offset, final int lineNumber) {
final TaskPriority priority= this.taskTagMap.get(match);
if (priority == null) {
return;
}
final var task= new BasicTask(priority, message,
lineNumber, offset, offset + message.length() );
this.requestor.acceptTask(task);
}
public void checkForTasks(final int startOffset, int endOffset) {
final Matcher matcher= this.taskTagMatcher;
if (matcher == null) {
return;
}
if (matcher.region(startOffset, endOffset).find()) {
final int tagStartOffset= matcher.start(1);
final int tagEndOffset= matcher.end(1);
while (endOffset > tagEndOffset) {
if (this.sourceContent.getChar(endOffset - 1) <= ' ') {
endOffset--;
continue;
}
else {
break;
}
}
final String text= this.sourceContent.getString(tagStartOffset, endOffset);
addTask(nonNullAssert(matcher.group(1)), text, tagStartOffset,
this.sourceContent.getStringLines().getLineOfOffset(tagStartOffset) + 1 );
}
}
}