KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > CompilationUnitProblemFinder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.core;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.OperationCanceledException;
18 import org.eclipse.jdt.core.*;
19 import org.eclipse.jdt.core.compiler.CategorizedProblem;
20 import org.eclipse.jdt.internal.compiler.*;
21 import org.eclipse.jdt.internal.compiler.Compiler;
22 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
23 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
24 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
25 import org.eclipse.jdt.internal.compiler.env.ISourceType;
26 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
27 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
28 import org.eclipse.jdt.internal.compiler.parser.Parser;
29 import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
30 import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
31 import org.eclipse.jdt.internal.core.util.Util;
32
33 /**
34  * Responsible for resolving types inside a compilation unit being reconciled,
35  * reporting the discovered problems to a given IProblemRequestor.
36  */

37 public class CompilationUnitProblemFinder extends Compiler JavaDoc {
38
39     /**
40      * Answer a new CompilationUnitVisitor using the given name environment and compiler options.
41      * The environment and options will be in effect for the lifetime of the compiler.
42      * When the compiler is run, compilation results are sent to the given requestor.
43      *
44      * @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
45      * Environment used by the compiler in order to resolve type and package
46      * names. The name environment implements the actual connection of the compiler
47      * to the outside world (e.g. in batch mode the name environment is performing
48      * pure file accesses, reuse previous build state or connection to repositories).
49      * Note: the name environment is responsible for implementing the actual classpath
50      * rules.
51      *
52      * @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
53      * Configurable part for problem handling, allowing the compiler client to
54      * specify the rules for handling problems (stop on first error or accumulate
55      * them all) and at the same time perform some actions such as opening a dialog
56      * in UI when compiling interactively.
57      * @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
58      *
59      * @param compilerOptions The compiler options to use for the resolution.
60      *
61      * @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
62      * Component which will receive and persist all compilation results and is intended
63      * to consume them as they are produced. Typically, in a batch compiler, it is
64      * responsible for writing out the actual .class files to the file system.
65      * @see org.eclipse.jdt.internal.compiler.CompilationResult
66      *
67      * @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
68      * Factory used inside the compiler to create problem descriptors. It allows the
69      * compiler client to supply its own representation of compilation problems in
70      * order to avoid object conversions. Note that the factory is not supposed
71      * to accumulate the created problems, the compiler will gather them all and hand
72      * them back as part of the compilation unit result.
73      */

74     protected CompilationUnitProblemFinder(
75         INameEnvironment environment,
76         IErrorHandlingPolicy policy,
77         CompilerOptions compilerOptions,
78         ICompilerRequestor requestor,
79         IProblemFactory problemFactory) {
80
81         super(environment,
82             policy,
83             compilerOptions,
84             requestor,
85             problemFactory
86         );
87     }
88
89     /**
90      * Add additional source types
91      */

92     public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
93         // ensure to jump back to toplevel type for first one (could be a member)
94
// while (sourceTypes[0].getEnclosingType() != null)
95
// sourceTypes[0] = sourceTypes[0].getEnclosingType();
96

97         CompilationResult result =
98             new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit);
99
100         // need to hold onto this
101
CompilationUnitDeclaration unit =
102             SourceTypeConverter.buildCompilationUnit(
103                 sourceTypes,//sourceTypes[0] is always toplevel here
104
SourceTypeConverter.FIELD_AND_METHOD // need field and methods
105
| SourceTypeConverter.MEMBER_TYPE // need member types
106
| SourceTypeConverter.FIELD_INITIALIZATION, // need field initialization
107
this.lookupEnvironment.problemReporter,
108                 result);
109
110         if (unit != null) {
111             this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
112             this.lookupEnvironment.completeTypeBindings(unit);
113         }
114     }
115
116     protected static CompilerOptions getCompilerOptions(Map JavaDoc settings, boolean creatingAST, boolean statementsRecovery) {
117         CompilerOptions compilerOptions = new CompilerOptions(settings);
118         compilerOptions.performMethodsFullRecovery = statementsRecovery;
119         compilerOptions.performStatementsRecovery = statementsRecovery;
120         compilerOptions.parseLiteralExpressionsAsConstants = !creatingAST; /*parse literal expressions as constants only if not creating a DOM AST*/
121         compilerOptions.storeAnnotations = creatingAST; /*store annotations in the bindings if creating a DOM AST*/
122         return compilerOptions;
123     }
124     
125     /*
126      * Low-level API performing the actual compilation
127      */

128     protected static IErrorHandlingPolicy getHandlingPolicy() {
129         return DefaultErrorHandlingPolicies.proceedWithAllProblems();
130     }
131
132     /*
133      * Answer the component to which will be handed back compilation results from the compiler
134      */

