### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/Compiler.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java,v retrieving revision 1.80 diff -u -r1.80 Compiler.java --- compiler/org/eclipse/jdt/internal/compiler/Compiler.java 10 Nov 2006 19:31:46 -0000 1.80 +++ compiler/org/eclipse/jdt/internal/compiler/Compiler.java 14 Nov 2006 16:48:59 -0000 @@ -40,6 +40,9 @@ // ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD public static boolean DEBUG = false; public int parseThreshold = -1; + + public AnnotationProcessorManager annotationProcessorManager; + // number of initial units parsed at once (-1: none) /* @@ -354,34 +357,30 @@ CompilationUnitDeclaration parsedUnit; CompilationResult unitResult = new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit); - try { - if (options.verbose) { - this.out.println( - Messages.bind(Messages.compilation_request, - new String[] { - String.valueOf(i + 1), - String.valueOf(maxUnits), - new String(sourceUnits[i].getFileName()) - })); - } - // diet parsing for large collection of units - if (totalUnits < parseThreshold) { - parsedUnit = parser.parse(sourceUnits[i], unitResult); - } else { - parsedUnit = parser.dietParse(sourceUnits[i], unitResult); - } - // initial type binding creation - lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); - this.addCompilationUnit(sourceUnits[i], parsedUnit); ImportReference currentPackage = parsedUnit.currentPackage; if (currentPackage != null) { unitResult.recordPackageName(currentPackage.tokens); } - //} catch (AbortCompilationUnit e) { - // requestor.acceptResult(unitResult.tagAsAccepted()); - } finally { - sourceUnits[i] = null; // no longer hold onto the unit + if (options.verbose) { + this.out.println( + Messages.bind(Messages.compilation_request, + new String[] { + String.valueOf(i + 1), + String.valueOf(maxUnits), + new String(sourceUnits[i].getFileName()) + })); + } + // diet parsing for large collection of units + if (totalUnits < parseThreshold) { + parsedUnit = parser.parse(sourceUnits[i], unitResult); + } else { + parsedUnit = parser.dietParse(sourceUnits[i], unitResult); } + // initial type binding creation + lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); + this.addCompilationUnit(sourceUnits[i], parsedUnit); + //} catch (AbortCompilationUnit e) { + // requestor.acceptResult(unitResult.tagAsAccepted()); } // binding resolution lookupEnvironment.completeTypeBindings(); @@ -394,14 +393,16 @@ */ public void compile(ICompilationUnit[] sourceUnits) { CompilationUnitDeclaration unit = null; - int i = 0; try { // build and record parsed units beginToCompile(sourceUnits); + if (annotationProcessorManager != null) { + processAnnotations(sourceUnits); + } // process all units (some more could be injected in the loop by the lookup environment) - for (; i < this.totalUnits; i++) { + for (int i = 0; i < this.totalUnits; i++) { unit = unitsToProcess[i]; try { if (options.verbose) @@ -450,6 +451,39 @@ } } + protected void processAnnotations(ICompilationUnit[] sourceUnits) { + int newUnitSize = 0; + do { + for (int i = 0; i < this.totalUnits; i++) { + CompilationUnitDeclaration unit = unitsToProcess[i]; + this.annotationProcessorManager.processAnnotations(unit); + } + List newUnits = this.annotationProcessorManager.getNewUnits(); + newUnitSize = newUnits.size(); + ICompilationUnit[] newSourceUnits = sourceUnits; + if (newUnitSize != 0) { + // we reset the compiler in order to restart with the new units + this.reset(); + int sourceUnitsLength = sourceUnits.length; + ICompilationUnit[] newSourceUnits = new ICompilationUnit[sourceUnitsLength + newUnitSize]; + newUnits.toArray(newSourceUnits); + System.arraycopy(sourceUnits, 0, newSourceUnits, newUnitSize, sourceUnitsLength); + beginToCompile(newSourceUnits); + this.annotationProcessorManager.reset(); + } + } while (newUnitSize != 0);` + // one more loop to create possible resources + // this loop cannot create any java source files + for (int i = 0; i < this.totalUnits; i++) { + CompilationUnitDeclaration unit = unitsToProcess[i]; + this.annotationProcessorManager.processAnnotations(unit); + } + List newUnits = this.annotationProcessorManager.getNewUnits(); + if (newUnits.size() != 0) { + // report error + } + } + /* * Compiler crash recovery in case of unexpected runtime exceptions */ Index: compiler/org/eclipse/jdt/internal/compiler/AnnotationProcessorManager.java =================================================================== RCS file: compiler/org/eclipse/jdt/internal/compiler/AnnotationProcessorManager.java diff -N compiler/org/eclipse/jdt/internal/compiler/AnnotationProcessorManager.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ compiler/org/eclipse/jdt/internal/compiler/AnnotationProcessorManager.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,37 @@ +package org.eclipse.jdt.internal.compiler; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; + +public class AnnotationProcessorManager { + List addedUnits; + + public static AnnotationProcessorManager configure(String[] commandLineArguments) { + return new AnnotationProcessorManager(); + } + + private AnnotationProcessorManager() { + this.addedUnits = new ArrayList(); + } + + public void processAnnotations(CompilationUnitDeclaration unit) { + // do nothing + } + + public void addNewUnit(ICompilationUnit unit) { + this.addedUnits.add(unit); + } + + public List getNewUnits() { + return this.addedUnits; + } + + public void reset() { + this.addedUnits.clear(); + } + + +} Index: compiler/org/eclipse/jdt/internal/compiler/AnnotationDiscoveryVisitor.java =================================================================== RCS file: compiler/org/eclipse/jdt/internal/compiler/AnnotationDiscoveryVisitor.java diff -N compiler/org/eclipse/jdt/internal/compiler/AnnotationDiscoveryVisitor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ compiler/org/eclipse/jdt/internal/compiler/AnnotationDiscoveryVisitor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,114 @@ +package org.eclipse.jdt.internal.compiler; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Argument; +import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; +import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; +import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; +import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.ClassScope; +import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; +import org.eclipse.jdt.internal.compiler.lookup.MethodScope; + +public class AnnotationDiscoveryVisitor extends ASTVisitor { + +Binding currentBinding; +List collector; +public AnnotationDiscoveryVisitor() { + this.collector = new ArrayList(); +} +public boolean visit(Argument argument, BlockScope scope) { + this.currentBinding = argument.binding; + Annotation[] annotations = argument.annotations; + if (annotations != null) { + int annotationsLength = annotations.length; + for (int i = 0; i < annotationsLength; i++) { + annotations[i].traverse(this, scope); + } + } + return false; +} +public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) { + this.currentBinding = constructorDeclaration.binding; + Annotation[] annotations = constructorDeclaration.annotations; + if (annotations != null) { + int annotationsLength = annotations.length; + for (int i = 0; i < annotationsLength; i++) { + annotations[i].traverse(this, constructorDeclaration.scope); + } + } + Argument[] arguments = constructorDeclaration.arguments; + if (arguments != null) { + int argumentLength = arguments.length; + for (int i = 0; i < argumentLength; i++) { + arguments[i].traverse(this, constructorDeclaration.scope); + } + } + return false; +} +public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) { + this.currentBinding = fieldDeclaration.binding; + Annotation[] annotations = fieldDeclaration.annotations; + if (annotations != null) { + int annotationsLength = annotations.length; + for (int i = 0; i < annotationsLength; i++) { + annotations[i].traverse(this, scope); + } + } + return false; +} +public void endVisit(MarkerAnnotation annotation, BlockScope scope) { + ASTNode.resolveAnnotations(scope, new Annotation[] { annotation}, this.currentBinding); + collector.add(annotation.getCompilerAnnotation()); +} +public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { + this.currentBinding = methodDeclaration.binding; + Annotation[] annotations = methodDeclaration.annotations; + if (annotations != null) { + int annotationsLength = annotations.length; + for (int i = 0; i < annotationsLength; i++) { + annotations[i].traverse(this, methodDeclaration.scope); + } + } + Argument[] arguments = methodDeclaration.arguments; + if (arguments != null) { + int argumentLength = arguments.length; + for (int i = 0; i < argumentLength; i++) { + arguments[i].traverse(this, methodDeclaration.scope); + } + } + return false; +} +public void endVisit(NormalAnnotation annotation, BlockScope scope) { + ASTNode.resolveAnnotations(scope, new Annotation[] { annotation}, this.currentBinding); + this.collector.add(annotation.getCompilerAnnotation()); +} +public void endVisit(SingleMemberAnnotation annotation, BlockScope scope) { + ASTNode.resolveAnnotations(scope, new Annotation[] { annotation}, this.currentBinding); + this.collector.add(annotation.getCompilerAnnotation()); +} +/* (non-Javadoc) + * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope) + */ +public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) { + this.currentBinding = memberTypeDeclaration.binding; + return true; +} +/* (non-Javadoc) + * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope) + */ +public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) { + this.currentBinding = typeDeclaration.binding; + return true; +} + +}