blob: 13057b2df4eb4d38e88b5d0258a2b4ac9df77e41 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2014, 2019 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.redocs.r.core.source;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.statet.ecommons.text.core.sections.IDocContentSections;
import org.eclipse.statet.ecommons.text.core.treepartitioner.ITreePartitionNode;
import org.eclipse.statet.ecommons.text.core.treepartitioner.TreePartitionUtils;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
public class RweaveDocSectionTreePartImpl {
private final IDocContentSections sections;
public RweaveDocSectionTreePartImpl(final IDocContentSections sections) {
this.sections= sections;
}
public IDocContentSections getSections() {
return this.sections;
}
public ITreePartitionNode getRChunkRegion(final IDocument document, final int offset)
throws BadLocationException {
return TreePartitionUtils.searchNode(document, this.sections.getPartitioning(), offset, false,
IRweaveDocumentConstants.RCHUNK_BASE_CONTENT_TYPE );
}
public List<ITreePartitionNode> getRChunkRegions(final IDocument document,
final int offset, final int length) throws BadLocationException {
final List<ITreePartitionNode> nodes= new ArrayList<>();
final ITreePartitionNode root= TreePartitionUtils.getRootNode(document, this.sections.getPartitioning());
addRChunkRegions(root, offset, offset + length, nodes);
return nodes;
}
private void addRChunkRegions(final ITreePartitionNode node, final int startOffset, final int endOffset,
final List<ITreePartitionNode> nodes) {
final int childCount= node.getChildCount();
int childIdx= 0;
for (; childIdx < childCount; childIdx++) {
final ITreePartitionNode child= node.getChild(childIdx);
if (child.getEndOffset() > startOffset) {
break;
}
}
for (; childIdx < childCount; childIdx++) {
final ITreePartitionNode child= node.getChild(childIdx);
if (child.getStartOffset() >= endOffset) {
break;
}
if (child.getType().getPartitionType() == IRweaveDocumentConstants.RCHUNK_BASE_CONTENT_TYPE) {
nodes.add(child);
}
else {
addRChunkRegions(child, startOffset, endOffset, nodes);
}
}
}
public IRegion getRChunkContentRegion(final IDocument document, final int offset)
throws BadLocationException {
final ITreePartitionNode rChunk= getRChunkRegion(document, offset);
if (rChunk == null || rChunk.getLength() <= 2) {
return null;
}
final int beginLine= document.getLineOfOffset(rChunk.getStartOffset()) + 1;
final int beginLineOffset= document.getLineOffset(beginLine);
int endLine= document.getLineOfOffset(rChunk.getEndOffset());
if (beginLine >= endLine) {
return null;
}
int endLineOffset= document.getLineOffset(endLine);
if (endLineOffset == rChunk.getEndOffset()) {
endLine--;
if (beginLine >= endLine) {
return null;
}
endLineOffset= document.getLineOffset(endLine);
}
if (document.getChar(endLineOffset) == '@') { // closed
return new Region(beginLineOffset, endLineOffset - beginLineOffset);
}
else { // node closed
return new Region(beginLineOffset, rChunk.getEndOffset() - beginLineOffset);
}
}
public List<ITreePartitionNode> getRChunkCodeRegions(final IDocument document,
final int offset, final int length) throws BadLocationException {
final List<ITreePartitionNode> rChunks= getRChunkRegions(document, offset, length);
final List<ITreePartitionNode> nodes= new ArrayList<>(rChunks.size());
final int endOffset= offset + length;
for (int i= 0; i < rChunks.size(); i++) {
final ITreePartitionNode node= rChunks.get(i);
final int childCount= node.getChildCount();
int childIdx= 0;
for (; childIdx < childCount; childIdx++) {
final ITreePartitionNode child= node.getChild(childIdx);
if (child.getEndOffset() > offset) {
break;
}
}
for (; childIdx < childCount; childIdx++) {
final ITreePartitionNode child= node.getChild(childIdx);
if (child.getStartOffset() >= endOffset) {
break;
}
if (child.getType().getPartitionType() == IRDocumentConstants.R_DEFAULT_CONTENT_TYPE) {
nodes.add(child);
}
}
}
return nodes;
}
public ITreePartitionNode getRCodeRegion(final IDocument document, final int offset)
throws BadLocationException {
return TreePartitionUtils.searchNode(document, this.sections.getPartitioning(), offset, true,
IRDocumentConstants.R_DEFAULT_CONTENT_TYPE );
}
}