| /*=============================================================================# |
| # Copyright (c) 2012, 2018 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.internal.docmlet.tex.core.model; |
| |
| import static org.eclipse.statet.docmlet.tex.core.model.ILtxModelProblemConstants.STATUS2_LABEL_UNDEFINED; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.statet.jcommons.collections.ImList; |
| |
| import org.eclipse.statet.ecommons.runtime.core.util.MessageBuilder; |
| import org.eclipse.statet.ecommons.text.core.ILineInformation; |
| |
| import org.eclipse.statet.docmlet.tex.core.ast.TexAstNode; |
| import org.eclipse.statet.docmlet.tex.core.model.ILtxModelInfo; |
| import org.eclipse.statet.docmlet.tex.core.model.ITexSourceUnit; |
| import org.eclipse.statet.docmlet.tex.core.model.TexModel; |
| import org.eclipse.statet.docmlet.tex.core.model.TexNameAccess; |
| import org.eclipse.statet.ltk.core.SourceContent; |
| import org.eclipse.statet.ltk.issues.core.BasicProblem; |
| import org.eclipse.statet.ltk.issues.core.Problem; |
| import org.eclipse.statet.ltk.issues.core.ProblemRequestor; |
| import org.eclipse.statet.ltk.model.core.elements.ISourceUnit; |
| import org.eclipse.statet.ltk.model.core.elements.NameAccessSet; |
| |
| |
| public class LtxProblemModelCheck { |
| |
| |
| private static final int REF_LABEL_LIMIT= 50; |
| private static final int BUFFER_SIZE= 100; |
| |
| |
| private ISourceUnit currentUnit; |
| private String currentText; |
| private ILineInformation currentLines; |
| private ProblemRequestor currentRequestor; |
| |
| private final MessageBuilder messageBuilder= new MessageBuilder(); |
| private final List<Problem> problemBuffer= new ArrayList<>(BUFFER_SIZE); |
| |
| private final int levelRefUndefined= Problem.SEVERITY_WARNING; |
| |
| |
| public void run(final ITexSourceUnit su, final SourceContent content, |
| final ILtxModelInfo model, final ProblemRequestor requestor) { |
| try { |
| this.currentUnit= su; |
| this.currentText= content.getText(); |
| this.currentLines= content.getLines(); |
| |
| this.currentRequestor= requestor; |
| checkLabels(model); |
| if (this.problemBuffer.size() > 0) { |
| this.currentRequestor.acceptProblems(TexModel.LTX_TYPE_ID, this.problemBuffer); |
| } |
| } |
| // catch (final InvocationTargetException e) {} |
| finally { |
| this.problemBuffer.clear(); |
| this.currentUnit= null; |
| this.currentRequestor= null; |
| } |
| } |
| |
| |
| private void checkLabels(final ILtxModelInfo model) { |
| final NameAccessSet<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(this.levelRefUndefined, STATUS2_LABEL_UNDEFINED, |
| this.messageBuilder.bind(ProblemMessages.Labels_UndefinedRef_message, access.getDisplayName()), |
| nameNode.getStartOffset(), nameNode.getEndOffset() ); |
| } |
| } |
| } |
| } |
| |
| protected final void addProblem(final int severity, final int code, final String message, |
| int startOffset, int endOffset) { |
| if (startOffset < 0) { |
| startOffset= 0; |
| } |
| if (endOffset > this.currentText.length()) { |
| endOffset= this.currentText.length(); |
| } |
| this.problemBuffer.add(new BasicProblem(TexModel.LTX_TYPE_ID, severity, code, message, |
| startOffset, endOffset )); |
| if (this.problemBuffer.size() >= BUFFER_SIZE) { |
| this.currentRequestor.acceptProblems(TexModel.LTX_TYPE_ID, this.problemBuffer); |
| this.problemBuffer.clear(); |
| } |
| } |
| |
| } |