135     protected static ICompilerRequestor getRequestor() {
136         return new ICompilerRequestor() {
137             public void acceptResult(CompilationResult compilationResult) {
138                 // default requestor doesn't handle compilation results back
139
}
140         };
141     }
142
143     public static CompilationUnitDeclaration process(
144         CompilationUnitDeclaration unit,
145         ICompilationUnit unitElement,
146         char[] contents,
147         Parser parser,
148         WorkingCopyOwner workingCopyOwner,
149         HashMap JavaDoc problems,
150         boolean creatingAST,
151         int reconcileFlags,
152         IProgressMonitor monitor)
153         throws JavaModelException {
154
155         JavaProject project = (JavaProject) unitElement.getJavaProject();
156         CancelableNameEnvironment environment = null;
157         CancelableProblemFactory problemFactory = null;
158         CompilationUnitProblemFinder problemFinder = null;
159         try {
160             environment = new CancelableNameEnvironment(project, workingCopyOwner, monitor);
161             problemFactory = new CancelableProblemFactory(monitor);
162             problemFinder = new CompilationUnitProblemFinder(
163                 environment,
164                 getHandlingPolicy(),
165                 getCompilerOptions(project.getOptions(true), creatingAST, ((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0)),
166                 getRequestor(),
167                 problemFactory);
168             if (parser != null) {
169                 problemFinder.parser = parser;
170             }
171             PackageFragment packageFragment = (PackageFragment)unitElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
172             char[][] expectedPackageName = null;
173             if (packageFragment != null){
174                 expectedPackageName = Util.toCharArrays(packageFragment.names);
175             }
176             if (unit == null) {
177                 unit = problemFinder.resolve(
178                     new BasicCompilationUnit(
179                         contents,
180                         expectedPackageName,
181                         unitElement.getPath().toString(),
182                         unitElement),
183                     true, // verify methods
184
true, // analyze code
185
true); // generate code
186
} else {
187                 problemFinder.resolve(
188                     unit,
189                     null, // no need for source
190
true, // verify methods
191
true, // analyze code
192
true); // generate code
193
}
194             CompilationResult unitResult = unit.compilationResult;
195             CategorizedProblem[] unitProblems = unitResult.getProblems();
196             int length = unitProblems == null ? 0 : unitProblems.length;
197             if (length > 0) {
198                 CategorizedProblem[] categorizedProblems = new CategorizedProblem[length];
199                 System.arraycopy(unitProblems, 0, categorizedProblems, 0, length);
200                 problems.put(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, categorizedProblems);
201             }
202             unitProblems = unitResult.getTasks();
203             length = unitProblems == null ? 0 : unitProblems.length;
204             if (length > 0) {
205                 CategorizedProblem[] categorizedProblems = new CategorizedProblem[length];
206                 System.arraycopy(unitProblems, 0, categorizedProblems, 0, length);
207                 problems.put(IJavaModelMarker.TASK_MARKER, categorizedProblems);
208             }
209             if (NameLookup.VERBOSE) {
210                 System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
211
System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
212
}
213             return unit;
214         } catch (OperationCanceledException e) {
215             throw e;
216         } catch(RuntimeException JavaDoc e) {
217             // avoid breaking other tools due to internal compiler failure (40334)
218
String JavaDoc lineDelimiter = unitElement.findRecommendedLineSeparator();
219             StringBuffer JavaDoc message = new StringBuffer JavaDoc("Exception occurred during problem detection:"); //$NON-NLS-1$
220
message.append(lineDelimiter);
221             message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$
222
message.append(lineDelimiter);
223             message.append(contents);
224             message.append(lineDelimiter);
225             message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$
226
Util.log(e, message.toString());
227             throw new JavaModelException(e, IJavaModelStatusConstants.COMPILER_FAILURE);
228         } finally {
229             if (environment != null)
230                 environment.monitor = null; // don't hold a reference to this external object
231
if (problemFactory != null)
232                 problemFactory.monitor = null; // don't hold a reference to this external object
233
// NB: unit.cleanUp() is done by caller
234
if (problemFinder != null && !creatingAST)
235                 problemFinder.lookupEnvironment.reset();
236         }
237     }
238
239     public static CompilationUnitDeclaration process(
240         ICompilationUnit unitElement,
241         char[] contents,
242         WorkingCopyOwner workingCopyOwner,
243         HashMap JavaDoc problems,
244         boolean creatingAST,
245         int reconcileFlags,
246         IProgressMonitor monitor)
247         throws JavaModelException {
248             
249         return process(null/*no CompilationUnitDeclaration*/, unitElement, contents, null/*use default Parser*/, workingCopyOwner, problems, creatingAST, reconcileFlags, monitor);
250     }
251
252     /* (non-Javadoc)
253      * Fix for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=60689.
254      * @see org.eclipse.jdt.internal.compiler.Compiler#initializeParser()
255      */

256     public void initializeParser() {
257         this.parser = new CommentRecorderParser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants);
258     }
259 }
260
261
Popular Tags