Refactory: remove unused classes, imports, fields and methods.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / CompilationUnitProblemFinder.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12
13 import java.util.Locale;
14 import java.util.Map;
15
16 import net.sourceforge.phpdt.core.ICompilationUnit;
17 import net.sourceforge.phpdt.core.IJavaElement;
18 import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
19 import net.sourceforge.phpdt.core.IJavaProject;
20 import net.sourceforge.phpdt.core.IPackageFragment;
21 import net.sourceforge.phpdt.core.IProblemRequestor;
22 import net.sourceforge.phpdt.core.JavaCore;
23 import net.sourceforge.phpdt.core.JavaModelException;
24 import net.sourceforge.phpdt.core.WorkingCopyOwner;
25 import net.sourceforge.phpdt.core.compiler.CharOperation;
26 import net.sourceforge.phpdt.core.compiler.IProblem;
27 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
28 import net.sourceforge.phpdt.internal.compiler.Compiler;
29 import net.sourceforge.phpdt.internal.compiler.DefaultErrorHandlingPolicies;
30 import net.sourceforge.phpdt.internal.compiler.ICompilerRequestor;
31 import net.sourceforge.phpdt.internal.compiler.IErrorHandlingPolicy;
32 import net.sourceforge.phpdt.internal.compiler.IProblemFactory;
33 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
34 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
35 import net.sourceforge.phpdt.internal.compiler.env.ISourceType;
36 import net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding;
37 import net.sourceforge.phpdt.internal.compiler.parser.SourceTypeConverter;
38 import net.sourceforge.phpdt.internal.compiler.parser.UnitParser;
39 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
40 import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
41 import net.sourceforge.phpdt.internal.core.util.Util;
42
43 import org.eclipse.core.runtime.IProgressMonitor;
44
45 /**
46  * Responsible for resolving types inside a compilation unit being reconciled,
47  * reporting the discovered problems to a given IProblemRequestor.
48  */
49 public class CompilationUnitProblemFinder extends Compiler {
50
51         /**
52          * Answer a new CompilationUnitVisitor using the given name environment and
53          * compiler options. The environment and options will be in effect for the
54          * lifetime of the compiler. When the compiler is run, compilation results
55          * are sent to the given requestor.
56          * 
57          * @param environment
58          *            org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
59          *            Environment used by the compiler in order to resolve type and
60          *            package names. The name environment implements the actual
61          *            connection of the compiler to the outside world (e.g. in batch
62          *            mode the name environment is performing pure file accesses,
63          *            reuse previous build state or connection to repositories).
64          *            Note: the name environment is responsible for implementing the
65          *            actual classpath rules.
66          * 
67          * @param policy
68          *            org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
69          *            Configurable part for problem handling, allowing the compiler
70          *            client to specify the rules for handling problems (stop on
71          *            first error or accumulate them all) and at the same time
72          *            perform some actions such as opening a dialog in UI when
73          *            compiling interactively.
74          * @see org.eclipse.jdt.internal.compiler.api.problem.DefaultErrorHandlingPolicies
75          * 
76          * @param settings
77          *            The settings to use for the resolution.
78          * 
79          * @param requestor
80          *            org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
81          *            Component which will receive and persist all compilation
82          *            results and is intended to consume them as they are produced.
83          *            Typically, in a batch compiler, it is responsible for writing
84          *            out the actual .class files to the file system.
85          * @see org.eclipse.jdt.internal.compiler.api.CompilationResult
86          * 
87          * @param problemFactory
88          *            org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
89          *            Factory used inside the compiler to create problem
90          *            descriptors. It allows the compiler client to supply its own
91          *            representation of compilation problems in order to avoid
92          *            object conversions. Note that the factory is not supposed to
93          *            accumulate the created problems, the compiler will gather them
94          *            all and hand them back as part of the compilation unit result.
95          */
96         protected CompilationUnitProblemFinder(INameEnvironment environment,
97                         IErrorHandlingPolicy policy, Map settings,
98                         ICompilerRequestor requestor, IProblemFactory problemFactory) {
99
100                 super(environment, policy, settings, requestor, problemFactory, true);
101         }
102
103         /**
104          * Add additional source types
105          */
106         public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) {
107                 // ensure to jump back to toplevel type for first one (could be a
108                 // member)
109                 // while (sourceTypes[0].getEnclosingType() != null)
110                 // sourceTypes[0] = sourceTypes[0].getEnclosingType();
111
112                 CompilationResult result = new CompilationResult(sourceTypes[0]
113                                 .getFileName(), 1, 1, 10); // this.options.maxProblemsPerUnit);
114
115                 // need to hold onto this
116                 CompilationUnitDeclaration unit = SourceTypeConverter
117                                 .buildCompilationUnit(sourceTypes,// sourceTypes[0] is always
118                                                                                                         // toplevel here
119                                                 true, // need field and methods
120                                                 true, // need member types
121                                                 true, // need field initialization
122                                                 lookupEnvironment.problemReporter, result);
123
124                 if (unit != null) {
125                         this.lookupEnvironment.buildTypeBindings(unit);
126                         this.lookupEnvironment.completeTypeBindings(unit, true);
127                 }
128         }
129
130         /*
131          * Low-level API performing the actual compilation
132          */
133         protected static IErrorHandlingPolicy getHandlingPolicy() {
134                 return DefaultErrorHandlingPolicies.proceedWithAllProblems();
135         }
136
137         protected static INameEnvironment getNameEnvironment(
138                         ICompilationUnit sourceUnit) throws JavaModelException {
139                 return (SearchableEnvironment) ((JavaProject) sourceUnit
140                                 .getJavaProject()).getSearchableNameEnvironment();
141         }
142
143         /*
144          * Answer the component to which will be handed back compilation results
145          * from the compiler
146          */
147         protected static ICompilerRequestor getRequestor() {
148                 return new ICompilerRequestor() {
149                         public void acceptResult(CompilationResult compilationResult) {
150                         }
151                 };
152         }
153
154         protected static IProblemFactory getProblemFactory(final char[] fileName,
155                         final IProblemRequestor problemRequestor,
156                         final IProgressMonitor monitor) {
157
158                 return new DefaultProblemFactory(Locale.getDefault()) {
159                         public IProblem createProblem(char[] originatingFileName,
160                                         int problemId, String[] problemArguments,
161                                         String[] messageArguments, int severity, int startPosition,
162                                         int endPosition, int lineNumber) {
163
164                                 if (monitor != null && monitor.isCanceled()) {
165                                         throw new AbortCompilation(true, null); // silent abort
166                                 }
167
168                                 IProblem problem = super.createProblem(originatingFileName,
169                                                 problemId, problemArguments, messageArguments,
170                                                 severity, startPosition, endPosition, lineNumber);
171                                 // only report local problems
172                                 if (CharOperation.equals(originatingFileName, fileName)) {
173                                         if (JavaModelManager.VERBOSE) {
174                                                 System.out
175                                                                 .println("PROBLEM FOUND while reconciling : " + problem.getMessage());//$NON-NLS-1$
176                                         }
177                                         problemRequestor.acceptProblem(problem);
178                                 }
179                                 if (monitor != null && monitor.isCanceled()) {
180                                         throw new AbortCompilation(true, null); // silent abort
181                                 }
182
183                                 return problem;
184                         }
185                 };
186         }
187
188         public static CompilationUnitDeclaration process(
189                         CompilationUnitDeclaration unit, ICompilationUnit unitElement,
190                         char[] contents, UnitParser parser,
191                         WorkingCopyOwner workingCopyOwner,
192                         IProblemRequestor problemRequestor, IProblemFactory problemFactory,
193                         boolean cleanupCU, IProgressMonitor monitor)
194                         throws JavaModelException {
195
196                 char[] fileName = unitElement.getElementName().toCharArray();
197
198                 JavaProject project = (JavaProject) unitElement.getJavaProject();
199                 CompilationUnitProblemFinder problemFinder = new CompilationUnitProblemFinder(
200                                 project.newSearchableNameEnvironment(workingCopyOwner),
201                                 getHandlingPolicy(), project.getOptions(true), getRequestor(),
202                                 problemFactory);
203                 if (parser != null) {
204                         problemFinder.parser = parser;
205                 }
206
207                 try {
208
209                         IPackageFragment packageFragment = (IPackageFragment) unitElement
210                                         .getAncestor(IJavaElement.PACKAGE_FRAGMENT);
211                         char[][] expectedPackageName = null;
212                         if (packageFragment != null) {
213                                 expectedPackageName = CharOperation.splitOn('.',
214                                                 packageFragment.getElementName().toCharArray());
215                         }
216                         if (unit == null) {
217                                 unit = problemFinder.resolve(
218                                                 new BasicCompilationUnit(contents, expectedPackageName,
219                                                                 new String(fileName), unitElement), true, // verify
220                                                                                                                                                         // methods
221                                                 true); // , // analyze code
222                                 // true); // generate code
223                         } else {
224                                 problemFinder.resolve(unit, null, // no need for source
225                                                 true, // verify methods
226                                                 true); // , // analyze code
227                                 // true); // generate code
228                         }
229                         reportProblems(unit, problemRequestor, monitor);
230                         return unit;
231                 } catch (RuntimeException e) {
232                         // avoid breaking other tools due to internal compiler failure
233                         // (40334)
234                         Util.log(e, "Exception occurred during problem detection: "); //$NON-NLS-1$ 
235                         throw new JavaModelException(e,
236                                         IJavaModelStatusConstants.COMPILER_FAILURE);
237                 } finally {
238                         if (cleanupCU && unit != null) {
239                                 unit.cleanUp();
240                         }
241                         problemFinder.lookupEnvironment.reset();
242                 }
243         }
244
245         public static CompilationUnitDeclaration process(
246                         ICompilationUnit unitElement, char[] contents,
247                         WorkingCopyOwner workingCopyOwner,
248                         IProblemRequestor problemRequestor, boolean cleanupCU,
249                         IProgressMonitor monitor) throws JavaModelException {
250
251                 return process(null/* no CompilationUnitDeclaration */, unitElement,
252                                 contents, null/* use default Parser */, workingCopyOwner,
253                                 problemRequestor, new DefaultProblemFactory(), cleanupCU,
254                                 monitor);
255         }
256
257         public static CompilationUnitDeclaration process(
258                         ICompilationUnit unitElement, IProblemRequestor problemRequestor,
259                         IProgressMonitor monitor) throws JavaModelException {
260
261                 char[] fileName = unitElement.getElementName().toCharArray();
262
263                 IJavaProject project = unitElement.getJavaProject();
264                 CompilationUnitProblemFinder problemFinder = new CompilationUnitProblemFinder(
265                                 getNameEnvironment(unitElement), getHandlingPolicy(), project
266                                                 .getOptions(true), getRequestor(), getProblemFactory(
267                                                 fileName, problemRequestor, monitor));
268
269                 CompilationUnitDeclaration unit = null;
270                 try {
271                         String encoding = project.getOption(JavaCore.CORE_ENCODING, true);
272
273                         IPackageFragment packageFragment = (IPackageFragment) unitElement
274                                         .getAncestor(IJavaElement.PACKAGE_FRAGMENT);
275                         char[][] expectedPackageName = null;
276                         if (packageFragment != null) {
277                                 expectedPackageName = CharOperation.splitOn('.',
278                                                 packageFragment.getElementName().toCharArray());
279                         }
280                         unit = problemFinder.resolve(new BasicCompilationUnit(unitElement
281                                         .getSource().toCharArray(), expectedPackageName,
282                                         new String(fileName), encoding), true, // verify methods
283                                         true); // analyze code
284                         // true); // generate code
285                         return unit;
286                 } finally {
287                         if (unit != null) {
288                                 unit.cleanUp();
289                         }
290                         problemFinder.lookupEnvironment.reset();
291                 }
292         }
293
294         private static void reportProblems(CompilationUnitDeclaration unit,
295                         IProblemRequestor problemRequestor, IProgressMonitor monitor) {
296                 CompilationResult unitResult = unit.compilationResult;
297                 IProblem[] problems = unitResult.getAllProblems();
298                 for (int i = 0, problemLength = problems == null ? 0 : problems.length; i < problemLength; i++) {
299                         if (JavaModelManager.VERBOSE) {
300                                 System.out
301                                                 .println("PROBLEM FOUND while reconciling : " + problems[i].getMessage());//$NON-NLS-1$
302                         }
303                         if (monitor != null && monitor.isCanceled())
304                                 break;
305
306                         problemRequestor.acceptProblem(problems[i]);
307                 }
308         }
309 }