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

📄 preprocessor.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;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Stack;

import org.eclipse.core.resources.IFile;
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.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;

import eclipseme.core.hook.sourceMapper.SourceMapperAccess;
import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.preprocessor.directive.CompilationUnitRootDirective;
import eclipseme.core.model.SymbolDefinitionSet;

/**
 * A preprocessor for preprocessing java files similar to the
 * Antenna preprocessor.
 * <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.5 $
 * <br>
 * $Date: 2006/11/12 01:11:00 $
 * <br>
 * @author Craig Setera
 */
public class Preprocessor {
	/** A preprocessor problem marker */
	public static final String PROBLEM_MARKER = "eclipseme.core.preprocessor.problemmarker";
	
	/**
	 * Create a new preprocessor.
	 */
	public Preprocessor() {
		super();
	}

	/**
	 * Preprocess the specified resource given the specified symbol
	 * definitions.
	 * 
	 * @param resource
	 * @param symbols
	 * @param monitor
	 * @return
	 * @throws CoreException
	 */
	public IDocument preprocess(
		IResource resource, 
		SymbolDefinitionSet symbols, 
		IProgressMonitor monitor) 
			throws CoreException 
	{
		IDocument document = getDocumentForFile((IFile) resource);
		preprocess(resource, document, symbols, monitor);
		return document;
	}

	/**
	 * Execute the preprocess functionality on the specified document
	 * for the specified resource.  When the method returns, the document
	 * will be updated to represent the current status of the specified
	 * symbol definitions.
	 * 
	 * @param resource
	 * @param document
	 * @param symbols
	 * @param monitor
	 * @throws CoreException
	 */
	public void preprocess(
		IResource resource,
		IDocument document, 
		SymbolDefinitionSet symbols, 
		IProgressMonitor monitor) 
			throws CoreException 
	{
		// Clear previous error and warning markers from the source file
		clearPreprocessorMarkers(resource);
		
		// Preprocess into a source document
		processSource(resource, document, symbols, monitor);
	}

	/**
	 * Clear previous preprocessor markers from the specified resource.
	 * 
	 * @param resource 
	 * @throws CoreException
	 */
	private void clearPreprocessorMarkers(IResource resource)
		throws CoreException 
	{
		IMarker[] markers = resource.findMarkers(PROBLEM_MARKER, true, IResource.DEPTH_ONE);
		for (int i = 0; i < markers.length; i++) {
			markers[i].delete();
		}
	}

	/**
	 * Collect the directives in the compilation unit.
	 * 
	 * @param astCompilationUnit
	 * @throws CoreException
	 */
	private CompilationUnitRootDirective collectDirectives(
		IResource resource,
		IDocument document,
		CompilationUnit astCompilationUnit) 
			throws CoreException 
	{
		CompilationUnitRootDirective root = 
			new CompilationUnitRootDirective(resource, null, null);
		Stack containerStack = new Stack();
		containerStack.add(root);
		
		Iterator comments = astCompilationUnit.getCommentList().iterator();
		while (comments.hasNext()) {
			Comment comment = (Comment) comments.next();
			if (comment.getNodeType() == ASTNode.LINE_COMMENT) {
				Directive directive = 
					DirectiveFactory.getDirective(resource, document, comment);
				
				if (directive != null) {
					handleDirective(containerStack, directive);
				}
			}
		}
		
		return root;
	}

	/**
	 * Return the current block as defined by the stack.
	 * 
	 * @param containerStack
	 * @return
	 */
	private IDirectiveContainer getCurrentContainer(Stack containerStack) {
		return (IDirectiveContainer) containerStack.peek();
	}

	/**
	 * Return a document instance based on the contents of the
	 * specified file.
	 * 
	 * @param file
	 * @return
	 * @throws CoreException
	 * @throws IOException
	 */
	private IDocument getDocumentForFile(IFile file) 
		throws CoreException 
	{
		String charset = file.getCharset(true);
		InputStream contentStream = file.getContents();
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(contentStream, charset));
		} catch (UnsupportedEncodingException e) {
			// Should not happen
		}
		
		String line = null;
		StringWriter stringWriter = new StringWriter();
		PrintWriter writer = new PrintWriter(stringWriter);
		
		try {
			while ((line = reader.readLine()) != null) {
				writer.println(line);
			}
		} catch (IOException e) {
			EclipseMECorePlugin.throwCoreException(IStatus.ERROR, -999, e);
		} finally {
			try { reader.close(); } catch (IOException e) { /* Munch */ }
		}
		
		return new Document(stringWriter.toString());
	}

	/**
	 * Process the specified source document given the specified symbol
	 * definitions
	 * 
	 * @param document 
	 * @param resource 
	 * @param symbols
	 * @param monitor
	 * @return
	 * @throws CoreException
	 */
	private void processSource(
		IResource resource, 
		IDocument document, 
		SymbolDefinitionSet symbols, 
		IProgressMonitor monitor) 
			throws CoreException 
	{
		ProcessingState state = new ProcessingState(document, symbols);
		
		ASTParser parser = ASTParser.newParser(AST.JLS3);
		parser.setSource(document.get().toCharArray());
		
		CompilationUnit astCompilationUnit = (CompilationUnit) parser.createAST(monitor);
		CompilationUnitRootDirective rootDirective = 
			collectDirectives(resource, document, astCompilationUnit);
		
		// Log an error if there are actually preprocessing directives
		// in this file, but the hook has not been installed
		if (rootDirective.hasChildren() && !SourceMapperAccess.isHookCodeInstalled()) {
			IMarker marker = resource.createMarker(PROBLEM_MARKER);
			marker.setAttribute(
				IMarker.MESSAGE, 
				"Preprocessor invoked, but hook is not installed.  Consult the installation instructions for EclipseME.");
			marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
		}
		
		rootDirective.execute(state, monitor);
	}

	/**
	 * Handle the specified directive.
	 * 
	 * @param containerStack
	 * @param directive
	 */
	private void handleDirective(Stack containerStack, Directive directive) {
		IDirectiveContainer block = getCurrentContainer(containerStack);
		block.addChild(directive);

		if (directive.isContainerStart()) {
			containerStack.push(directive);
		} else if (directive.isContainerEnd()) {
			containerStack.pop();
		}
	}
}

⌨️ 快捷键说明

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