⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractifdirective.java

📁 eclipseme的最新版本的source,欢迎j2me程序员使用
💻 JAVA
字号:
/**
 * Copyright (c) 2003-2005 Craig Setera
 * All Rights Reserved.
 * Licensed under the Eclipse Public License - v 1.0
 * For more information see http://www.eclipse.org/legal/epl-v10.html
 */
package eclipseme.core.internal.preprocessor.directive;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.dom.Comment;
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 eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.preprocessor.Directive;
import eclipseme.core.internal.preprocessor.ProcessingState;
import eclipseme.core.model.SymbolDefinitionSet;

/**
 * Abstract superclass of all if conditional directives.
 * If directives define a set of conditional blocks that
 * are or are not enabled.
 * <p />
 * Copyright (c) 2003-2005 Craig Setera<br>
 * All Rights Reserved.<br>
 * Licensed under the Eclipse Public License - v 1.0<p/>
 * <br>
 * $Revision: 1.3 $
 * <br>
 * $Date: 2006/11/19 01:37:59 $
 * <br>
 * @author Craig Setera
 */
public abstract class AbstractIfDirective extends AbstractStartDirective {
	private static final String LINE_COMMENT = "//# ";

	protected class ConditionalBlock {
		private Directive[] directives;
		
		/**
		 * Construct a new instance.
		 * 
		 * @param directives
		 */
		public ConditionalBlock(Directive[] directives) {
			this.directives = directives;
		}

		/**
		 * Return the directives that are part of this block.
		 * 
		 * @return
		 */
		public Directive[] getDirectives() {
			return directives;
		}
		
		/**
		 * @return Returns the endDirective.
		 */
		public Directive getEndDirective() {
			return directives[directives.length - 1];
		}

		/**
		 * Return the region covered by this conditional block.
		 * 
		 * @return
		 * @throws CoreException
		 */
		public IRegion getRegion() 
			throws CoreException 
		{
			IRegion startRegion = getStartDirective().getRegion();
			IRegion endRegion = getEndDirective().getRegion();
			int length = 
				(endRegion.getOffset() - startRegion.getOffset()) + 
				endRegion.getLength(); 
			
			return new Region(startRegion.getOffset(), length);
		}
		
		/**
		 * @return Returns the startDirective.
		 */
		public Directive getStartDirective() {
			return directives[0];
		}

		/**
		 * Return a boolean indicating whether the specified block
		 * should be enabled.
		 * 
		 * @param identifiers
		 * @param monitor
		 * @return
		 */
		public boolean isEnabled(SymbolDefinitionSet identifiers, IProgressMonitor monitor) {
			AbstractConditionalDirective startDirective = 
				(AbstractConditionalDirective) getStartDirective();
			return startDirective.isEnabled(identifiers, monitor);
		}
	}

	private ConditionalBlock[] conditionalBlocks;

	
	/**
	 * Construct a new instance.
	 * 
	 * @param compilationUnit
	 * @param comment
	 * @param commentText
	 */
	public AbstractIfDirective(
		IResource resource,
		Comment comment, 
		String commentText) 
	{
		super(resource, comment, commentText);
	}

	/**
	 * @see eclipseme.core.internal.preprocessor.Directive#execute(ProcessingState, IProgressMonitor)
	 */
	public void execute(ProcessingState processingState, IProgressMonitor monitor) 
		throws CoreException 
	{
		if (isValid()) {
			ConditionalBlock[] blocks = getConditionalBlocks();
			int enabledBlock = findEnabledBlock(blocks, processingState.symbols, monitor);
			
			for (int i = 0; i < blocks.length; i++) {
				if (i == enabledBlock) {
					Directive[] children = blocks[i].getDirectives();
					for (int j = 1; j < children.length - 1; j++) {
						children[j].execute(processingState, monitor);
					}
				} else {
					disableBlock(processingState, blocks[i]);
				}
			}
		}
	}

