1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler;
14 * A compilation result consists of all information returned by the compiler for
15 * a single compiled compilation source unit. This includes:
17 * <li> the compilation unit that was compiled
18 * <li> for each type produced by compiling the compilation unit, its binary and optionally its principal structure
19 * <li> any problems (errors or warnings) produced
20 * <li> dependency info
23 * The principle structure and binary may be null if the compiler could not produce them.
24 * If neither could be produced, there is no corresponding entry for the type.
26 * The dependency info includes type references such as supertypes, field types, method
27 * parameter and return types, local variable types, types of intermediate expressions, etc.
28 * It also includes the namespaces (packages) in which names were looked up.
29 * It does <em>not</em> include finer grained dependencies such as information about
30 * specific fields and methods which were referenced, but does contain their
31 * declaring types and any other types used to locate such fields or methods.
34 import net.sourceforge.phpdt.core.compiler.*;
35 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
36 import net.sourceforge.phpdt.internal.compiler.env.*;
37 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
41 public class CompilationResult {
43 public IProblem problems[];
44 public int problemCount;
45 public ICompilationUnit compilationUnit;
46 private Map problemsMap;
47 private Map firstErrorsMap;
48 private HashSet duplicateProblems;
49 private int maxProblemPerUnit;
50 public char[][][] qualifiedReferences;
51 public char[][] simpleNameReferences;
53 public int lineSeparatorPositions[];
54 public Hashtable compiledTypes = new Hashtable(11);
55 public int unitIndex, totalUnitsKnown;
56 public boolean hasBeenAccepted = false;
57 public char[] fileName;
59 public CompilationResult(
63 int maxProblemPerUnit){
65 this.fileName = fileName;
66 this.unitIndex = unitIndex;
67 this.totalUnitsKnown = totalUnitsKnown;
68 this.maxProblemPerUnit = maxProblemPerUnit;
72 public CompilationResult(
73 ICompilationUnit compilationUnit,
76 int maxProblemPerUnit){
78 this.fileName = compilationUnit.getFileName();
79 this.compilationUnit = compilationUnit;
80 this.unitIndex = unitIndex;
81 this.totalUnitsKnown = totalUnitsKnown;
82 this.maxProblemPerUnit = maxProblemPerUnit;
85 private int computePriority(IProblem problem){
87 final int P_STATIC = 1000;
88 final int P_OUTSIDE_METHOD = 4000;
89 final int P_FIRST_ERROR = 2000;
90 final int P_ERROR = 10000;
92 int priority = 1000 - problem.getSourceLineNumber(); // early problems first
93 if (priority < 0) priority = 0;
94 if (problem.isError()){
97 ReferenceContext context = problemsMap == null ? null : (ReferenceContext) problemsMap.get(problem);
99 if (context instanceof AbstractMethodDeclaration){
100 AbstractMethodDeclaration method = (AbstractMethodDeclaration) context;
101 if (method.isStatic()) {
102 priority += P_STATIC;
105 priority += P_OUTSIDE_METHOD;
108 priority += P_OUTSIDE_METHOD;
110 if (firstErrorsMap.containsKey(problem)){
111 priority += P_FIRST_ERROR;
115 public ClassFile[] getClassFiles() {
116 Enumeration enum = compiledTypes.elements();
117 ClassFile[] classFiles = new ClassFile[compiledTypes.size()];
119 while (enum.hasMoreElements()){
120 classFiles[index++] = (ClassFile)enum.nextElement();
125 * Answer the initial compilation unit corresponding to the present compilation result
127 public ICompilationUnit getCompilationUnit(){
128 return compilationUnit;
131 * Answer the initial file name
133 public char[] getFileName(){
137 * Answer the problems (errors and warnings) encountered during compilation.
139 * This is not a compiler internal API - it has side-effects !
140 * It is intended to be used only once all problems have been detected,
141 * and makes sure the problems slot as the exact size of the number of
144 public IProblem[] getProblems() {
146 // Re-adjust the size of the problems if necessary.
147 if (problems != null) {
149 if (this.problemCount != problems.length) {
150 System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount);
153 if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
154 quickPrioritize(problems, 0, problemCount - 1);
155 this.problemCount = this.maxProblemPerUnit;
156 System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount);
159 // Sort problems per source positions.
160 quicksort(problems, 0, problems.length-1);
165 public boolean hasErrors() {
166 if (problems != null)
167 for (int i = 0; i < problemCount; i++) {
168 if (problems[i].isError())
173 public boolean hasProblems() {
174 return problemCount != 0;
176 public boolean hasWarnings() {
177 if (problems != null)
178 for (int i = 0; i < problemCount; i++) {
179 if (problems[i].isWarning())
185 private static void quicksort(IProblem arr[], int left, int right) {
189 /* do nothing if array contains fewer than two */
194 swap(arr, left, (left + right) / 2);
196 pos = arr[left].getSourceStart();
198 for (i = left + 1; i <= right; i++) {
199 if (arr[i].getSourceStart() < pos) {
200 swap(arr, ++last, i);
204 swap(arr, left, last);
205 quicksort(arr, left, last - 1);
206 quicksort(arr, last + 1, right);
209 private void quickPrioritize(IProblem arr[], int left, int right) {
213 /* do nothing if array contains fewer than two */
218 swap(arr, left, (left + right) / 2);
220 prio = computePriority(arr[left]);
222 for (i = left + 1; i <= right; i++) {
223 if (computePriority(arr[i]) > prio) {
224 swap(arr, ++last, i);
228 swap(arr, left, last);
229 quickPrioritize(arr, left, last - 1);
230 quickPrioritize(arr, last + 1, right);
234 * For now, remember the compiled type using its compound name.
236 public void record(char[] typeName, ClassFile classFile) {
237 compiledTypes.put(typeName, classFile);
239 public void record(IProblem newProblem, ReferenceContext referenceContext) {
240 if (problemCount == 0) {
241 problems = new IProblem[5];
243 if (problemCount == problems.length)
244 System.arraycopy(problems, 0, (problems = new IProblem[problemCount * 2]), 0, problemCount);
246 problems[problemCount++] = newProblem;
247 if (referenceContext != null){
248 if (problemsMap == null) problemsMap = new Hashtable(5);
249 if (firstErrorsMap == null) firstErrorsMap = new Hashtable(5);
250 if (newProblem.isError() && !referenceContext.hasErrors()) firstErrorsMap.put(newProblem, newProblem);
251 problemsMap.put(newProblem, referenceContext);
254 private static void swap(IProblem arr[], int i, int j) {
260 CompilationResult tagAsAccepted(){
261 this.hasBeenAccepted = true;
262 this.problemsMap = null; // flush
266 public String toString(){
267 StringBuffer buffer = new StringBuffer();
268 if (this.fileName != null){
269 buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$
271 if (this.compiledTypes != null){
272 buffer.append("COMPILED type(s) \n"); //$NON-NLS-1$
273 Enumeration typeNames = this.compiledTypes.keys();
274 while (typeNames.hasMoreElements()) {
275 char[] typeName = (char[]) typeNames.nextElement();
276 buffer.append("\t - ").append(typeName).append('\n'); //$NON-NLS-1$
280 buffer.append("No COMPILED type\n"); //$NON-NLS-1$
282 if (problems != null){
283 buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$//$NON-NLS-2$
284 for (int i = 0; i < this.problemCount; i++){
285 buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$
288 buffer.append("No PROBLEM\n"); //$NON-NLS-1$
290 return buffer.toString();