/**
* 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.internal.ui.editor;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org2.eclipse.php.internal.ui.preferences.PreferenceConstants;
import com.aptana.editor.common.AbstractThemeableEditor;
import com.aptana.editor.common.text.AbstractFoldingComputer;
import com.aptana.editor.html.HTMLFoldingComputer;
import com.aptana.editor.php.epl.PHPEplPlugin;
import com.aptana.editor.php.internal.core.IPHPConstants;
import com.aptana.editor.php.internal.parser.PHPParseRootNode;
import com.aptana.editor.php.internal.parser.nodes.PHPBaseParseNode;
import com.aptana.editor.php.internal.parser.nodes.PHPClassParseNode;
import com.aptana.editor.php.internal.parser.nodes.PHPCommentNode;
import com.aptana.editor.php.internal.parser.nodes.PHPFunctionParseNode;
import com.aptana.parsing.ast.IParseNode;
public class PHPFoldingComputer extends AbstractFoldingComputer
{
private boolean hasCachedAST;
public PHPFoldingComputer(AbstractThemeableEditor editor, IDocument document)
{
super(editor, document);
}
@Override
public boolean isFoldable(IParseNode child)
{
if (IPHPConstants.CONTENT_TYPE_PHP.equals(child.getLanguage()))
{
// FIXME The PHP parser hacks php start/end blocks. It just creates one PHPBlockNode with 0,0 offsets to
// hold
// all children and then grabs the children out of it and attaches them to the parse root node.
// So until that is changed, there's no way to be able to fold <?php ... ?> blocks.
if (child instanceof PHPCommentNode)
{
PHPCommentNode commentNode = (PHPCommentNode) child;
return commentNode.isMultiline() || commentNode.isPHPDoc();
}
switch (child.getNodeType())
{
case PHPBaseParseNode.HTML_NODE:
case PHPBaseParseNode.FUNCTION_NODE:
case PHPBaseParseNode.CLASS_NODE:
case PHPBaseParseNode.FOR_NODE:
case PHPBaseParseNode.WHILE_NODE:
case PHPBaseParseNode.DO_NODE:
case PHPBaseParseNode.SWITCH_NODE:
case PHPBaseParseNode.SWITCH_CASE_NODE:
case PHPBaseParseNode.TRY_NODE:
case PHPBaseParseNode.CATCH_NODE:
case PHPBaseParseNode.IF_ELSE_NODE:
return true;
}
return false;
}
return htmlFoldingComputer().isFoldable(child);
}
private synchronized AbstractFoldingComputer htmlFoldingComputer()
{
return new HTMLFoldingComputer(getEditor(), getDocument());
}
@Override
public boolean isCollapsed(IParseNode child)
{
if (IPHPConstants.CONTENT_TYPE_PHP.equals(child.getLanguage()))
{
if (child instanceof PHPFunctionParseNode)
{
return Platform.getPreferencesService().getBoolean(PHPEplPlugin.PLUGIN_ID,
PreferenceConstants.EDITOR_FOLDING_FUNCTIONS, false, null);
}
if (child instanceof PHPClassParseNode)
{
return Platform.getPreferencesService().getBoolean(PHPEplPlugin.PLUGIN_ID,
PreferenceConstants.EDITOR_FOLDING_CLASSES, false, null);
}
if (child instanceof PHPCommentNode)
{
PHPCommentNode commentNode = (PHPCommentNode) child;
if (commentNode.isPHPDoc())
{
return Platform.getPreferencesService().getBoolean(PHPEplPlugin.PLUGIN_ID,
PreferenceConstants.EDITOR_FOLDING_PHPDOC, false, null);
}
return Platform.getPreferencesService().getBoolean(PHPEplPlugin.PLUGIN_ID,
PreferenceConstants.EDITOR_FOLDING_COMMENTS, false, null);
}
}
return htmlFoldingComputer().isCollapsed(child);
}
/*
* (non-Javadoc)
* @see
* com.aptana.editor.common.text.AbstractFoldingComputer#getPositions(org.eclipse.core.runtime.IProgressMonitor,
* com.aptana.parsing.ast.IParseNode)
*/
@Override
protected Map<ProjectionAnnotation, Position> getPositions(IProgressMonitor monitor, IParseNode parseNode)
{
if (parseNode instanceof PHPParseRootNode)
{
hasCachedAST = ((PHPParseRootNode) parseNode).isCached();
}
return super.getPositions(monitor, parseNode);
}
/**
* Returns <code>true</code> if the {@link #getPositions(IProgressMonitor, IParseNode)} call detected that the AST
* that was passed is cached (e.g. there is a parse error that prevented a creation of a new AST).
*
* @return <code>true</code> if the AST is cached; <code>false</code> otherwise.
*/
public boolean hasCachedAST()
{
return hasCachedAST;
}
}