X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java index 6974459..bb11974 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/CompilationResult.java @@ -1,292 +1,461 @@ /******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. + * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html + * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation - ******************************************************************************/ + *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler; /** - * A compilation result consists of all information returned by the compiler for - * a single compiled compilation source unit. This includes: + * A compilation result consists of all information returned by the compiler for + * a single compiled compilation source unit. This includes: * - * - * The principle structure and binary may be null if the compiler could not produce them. - * If neither could be produced, there is no corresponding entry for the type. - * - * The dependency info includes type references such as supertypes, field types, method - * parameter and return types, local variable types, types of intermediate expressions, etc. - * It also includes the namespaces (packages) in which names were looked up. - * It does not include finer grained dependencies such as information about - * specific fields and methods which were referenced, but does contain their - * declaring types and any other types used to locate such fields or methods. + * + * The principle structure and binary may be null if the compiler could not + * produce them. If neither could be produced, there is no corresponding entry + * for the type. + * + * The dependency info includes type references such as supertypes, field types, + * method parameter and return types, local variable types, types of + * intermediate expressions, etc. It also includes the namespaces (packages) in + * which names were looked up. It does not include finer grained + * dependencies such as information about specific fields and methods which were + * referenced, but does contain their declaring types and any other types used + * to locate such fields or methods. */ -import net.sourceforge.phpdt.core.compiler.*; -import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration; -import net.sourceforge.phpdt.internal.compiler.env.*; -import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +// import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Map; -import java.util.*; +import net.sourceforge.phpdt.core.compiler.IProblem; +import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; public class CompilationResult { - + public IProblem problems[]; + + public IProblem tasks[]; + public int problemCount; + + public int taskCount; + public ICompilationUnit compilationUnit; + private Map problemsMap; + private Map firstErrorsMap; - private HashSet duplicateProblems; + private int maxProblemPerUnit; + public char[][][] qualifiedReferences; + public char[][] simpleNameReferences; public int lineSeparatorPositions[]; - public Hashtable compiledTypes = new Hashtable(11); + + // public Hashtable compiledTypes = new Hashtable(11); public int unitIndex, totalUnitsKnown; + public boolean hasBeenAccepted = false; + public char[] fileName; - -public CompilationResult( - char[] fileName, - int unitIndex, - int totalUnitsKnown, - int maxProblemPerUnit){ - - this.fileName = fileName; - this.unitIndex = unitIndex; - this.totalUnitsKnown = totalUnitsKnown; - this.maxProblemPerUnit = maxProblemPerUnit; -} + public CompilationResult(char[] fileName, int unitIndex, + int totalUnitsKnown, int maxProblemPerUnit) { -public CompilationResult( - ICompilationUnit compilationUnit, - int unitIndex, - int totalUnitsKnown, - int maxProblemPerUnit){ + this.fileName = fileName; + this.unitIndex = unitIndex; + this.totalUnitsKnown = totalUnitsKnown; + this.maxProblemPerUnit = maxProblemPerUnit; + } - this.fileName = compilationUnit.getFileName(); - this.compilationUnit = compilationUnit; - this.unitIndex = unitIndex; - this.totalUnitsKnown = totalUnitsKnown; - this.maxProblemPerUnit = maxProblemPerUnit; + public CompilationResult(ICompilationUnit compilationUnit, int unitIndex, + int totalUnitsKnown, int maxProblemPerUnit) { -} -private int computePriority(IProblem problem){ - - final int P_STATIC = 1000; - final int P_OUTSIDE_METHOD = 4000; - final int P_FIRST_ERROR = 2000; - final int P_ERROR = 10000; - - int priority = 1000 - problem.getSourceLineNumber(); // early problems first - if (priority < 0) priority = 0; - if (problem.isError()){ - priority += P_ERROR; + this.fileName = compilationUnit.getFileName(); + this.compilationUnit = compilationUnit; + this.unitIndex = unitIndex; + this.totalUnitsKnown = totalUnitsKnown; + this.maxProblemPerUnit = maxProblemPerUnit; } - ReferenceContext context = problemsMap == null ? null : (ReferenceContext) problemsMap.get(problem); - if (context != null){ - if (context instanceof AbstractMethodDeclaration){ - AbstractMethodDeclaration method = (AbstractMethodDeclaration) context; - if (method.isStatic()) { - priority += P_STATIC; - } + + private int computePriority(IProblem problem) { + + //final int P_STATIC = 1000; + final int P_OUTSIDE_METHOD = 4000; + final int P_FIRST_ERROR = 2000; + final int P_ERROR = 10000; + + int priority = 1000 - problem.getSourceLineNumber(); // early + // problems + // first + if (priority < 0) + priority = 0; + if (problem.isError()) { + priority += P_ERROR; + } + ReferenceContext context = problemsMap == null ? null + : (ReferenceContext) problemsMap.get(problem); + if (context != null) { + // if (context instanceof AbstractMethodDeclaration){ + // AbstractMethodDeclaration method = (AbstractMethodDeclaration) + // context; + // if (method.isStatic()) { + // priority += P_STATIC; + // } + // } else { + priority += P_OUTSIDE_METHOD; + // } } else { - priority += P_OUTSIDE_METHOD; + priority += P_OUTSIDE_METHOD; } - } else { - priority += P_OUTSIDE_METHOD; - } - if (firstErrorsMap.containsKey(problem)){ - priority += P_FIRST_ERROR; - } - return priority; -} -public ClassFile[] getClassFiles() { - Enumeration enum = compiledTypes.elements(); - ClassFile[] classFiles = new ClassFile[compiledTypes.size()]; - int index = 0; - while (enum.hasMoreElements()){ - classFiles[index++] = (ClassFile)enum.nextElement(); + if (firstErrorsMap.containsKey(problem)) { + priority += P_FIRST_ERROR; + } + return priority; } - return classFiles; -} -/** - * Answer the initial compilation unit corresponding to the present compilation result - */ -public ICompilationUnit getCompilationUnit(){ - return compilationUnit; -} -/** - * Answer the initial file name - */ -public char[] getFileName(){ - return fileName; -} -/** - * Answer the problems (errors and warnings) encountered during compilation. - * - * This is not a compiler internal API - it has side-effects ! - * It is intended to be used only once all problems have been detected, - * and makes sure the problems slot as the exact size of the number of - * problems. - */ -public IProblem[] getProblems() { - - // Re-adjust the size of the problems if necessary. - if (problems != null) { - if (this.problemCount != problems.length) { - System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount); + public IProblem[] getAllProblems() { + IProblem[] problems = this.getProblems(); + int problemCount = problems != null ? problems.length : 0; + IProblem[] tasks = this.getTasks(); + int taskCount = tasks != null ? tasks.length : 0; + if (taskCount == 0) { + return problems; + } + if (problemCount == 0) { + return tasks; } - if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){ - quickPrioritize(problems, 0, problemCount - 1); - this.problemCount = this.maxProblemPerUnit; - System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount); + int totalNumberOfProblem = problemCount + taskCount; + IProblem[] allProblems = new IProblem[totalNumberOfProblem]; + int allProblemIndex = 0; + int taskIndex = 0; + int problemIndex = 0; + while (taskIndex + problemIndex < totalNumberOfProblem) { + IProblem nextTask = null; + IProblem nextProblem = null; + if (taskIndex < taskCount) { + nextTask = tasks[taskIndex]; + } + if (problemIndex < problemCount) { + nextProblem = problems[problemIndex]; + } + // select the next problem + IProblem currentProblem = null; + if (nextProblem != null) { + if (nextTask != null) { + if (nextProblem.getSourceStart() < nextTask + .getSourceStart()) { + currentProblem = nextProblem; + problemIndex++; + } else { + currentProblem = nextTask; + taskIndex++; + } + } else { + currentProblem = nextProblem; + problemIndex++; + } + } else { + if (nextTask != null) { + currentProblem = nextTask; + taskIndex++; + } + } + allProblems[allProblemIndex++] = currentProblem; } + return allProblems; + } + + // public ClassFile[] getClassFiles() { + // Enumeration enum = compiledTypes.elements(); + // ClassFile[] classFiles = new ClassFile[compiledTypes.size()]; + // int index = 0; + // while (enum.hasMoreElements()){ + // classFiles[index++] = (ClassFile)enum.nextElement(); + // } + // return classFiles; + // } - // Sort problems per source positions. - quicksort(problems, 0, problems.length-1); + /** + * Answer the initial compilation unit corresponding to the present + * compilation result + */ + public ICompilationUnit getCompilationUnit() { + return compilationUnit; + } + + /** + * Answer the initial file name + */ + public char[] getFileName() { + return fileName; } - return problems; -} -public boolean hasErrors() { - if (problems != null) - for (int i = 0; i < problemCount; i++) { + /** + * Answer the errors encountered during compilation. + */ + public IProblem[] getErrors() { + + IProblem[] problems = getProblems(); + int errorCount = 0; + for (int i = 0; i < this.problemCount; i++) { if (problems[i].isError()) - return true; + errorCount++; } - return false; -} -public boolean hasProblems() { - return problemCount != 0; -} -public boolean hasWarnings() { - if (problems != null) - for (int i = 0; i < problemCount; i++) { - if (problems[i].isWarning()) - return true; + if (errorCount == this.problemCount) + return problems; + IProblem[] errors = new IProblem[errorCount]; + int index = 0; + for (int i = 0; i < this.problemCount; i++) { + if (problems[i].isError()) + errors[index++] = problems[i]; } - return false; -} + return errors; + } -private static void quicksort(IProblem arr[], int left, int right) { - int i, last, pos; + /** + * Answer the problems (errors and warnings) encountered during compilation. + * + * This is not a compiler internal API - it has side-effects ! It is + * intended to be used only once all problems have been detected, and makes + * sure the problems slot as the exact size of the number of problems. + */ + public IProblem[] getProblems() { - if (left >= right) { - /* do nothing if array contains fewer than two */ - return; - /* two elements */ + // Re-adjust the size of the problems if necessary. + if (problems != null) { + + if (this.problemCount != problems.length) { + System.arraycopy(problems, 0, + (problems = new IProblem[problemCount]), 0, + problemCount); + } + + if (this.maxProblemPerUnit > 0 + && this.problemCount > this.maxProblemPerUnit) { + quickPrioritize(problems, 0, problemCount - 1); + this.problemCount = this.maxProblemPerUnit; + System.arraycopy(problems, 0, + (problems = new IProblem[problemCount]), 0, + problemCount); + } + + // Sort problems per source positions. + quickSort(problems, 0, problems.length - 1); + } + return problems; } - swap(arr, left, (left + right) / 2); - last = left; - pos = arr[left].getSourceStart(); + /** + * Answer the tasks (TO-DO, ...) encountered during compilation. + * + * This is not a compiler internal API - it has side-effects ! It is + * intended to be used only once all problems have been detected, and makes + * sure the problems slot as the exact size of the number of problems. + */ + public IProblem[] getTasks() { - for (i = left + 1; i <= right; i++) { - if (arr[i].getSourceStart() < pos) { - swap(arr, ++last, i); + // Re-adjust the size of the tasks if necessary. + if (this.tasks != null) { + + if (this.taskCount != this.tasks.length) { + System.arraycopy(this.tasks, 0, + (this.tasks = new IProblem[this.taskCount]), 0, + this.taskCount); + } + quickSort(tasks, 0, tasks.length - 1); } + return this.tasks; } - swap(arr, left, last); - quicksort(arr, left, last - 1); - quicksort(arr, last + 1, right); -} +// public boolean hasErrors() { +// +// if (problems != null) +// for (int i = 0; i < problemCount; i++) { +// if (problems[i].isError()) +// return true; +// } +// return false; +// } -private void quickPrioritize(IProblem arr[], int left, int right) { - int i, last, prio; +// public boolean hasProblems() { +// +// return problemCount != 0; +// } - if (left >= right) { - /* do nothing if array contains fewer than two */ - return; - /* two elements */ + public boolean hasSyntaxError() { + + if (problems != null) + for (int i = 0; i < problemCount; i++) { + IProblem problem = problems[i]; + if ((problem.getID() & IProblem.Syntax) != 0 + && problem.isError()) + return true; + } + return false; } - swap(arr, left, (left + right) / 2); - last = left; - prio = computePriority(arr[left]); +// public boolean hasTasks() { +// return this.taskCount != 0; +// } - for (i = left + 1; i <= right; i++) { - if (computePriority(arr[i]) > prio) { - swap(arr, ++last, i); - } +// public boolean hasWarnings() { +// +// if (problems != null) +// for (int i = 0; i < problemCount; i++) { +// if (problems[i].isWarning()) +// return true; +// } +// return false; +// } + + private static void quickSort(IProblem[] list, int left, int right) { + + if (left >= right) + return; + + // sort the problems by their source start position... starting with 0 + int original_left = left; + int original_right = right; + int mid = list[(left + right) / 2].getSourceStart(); + do { + while (list[left].getSourceStart() < mid) + left++; + while (mid < list[right].getSourceStart()) + right--; + if (left <= right) { + IProblem tmp = list[left]; + list[left] = list[right]; + list[right] = tmp; + left++; + right--; + } + } while (left <= right); + if (original_left < right) + quickSort(list, original_left, right); + if (left < original_right) + quickSort(list, left, original_right); } - swap(arr, left, last); - quickPrioritize(arr, left, last - 1); - quickPrioritize(arr, last + 1, right); -} + private void quickPrioritize(IProblem[] list, int left, int right) { -/** - * For now, remember the compiled type using its compound name. - */ -public void record(char[] typeName, ClassFile classFile) { - compiledTypes.put(typeName, classFile); -} -public void record(IProblem newProblem, ReferenceContext referenceContext) { - if (problemCount == 0) { - problems = new IProblem[5]; - } else { - if (problemCount == problems.length) - System.arraycopy(problems, 0, (problems = new IProblem[problemCount * 2]), 0, problemCount); - }; - problems[problemCount++] = newProblem; - if (referenceContext != null){ - if (problemsMap == null) problemsMap = new Hashtable(5); - if (firstErrorsMap == null) firstErrorsMap = new Hashtable(5); - if (newProblem.isError() && !referenceContext.hasErrors()) firstErrorsMap.put(newProblem, newProblem); - problemsMap.put(newProblem, referenceContext); + if (left >= right) + return; + + // sort the problems by their priority... starting with the highest + // priority + int original_left = left; + int original_right = right; + int mid = computePriority(list[(left + right) / 2]); + do { + while (computePriority(list[right]) < mid) + right--; + while (mid < computePriority(list[left])) + left++; + if (left <= right) { + IProblem tmp = list[left]; + list[left] = list[right]; + list[right] = tmp; + left++; + right--; + } + } while (left <= right); + if (original_left < right) + quickPrioritize(list, original_left, right); + if (left < original_right) + quickPrioritize(list, left, original_right); } -} -private static void swap(IProblem arr[], int i, int j) { - IProblem tmp; - tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; -} -CompilationResult tagAsAccepted(){ - this.hasBeenAccepted = true; - this.problemsMap = null; // flush - return this; -} -public String toString(){ - StringBuffer buffer = new StringBuffer(); - if (this.fileName != null){ - buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$ + /** + * For now, remember the compiled type using its compound name. + */ + // public void record(char[] typeName, ClassFile classFile) { + // + // compiledTypes.put(typeName, classFile); + // } + public void record(IProblem newProblem, ReferenceContext referenceContext) { + + if (newProblem.getID() == IProblem.Task) { + recordTask(newProblem); + return; + } + if (problemCount == 0) { + problems = new IProblem[5]; + } else if (problemCount == problems.length) { + System.arraycopy(problems, 0, + (problems = new IProblem[problemCount * 2]), 0, + problemCount); + } + problems[problemCount++] = newProblem; + if (referenceContext != null) { + if (problemsMap == null) + problemsMap = new Hashtable(5); + if (firstErrorsMap == null) + firstErrorsMap = new Hashtable(5); + if (newProblem.isError() && !referenceContext.hasErrors()) + firstErrorsMap.put(newProblem, newProblem); + problemsMap.put(newProblem, referenceContext); + } } - if (this.compiledTypes != null){ - buffer.append("COMPILED type(s) \n"); //$NON-NLS-1$ - Enumeration typeNames = this.compiledTypes.keys(); - while (typeNames.hasMoreElements()) { - char[] typeName = (char[]) typeNames.nextElement(); - buffer.append("\t - ").append(typeName).append('\n'); //$NON-NLS-1$ - + + private void recordTask(IProblem newProblem) { + if (this.taskCount == 0) { + this.tasks = new IProblem[5]; + } else if (this.taskCount == this.tasks.length) { + System.arraycopy(this.tasks, 0, + (this.tasks = new IProblem[this.taskCount * 2]), 0, + this.taskCount); } - } else { - buffer.append("No COMPILED type\n"); //$NON-NLS-1$ + this.tasks[this.taskCount++] = newProblem; + } + + public CompilationResult tagAsAccepted() { + + this.hasBeenAccepted = true; + this.problemsMap = null; // flush + return this; } - if (problems != null){ - buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$//$NON-NLS-2$ - for (int i = 0; i < this.problemCount; i++){ - buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$ + + public String toString() { + + StringBuffer buffer = new StringBuffer(); + if (this.fileName != null) { + buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$ } - } else { - buffer.append("No PROBLEM\n"); //$NON-NLS-1$ - } - return buffer.toString(); -} + // if (this.compiledTypes != null){ + // buffer.append("COMPILED type(s) \n"); //$NON-NLS-1$ + // Enumeration typeNames = this.compiledTypes.keys(); + // while (typeNames.hasMoreElements()) { + // char[] typeName = (char[]) typeNames.nextElement(); + // buffer.append("\t - ").append(typeName).append('\n'); //$NON-NLS-1$ + // + // } + // } else { + // buffer.append("No COMPILED type\n"); //$NON-NLS-1$ + // } + if (problems != null) { + buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$//$NON-NLS-2$ + for (int i = 0; i < this.problemCount; i++) { + buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$ + } + } else { + buffer.append("No PROBLEM\n"); //$NON-NLS-1$ + } + return buffer.toString(); + } }