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