| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.core; |
| |
| import java.util.Locale; |
| import java.util.Map; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.compiler.IProblem; |
| import org.eclipse.jdt.internal.compiler.CompilationResult; |
| import org.eclipse.jdt.internal.compiler.Compiler; |
| import org.eclipse.jdt.internal.compiler.ASTVisitor; |
| import org.eclipse.jdt.internal.compiler.ICompilerRequestor; |
| import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; |
| import org.eclipse.jdt.internal.compiler.IProblemFactory; |
| import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; |
| import org.eclipse.jdt.internal.compiler.env.AccessRestriction; |
| import org.eclipse.jdt.internal.compiler.env.INameEnvironment; |
| import org.eclipse.jdt.internal.compiler.env.ISourceType; |
| import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; |
| import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.jdt.internal.core.util.Util; |
| |
| public class CompilationUnitVisitor extends Compiler { |
| |
| /** |
| * Answer a new CompilationUnitVisitor using the given name environment and compiler options. |
| * The environment and options will be in effect for the lifetime of the compiler. |
| * When the compiler is run, compilation results are sent to the given requestor. |
| * |
| * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment |
| * Environment used by the compiler in order to resolve type and package |
| * names. The name environment implements the actual connection of the compiler |
| * to the outside world (e.g. in batch mode the name environment is performing |
| * pure file accesses, reuse previous build state or connection to repositories). |
| * Note: the name environment is responsible for implementing the actual classpath |
| * rules. |
| * |
| * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy |
| * Configurable part for problem handling, allowing the compiler client to |
| * specify the rules for handling problems (stop on first error or accumulate |
| * them all) and at the same time perform some actions such as opening a dialog |
| * in UI when compiling interactively. |
| * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies |
| * |
| * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor |
| * Component which will receive and persist all compilation results and is intended |
| * to consume them as they are produced. Typically, in a batch compiler, it is |
| * responsible for writing out the actual .class files to the file system. |
| * @see org.eclipse.jdt.internal.compiler.CompilationResult |
| * |
| * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory |
| * Factory used inside the compiler to create problem descriptors. It allows the |
| * compiler client to supply its own representation of compilation problems in |
| * order to avoid object conversions. Note that the factory is not supposed |
| * to accumulate the created problems, the compiler will gather them all and hand |
| * them back as part of the compilation unit result. |
| */ |
| public CompilationUnitVisitor( |
| INameEnvironment environment, |
| IErrorHandlingPolicy policy, |
| Map settings, |
| ICompilerRequestor requestor, |
| IProblemFactory problemFactory) { |
| |
| super(environment, policy, settings, requestor, problemFactory); |
| } |
| |
| /** |
| * Add additional source types |
| */ |
| public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) { |
| CompilationResult result = |
| new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit); |
| // need to hold onto this |
| CompilationUnitDeclaration unit = |
| SourceTypeConverter.buildCompilationUnit( |
| sourceTypes,//sourceTypes[0] is always toplevel here |
| SourceTypeConverter.FIELD_AND_METHOD // need field and methods |
| | SourceTypeConverter.MEMBER_TYPE, // need member types |
| // no need for field initialization |
| this.lookupEnvironment.problemReporter, |
| result); |
| |
| if (unit != null) { |
| this.lookupEnvironment.buildTypeBindings(unit, accessRestriction); |
| this.lookupEnvironment.completeTypeBindings(unit, true); |
| } |
| } |
| |
| /* |
| * Low-level API performing the actual compilation |
| */ |
| protected static IErrorHandlingPolicy getHandlingPolicy() { |
| |
| // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match) |
| return new IErrorHandlingPolicy() { |
| public boolean stopOnFirstError() { |
| return false; |
| } |
| public boolean proceedOnErrors() { |
| return false; // stop if there are some errors |
| } |
| }; |
| } |
| |
| /* |
| * Answer the component to which will be handed back compilation results from the compiler |
| */ |
| protected static ICompilerRequestor getRequestor() { |
| return new ICompilerRequestor() { |
| public void acceptResult(CompilationResult compilationResult) { |
| // nothing to do |
| } |
| }; |
| } |
| |
| public static void visit( |
| ICompilationUnit unitElement, |
| ASTVisitor visitor) |
| throws JavaModelException { |
| |
| JavaProject project = (JavaProject) unitElement.getJavaProject(); |
| CompilationUnitVisitor compilationUnitVisitor = |
| new CompilationUnitVisitor( |
| project.newSearchableNameEnvironment(unitElement.getOwner()), |
| getHandlingPolicy(), |
| project.getOptions(true), |
| getRequestor(), |
| getProblemFactory(visitor)); |
| |
| CompilationUnitDeclaration unit = null; |
| try { |
| |
| PackageFragment packageFragment = (PackageFragment)unitElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT); |
| char[][] expectedPackageName = null; |
| if (packageFragment != null){ |
| expectedPackageName = Util.toCharArrays(packageFragment.names); |
| } |
| unit = |
| compilationUnitVisitor.resolve( |
| new BasicCompilationUnit( |
| unitElement.getSource().toCharArray(), |
| expectedPackageName, |
| unitElement.getElementName(), |
| unitElement), |
| true, // method verification |
| false, // no flow analysis |
| false); // no code generation |
| if (unit != null) { |
| unit.traverse(visitor, unit.scope); |
| } |
| } finally { |
| if (unit != null) { |
| unit.cleanUp(); |
| } |
| } |
| } |
| |
| protected static IProblemFactory getProblemFactory(final ASTVisitor visitor) { |
| |
| return new DefaultProblemFactory(Locale.getDefault()) { |
| public IProblem createProblem( |
| char[] originatingFileName, |
| int problemId, |
| String[] problemArguments, |
| String[] messageArguments, |
| int severity, |
| int startPosition, |
| int endPosition, |
| int lineNumber) { |
| |
| IProblem problem = |
| super.createProblem( |
| originatingFileName, |
| problemId, |
| problemArguments, |
| messageArguments, |
| severity, |
| startPosition, |
| endPosition, |
| lineNumber); |
| visitor.acceptProblem(problem); |
| return problem; |
| } |
| }; |
| } |
| } |