| /*=============================================================================# |
| # 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 ); |
| } |
| |
| } |