* Copyright (C) 2010 Robert Futrell
* robert_futrell at users.sourceforge.net
* http://fifesoft.com/rsyntaxtextarea
* This library is distributed under a modified BSD license. See the included
* RSTALanguageSupport.License.txt file for details.
package org.fife.rsta.ac.java.rjc.ast;
import java.util.ArrayList;
import org.fife.rsta.ac.java.rjc.lang.Modifiers;
import org.fife.rsta.ac.java.rjc.lang.Type;
import org.fife.rsta.ac.java.rjc.lexer.Offset;
import org.fife.rsta.ac.java.rjc.lexer.TokenTypes;
* A block of code in curly braces in a class.<p>
* This class implements the <code>Member</code> interface because a block
* can be a member (say, a static block in a class declaration), but usually
* it's not actually a <code>Member</code>, but something else, e.g. the body
* of a method, or the content of an <code>if</code>-statement, etc.
public class CodeBlock extends AbstractMember {
* The name of all <code>CodeBlock</code>s.
public static final String NAME = "{...}";
private CodeBlock parent;
private boolean isStatic;
public CodeBlock(boolean isStatic, Offset startOffs) {
this.isStatic = isStatic;
public void add(CodeBlock child) {
children = new ArrayList();
public void addLocalVariable(LocalVariable localVar) {
localVars = new ArrayList();
public boolean containsOffset(int offs) {
// Do endOffset first since we'll often iterate from first CodeBlock
// to last, so checking it first should be faster.
return getNameEndOffset()>=offs && getNameStartOffset()<=offs;
public CodeBlock getChildBlock(int index) {
return (CodeBlock)children.get(index);
public int getChildBlockCount() {
return children==null ? 0 : children.size();
* Returns the deepest code block nested under this one (or this one
* itself) containing a given offset.
* @param offs The offset to look for.
* @return The deepest-nested code block containing the offset, or
* <code>null</code> if this code block and none of its children
public CodeBlock getDeepestCodeBlockContaining(int offs) {
if (!containsOffset(offs)) {
for (int i=0; i<getChildBlockCount(); i++) {
CodeBlock child = getChildBlock(i);
if (child.containsOffset(offs)) {
return child.getDeepestCodeBlockContaining(offs);
public String getDocComment() {
// TODO: Can static blocks have doc comments?
public LocalVariable getLocalVar(int index) {
return (LocalVariable)localVars.get(index);
public int getLocalVarCount() {
return localVars==null ? 0 : localVars.size();
* Returns all local variables declared before a given offset, both in
* this code block and in all parent blocks.
* @param offs The offset.
* @return The {@link LocalVariable}s, or an empty list of none were
* declared before the offset.
public List getLocalVarsBefore(int offs) {
List vars = new ArrayList();
for (int i=0; i<getLocalVarCount(); i++) {
LocalVariable localVar = getLocalVar(i);
if (localVar.getNameStartOffset()<offs) {
vars.addAll(parent.getLocalVarsBefore(offs));
public Modifiers getModifiers() {
Modifiers modifiers = new Modifiers();
modifiers.addModifier(TokenTypes.KEYWORD_STATIC);
public CodeBlock getParent() {
* Returns <code>null</code>, since blocks don't have types.
* @return <code>null</code> always.
public boolean isDeprecated() {
* Returns whether this block is a static block (in a class declaration).
* @return Whether this is a static code block.
public boolean isStatic() {
public void setParent(CodeBlock parent) {