	/**
	 * Disable the code in the document based on the
	 * conditional block.
	 * 
	 * @param processingState
	 * @param block
	 * @throws CoreException 
	 * @throws BadLocationException 
	 */
	protected void disableBlock(ProcessingState processingState, ConditionalBlock block) 
		throws CoreException 
	{
		IDocument document = processingState.document;
		IRegion blockRegion = block.getRegion();
		
		int startLine = getLineOfOffset(processingState, blockRegion.getOffset());
		int endLine = getLineOfOffset(
				processingState, 
				blockRegion.getOffset() + blockRegion.getLength());
		
		for (int line = startLine + 1; line < endLine; line++) {
			try {
				int lineOffset = document.getLineOffset(line);
				insertText(processingState, lineOffset, LINE_COMMENT);
			} catch (BadLocationException e) {
				EclipseMECorePlugin.throwCoreException(IStatus.ERROR, -999, e);
			}
		}
	}

	/**
	 * Find and return the first enabled block in the list of
	 * blocks.
	 * 
	 * @param blocks
	 * @param symbols
	 * @param monitor
	 * @return
	 */
	private int findEnabledBlock(
		ConditionalBlock[] blocks, 
		SymbolDefinitionSet symbols, 
		IProgressMonitor monitor) 
	{
		int blockIndex = -1;
		
		for (int i = 0; i < blocks.length; i++) {
			ConditionalBlock block = blocks[i];
			if (block.isEnabled(symbols, monitor)) {
				blockIndex = i;
				break;
			}
		}
		
		return blockIndex;
	}
	
	/**
	 * Return an array of conditional blocks.
	 * 
	 * @return
	 */
	protected ConditionalBlock[] getConditionalBlocks() {
		if (conditionalBlocks == null) {
			ArrayList blocks = new ArrayList();
			
			ArrayList blockDirectives = new ArrayList();
			blockDirectives.add(this);
			
			Iterator iterator = children.iterator();
			while (iterator.hasNext()) {
				Directive directive = (Directive) iterator.next();
				blockDirectives.add(directive);
				
				if (directive.isConditionalDirective()) {
					AbstractConditionalDirective conditional =
						(AbstractConditionalDirective) directive;
					
					if (conditional.isElseDirective() || conditional.isContainerEnd()) {
						ConditionalBlock block = new ConditionalBlock(
							(Directive[]) blockDirectives.toArray(new Directive[blockDirectives.size()]));
						blocks.add(block);
						
						blockDirectives.clear();
						blockDirectives.add(directive);
					}
				}
			}
			
			conditionalBlocks =
				(ConditionalBlock[]) blocks.toArray(new ConditionalBlock[blocks.size()]);
		}
		
		return conditionalBlocks;
	}
	
	/**
	 * Return a boolean indicating whether or not this directive is
	 * currently valid.
	 * 
	 * @return
	 * @throws CoreException
	 */
	protected abstract boolean isValid() throws CoreException;

	/**
	 * Validate the specific child directive.  Return a boolean indicating
	 * whether the directive is valid within this if directive and add
	 * a problem marker if it is not valid.
	 * 
	 * @param directive
	 * @return
	 * @throws CoreException
	 */
	protected abstract boolean validateChild(Directive directive) throws CoreException;
	
	/**
	 * Validate the children of this directive, returning a boolean
	 * indicating the validity.
	 * 
	 * @return
	 * @throws CoreException 
	 */
	protected boolean validateChildren() 
		throws CoreException 
	{
		boolean valid = true;
		
		Directive[] children = getChildren();
		for (int i = 0; i < children.length && valid; i++) {
			Directive directive = children[i];
			valid = validateChild(directive);
		}
		
		if (valid) {
			valid = validateClosed();
		}
		
		return valid;
	}

	/**
	 * Validate that the if directive is appropriately closed.
	 * 
	 * @return
	 * @throws CoreException 
	 */
	private boolean validateClosed() 
		throws CoreException 
	{
		boolean closed = false;

		Directive[] children = getChildren();
		if (children.length > 0) {
			Directive lastChild = children[children.length - 1];
			closed = lastChild.isConditionalDirective() && lastChild.isContainerEnd();
		}
		
		if (!closed) {
			createProblemMarker(IMarker.SEVERITY_ERROR, "Conditional directive not closed");
		}
		
		return closed;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -