/**
* Aptana Studio
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.editor.php.formatter.nodes;
import com.aptana.editor.php.formatter.PHPFormatterConstants;
import com.aptana.formatter.IFormatterContext;
import com.aptana.formatter.IFormatterDocument;
import com.aptana.formatter.IFormatterWriter;
import com.aptana.formatter.nodes.FormatterBlockWithBeginEndNode;
import com.aptana.formatter.nodes.NodeTypes.TypeBracket;
/**
* A PHP node formatter for parentheses, which can be used for any other single char open and close pair, such as
* brackets etc.
*
* @author Shalom Gibly <sgibly@aptana.com>
*/
public class FormatterPHPParenthesesNode extends FormatterBlockWithBeginEndNode
{
private boolean asWrapper;
private boolean newLineBeforeClosing;
private TypeBracket parenthesesType;
private int containedElementsCount;
/**
* Constructs a new FormatterPHPParenthesesNode
*
* @param document
* @param asWrapper
* Indicate that these parentheses do not have an open and close brackets, but is acting as a wrapper
* node for an expression that appears inside it. For example, an 'echo' statement without the
* @param forceSameLine
* Force the open and close parentheses.
* @param type
* The bracket (parentheses) type - a {@link TypeBracket} value.
*/
public FormatterPHPParenthesesNode(IFormatterDocument document, boolean asWrapper, int containedElementsCount,
TypeBracket type)
{
super(document);
this.asWrapper = asWrapper;
this.containedElementsCount = containedElementsCount;
this.parenthesesType = type;
}
/**
* Constructs a new FormatterPHPParenthesesNode
*
* @param document
*/
public FormatterPHPParenthesesNode(IFormatterDocument document, TypeBracket type)
{
this(document, false, 0, type);
}
/**
* Force a new line before the closing parentheses.<br>
* The new line will only be inserted when this node is <b>not</b> a wrapper node.
*
* @param newLineBeforeClosing
*/
public void setNewLineBeforeClosing(boolean newLineBeforeClosing)
{
this.newLineBeforeClosing = newLineBeforeClosing;
}
/*
* (non-Javadoc)
* @see com.aptana.formatter.nodes.AbstractFormatterNode#getSpacesCountBefore()
*/
@Override
public int getSpacesCountBefore()
{
if (isAsWrapper())
{
return 1;
}
switch (parenthesesType)
{
case DECLARATION_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_OPENING_DECLARATION_PARENTHESES);
case INVOCATION_PARENTHESIS:
case ARRAY_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_OPENING_INVOCATION_PARENTHESES);
case ARRAY_SQUARE:
return getInt(PHPFormatterConstants.SPACES_BEFORE_OPENING_ARRAY_ACCESS_PARENTHESES);
case CONDITIONAL_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_OPENING_CONDITIONAL_PARENTHESES);
case LOOP_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_OPENING_LOOP_PARENTHESES);
default:
return 0;
}
}
/**
* We override the acceptBody to control any spaces that should be added before or after the body.
*
* @see com.aptana.formatter.nodes.FormatterBlockNode#acceptBody(com.aptana.formatter.IFormatterContext,
* com.aptana.formatter.IFormatterWriter)
*/
@Override
protected void acceptBody(IFormatterContext context, IFormatterWriter visitor) throws Exception
{
int spacesBeforeBody = getSpacesBeforeBody();
if (spacesBeforeBody > 0)
{
writeSpaces(visitor, context, spacesBeforeBody);
}
super.acceptBody(context, visitor);
int spacesAfterBody = getSpacesAfterBody();
if (spacesAfterBody > 0)
{
writeSpaces(visitor, context, spacesAfterBody);
}
}
/*
* (non-Javadoc)
* @see com.aptana.formatter.nodes.AbstractFormatterNode#shouldConsumePreviousWhiteSpaces()
*/
@Override
public boolean shouldConsumePreviousWhiteSpaces()
{
return true;
}
/**
* @return the asWrapper
*/
public boolean isAsWrapper()
{
return asWrapper;
}
/*
* (non-Javadoc)
* @see com.aptana.formatter.nodes.FormatterBlockNode#isIndenting()
*/
@Override
protected boolean isIndenting()
{
switch (parenthesesType)
{
case ARRAY_PARENTHESIS:
return getDocument().getBoolean(PHPFormatterConstants.NEW_LINES_BETWEEN_ARRAY_CREATION_ELEMENTS);
}
return super.isIndenting();
}
/*
* (non-Javadoc)
* @see com.aptana.formatter.nodes.FormatterBlockNode#isAddingEndNewLine()
*/
@Override
protected boolean isAddingEndNewLine()
{
if (!asWrapper && newLineBeforeClosing)
{
return true;
}
switch (parenthesesType)
{
case ARRAY_PARENTHESIS:
if (containedElementsCount > 1)
{
return getDocument().getBoolean(PHPFormatterConstants.NEW_LINES_BETWEEN_ARRAY_CREATION_ELEMENTS);
}
}
return false;
}
/**
* @return The amount of spaces that we should insert before the body.
*/
private int getSpacesBeforeBody()
{
if (isAsWrapper())
{
return 0;
}
switch (parenthesesType)
{
case DECLARATION_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_AFTER_OPENING_DECLARATION_PARENTHESES);
case INVOCATION_PARENTHESIS:
case ARRAY_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_AFTER_OPENING_INVOCATION_PARENTHESES);
case ARRAY_SQUARE:
return getInt(PHPFormatterConstants.SPACES_AFTER_OPENING_ARRAY_ACCESS_PARENTHESES);
case CONDITIONAL_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_AFTER_OPENING_CONDITIONAL_PARENTHESES);
case LOOP_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_AFTER_OPENING_LOOP_PARENTHESES);
default:
return 0;
}
}
/**
* @return The amount of spaces that we should insert after the body.
*/
private int getSpacesAfterBody()
{
if (isAsWrapper())
{
return 0;
}
switch (parenthesesType)
{
case DECLARATION_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_CLOSING_DECLARATION_PARENTHESES);
case INVOCATION_PARENTHESIS:
case ARRAY_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_CLOSING_INVOCATION_PARENTHESES);
case ARRAY_SQUARE:
return getInt(PHPFormatterConstants.SPACES_BEFORE_CLOSING_ARRAY_ACCESS_PARENTHESES);
case CONDITIONAL_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_CLOSING_CONDITIONAL_PARENTHESES);
case LOOP_PARENTHESIS:
return getInt(PHPFormatterConstants.SPACES_BEFORE_CLOSING_LOOP_PARENTHESES);
default:
return 0;
}
}
}