/*=============================================================================#
# Copyright (c) 2012-2016 Stephan Wahlbrink (WalWare.de) and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Stephan Wahlbrink - initial API and implementation
#=============================================================================*/
package de.walware.docmlet.tex.internal.core.model;
import static de.walware.docmlet.tex.core.model.ILtxModelProblemConstants.STATUS2_LABEL_UNDEFINED;
import java.util.ArrayList;
import java.util.List;
import de.walware.jcommons.collections.ImList;
import de.walware.ecommons.MessageBuilder;
import de.walware.ecommons.ltk.IProblem;
import de.walware.ecommons.ltk.IProblemRequestor;
import de.walware.ecommons.ltk.core.SourceContent;
import de.walware.ecommons.ltk.core.impl.Problem;
import de.walware.ecommons.ltk.core.model.INameAccessSet;
import de.walware.ecommons.ltk.core.model.ISourceUnit;
import de.walware.ecommons.text.core.ILineInformation;
import de.walware.docmlet.tex.core.ast.TexAstNode;
import de.walware.docmlet.tex.core.model.ILtxModelInfo;
import de.walware.docmlet.tex.core.model.ITexSourceUnit;
import de.walware.docmlet.tex.core.model.TexModel;
import de.walware.docmlet.tex.core.model.TexNameAccess;
public class LtxProblemModelCheck {
private static final int REF_LABEL_LIMIT = 50;
private static final int BUFFER_SIZE = 100;
private ISourceUnit fCurrentUnit;
private String fCurrentText;
private ILineInformation fCurrentLines;
private IProblemRequestor fCurrentRequestor;
private final MessageBuilder fMessageBuilder = new MessageBuilder();
private final List<IProblem> fProblemBuffer = new ArrayList<>(BUFFER_SIZE);
private final int fLevelRefUndefined = IProblem.SEVERITY_WARNING;
public void run(final ITexSourceUnit su, final SourceContent content,
final ILtxModelInfo model, final IProblemRequestor requestor) {
try {
fCurrentUnit = su;
fCurrentText = content.getText();
fCurrentLines = content.getLines();
fCurrentRequestor = requestor;
checkLabels(model);
if (fProblemBuffer.size() > 0) {
fCurrentRequestor.acceptProblems(TexModel.LTX_TYPE_ID, fProblemBuffer);
}
}
// catch (final InvocationTargetException e) {}
finally {
fProblemBuffer.clear();
fCurrentUnit = null;
fCurrentRequestor = null;
}
}
private void checkLabels(final ILtxModelInfo model) {
final INameAccessSet<TexNameAccess> labelSet = model.getLabels();
final List<String> labels = labelSet.getNames();
ITER_LABELS: for (final String label : labels) {
if (label != null && label.length() > 0) {
final ImList<TexNameAccess> accessList= labelSet.getAllInUnit(label);
for (final TexNameAccess access : accessList) {
if (access.isWriteAccess()) {
continue ITER_LABELS;
}
}
for (final TexNameAccess access : accessList) {
final TexAstNode nameNode = access.getNameNode();
addProblem(fLevelRefUndefined, STATUS2_LABEL_UNDEFINED,
fMessageBuilder.bind(ProblemMessages.Labels_UndefinedRef_message, access.getDisplayName()),
nameNode.getOffset(), nameNode.getEndOffset() );
}
}
}
}
protected final void addProblem(final int severity, final int code, final String message,
int startOffset, int stopOffset) {
if (startOffset < 0) {
startOffset = 0;
}
if (stopOffset > fCurrentText.length()) {
stopOffset = fCurrentText.length();
}
fProblemBuffer.add(new Problem(TexModel.LTX_TYPE_ID, severity, code, message, fCurrentUnit,
startOffset, stopOffset ));
if (fProblemBuffer.size() >= BUFFER_SIZE) {
fCurrentRequestor.acceptProblems(TexModel.LTX_TYPE_ID, fProblemBuffer);
fProblemBuffer.clear();
}
}
}