package com.github.sommeri.less4j.core.ast; import java.util.ArrayList; import java.util.List; import com.github.sommeri.less4j.core.ast.annotations.NotAstProperty; import com.github.sommeri.less4j.core.parser.HiddenTokenAwareTree; import com.github.sommeri.less4j.utils.ArraysUtils; public abstract class Body extends ASTCssNode { private SyntaxOnlyElement openingCurlyBrace; private SyntaxOnlyElement closingCurlyBrace; private List<ASTCssNode> body = new ArrayList<ASTCssNode>(); public Body(HiddenTokenAwareTree underlyingStructure) { super(underlyingStructure); } public Body(HiddenTokenAwareTree underlyingStructure, SyntaxOnlyElement lbrace, SyntaxOnlyElement rbrace, List<ASTCssNode> members) { this(underlyingStructure); openingCurlyBrace = lbrace; closingCurlyBrace = rbrace; body.addAll(members); } public SyntaxOnlyElement getOpeningCurlyBrace() { return openingCurlyBrace; } public void setOpeningCurlyBrace(SyntaxOnlyElement openingCurlyBrace) { this.openingCurlyBrace = openingCurlyBrace; } public SyntaxOnlyElement getClosingCurlyBrace() { return closingCurlyBrace; } public void setClosingCurlyBrace(SyntaxOnlyElement closingCurlyBrace) { this.closingCurlyBrace = closingCurlyBrace; } @Override @NotAstProperty public List<ASTCssNode> getChilds() { List<ASTCssNode> result = ArraysUtils.asNonNullList((ASTCssNode) openingCurlyBrace); result.addAll(body); if (closingCurlyBrace != null) result.add(closingCurlyBrace); return result; } public List<ASTCssNode> getMembers() { return body; } public boolean isEmpty() { return body.isEmpty() && getOrphanComments().isEmpty(); } public void removeAllMembers() { body = new ArrayList<ASTCssNode>(); } public void addMembers(List<? extends ASTCssNode> members) { body.addAll(members); } public void addMembersAfter(List<? extends ASTCssNode> newMembers, ASTCssNode kid) { int index = body.indexOf(kid); if (index == -1) index = body.size(); else index++; body.addAll(index, newMembers); } public void addMemberAfter(ASTCssNode newMember, ASTCssNode kid) { int index = body.indexOf(kid); if (index == -1) index = body.size(); else index++; body.add(index, newMember); } public void addMember(ASTCssNode member) { body.add(member); } public void replaceMember(ASTCssNode oldMember, List<ASTCssNode> newMembers) { body.addAll(body.indexOf(oldMember), newMembers); body.remove(oldMember); oldMember.setParent(null); configureParentToAllChilds();//POSSIBLE OPTIMIZATION: all these could be more targetted } public void replaceMember(ASTCssNode oldMember, ASTCssNode newMember) { body.add(body.indexOf(oldMember), newMember); body.remove(oldMember); oldMember.setParent(null); newMember.setParent(this); } public List<ASTCssNode> membersByType(ASTCssNodeType type) { List<ASTCssNode> result = new ArrayList<ASTCssNode>(); List<ASTCssNode> body = getMembers(); for (ASTCssNode node : body) { if (node.getType() == type) { result.add(node); } } return result; } public List<ASTCssNode> membersByNotType(ASTCssNodeType type) { List<ASTCssNode> result = new ArrayList<ASTCssNode>(); List<ASTCssNode> body = getMembers(); for (ASTCssNode node : body) { if (node.getType() != type) { result.add(node); } } return result; } public boolean removeMember(ASTCssNode node) { return body.remove(node); } public boolean removeMembers(List<ASTCssNode> nodes) { return body.removeAll(nodes); } public Body clone() { Body result = (Body) super.clone(); result.body = ArraysUtils.deeplyClonedList(body); result.openingCurlyBrace = openingCurlyBrace == null ? null : openingCurlyBrace.clone(); result.closingCurlyBrace = closingCurlyBrace == null ? null : closingCurlyBrace.clone(); result.configureParentToAllChilds(); return result; } public Body emptyClone() { Body result = (Body) super.clone(); result.body = new ArrayList<ASTCssNode>(); return result; } public List<ASTCssNode> getDeclarations() { return membersByType(ASTCssNodeType.DECLARATION); } public List<ASTCssNode> getNotDeclarations() { return membersByNotType(ASTCssNodeType.DECLARATION); } @Override public void setParent(ASTCssNode parent) { if (parent != null && !(parent instanceof BodyOwner)) throw new IllegalArgumentException("Body parent must be a BodyOwner: " + parent.getType()); super.setParent(parent); } }