### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java,v retrieving revision 1.54 diff -u -r1.54 FileSystem.java --- batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java 27 Aug 2009 15:27:01 -0000 1.54 +++ batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java 17 Feb 2010 20:36:35 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -126,7 +126,7 @@ } initializeKnownFileNames(initialFileNames); } -FileSystem(Classpath[] paths, String[] initialFileNames) { +protected FileSystem(Classpath[] paths, String[] initialFileNames) { final int length = paths.length; int counter = 0; this.classpaths = new FileSystem.Classpath[length]; Index: batch/org/eclipse/jdt/internal/compiler/batch/Main.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java,v retrieving revision 1.349 diff -u -r1.349 Main.java --- batch/org/eclipse/jdt/internal/compiler/batch/Main.java 13 Jan 2010 15:13:48 -0000 1.349 +++ batch/org/eclipse/jdt/internal/compiler/batch/Main.java 17 Feb 2010 20:36:35 -0000 @@ -2837,12 +2837,7 @@ public File getJavaHome() { if (!this.javaHomeChecked) { this.javaHomeChecked = true; - String javaHome = System.getProperty("java.home");//$NON-NLS-1$ - if (javaHome != null) { - this.javaHomeCache = new File(javaHome); - if (!this.javaHomeCache.exists()) - this.javaHomeCache = null; - } + this.javaHomeCache = Util.getJavaHome(); } return this.javaHomeCache; } @@ -2872,74 +2867,13 @@ paths[i], customEncoding, false, true); } } else { - bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH); - /* no bootclasspath specified - * we can try to retrieve the default librairies of the VM used to run - * the batch compiler - */ - String javaversion = System.getProperty("java.version");//$NON-NLS-1$ - if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$ + bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH); + try { + Util.collectRunningVMBootclasspath(bootclasspaths); + } catch(IllegalStateException e) { this.logger.logWrongJDK(); this.proceed = false; return null; - } - - /* - * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath - */ - // check bootclasspath properties for Sun, JRockit and Harmony VMs - String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$ - if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { - // IBM J9 VMs - bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$ - if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { - // Harmony using IBM VME - bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$ - } - } - if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) { - StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator); - String token; - while (tokenizer.hasMoreTokens()) { - token = tokenizer.nextToken(); - FileSystem.Classpath currentClasspath = FileSystem - .getClasspath(token, customEncoding, null); - if (currentClasspath != null) { - bootclasspaths.add(currentClasspath); - } - } - } else { - // try to get all jars inside the lib folder of the java home - final File javaHome = getJavaHome(); - if (javaHome != null) { - File[] directoriesToCheck = null; - if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$ - directoriesToCheck = new File[] { - new File(javaHome, "../Classes"), //$NON-NLS-1$ - }; - } else { - // fall back to try to retrieve them out of the lib directory - directoriesToCheck = new File[] { - new File(javaHome, "lib") //$NON-NLS-1$ - }; - } - File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck); - if (systemLibrariesJars != null) { - for (int i = 0, max = systemLibrariesJars.length; i < max; i++) { - File[] current = systemLibrariesJars[i]; - if (current != null) { - for (int j = 0, max2 = current.length; j < max2; j++) { - FileSystem.Classpath classpath = - FileSystem.getClasspath(current[j].getAbsolutePath(), - null, false, null, null); - if (classpath != null) { - bootclasspaths.add(classpath); - } - } - } - } - } - } } } return bootclasspaths; Index: compiler/org/eclipse/jdt/internal/compiler/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java,v retrieving revision 1.76 diff -u -r1.76 Util.java --- compiler/org/eclipse/jdt/internal/compiler/util/Util.java 24 Jun 2009 12:31:27 -0000 1.76 +++ compiler/org/eclipse/jdt/internal/compiler/util/Util.java 17 Feb 2010 20:36:35 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -24,6 +24,7 @@ import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.HashSet; +import java.util.List; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -31,6 +32,8 @@ import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.batch.FileSystem; +import org.eclipse.jdt.internal.compiler.batch.Main; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; @@ -882,4 +885,85 @@ classFile.recordInnerClasses(typeBinding); } } + /* + * External API + */ + public static File getJavaHome() { + String javaHome = System.getProperty("java.home");//$NON-NLS-1$ + if (javaHome != null) { + File javaHomeFile = new File(javaHome); + if (javaHomeFile.exists()) { + return javaHomeFile; + } + } + return null; + } + + public static void collectRunningVMBootclasspath(List bootclasspaths) { + /* no bootclasspath specified + * we can try to retrieve the default librairies of the VM used to run + * the batch compiler + */ + String javaversion = System.getProperty("java.version");//$NON-NLS-1$ + if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$ + throw new IllegalStateException(); + } + + /* + * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath + */ + // check bootclasspath properties for Sun, JRockit and Harmony VMs + String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$ + if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { + // IBM J9 VMs + bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$ + if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { + // Harmony using IBM VME + bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$ + } + } + if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) { + StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator); + String token; + while (tokenizer.hasMoreTokens()) { + token = tokenizer.nextToken(); + FileSystem.Classpath currentClasspath = FileSystem.getClasspath(token, null, null); + if (currentClasspath != null) { + bootclasspaths.add(currentClasspath); + } + } + } else { + // try to get all jars inside the lib folder of the java home + final File javaHome = getJavaHome(); + if (javaHome != null) { + File[] directoriesToCheck = null; + if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$ + directoriesToCheck = new File[] { + new File(javaHome, "../Classes"), //$NON-NLS-1$ + }; + } else { + // fall back to try to retrieve them out of the lib directory + directoriesToCheck = new File[] { + new File(javaHome, "lib") //$NON-NLS-1$ + }; + } + File[][] systemLibrariesJars = Main.getLibrariesFiles(directoriesToCheck); + if (systemLibrariesJars != null) { + for (int i = 0, max = systemLibrariesJars.length; i < max; i++) { + File[] current = systemLibrariesJars[i]; + if (current != null) { + for (int j = 0, max2 = current.length; j < max2; j++) { + FileSystem.Classpath classpath = + FileSystem.getClasspath(current[j].getAbsolutePath(), + null, false, null, null); + if (classpath != null) { + bootclasspaths.add(classpath); + } + } + } + } + } + } + } + } } \ No newline at end of file Index: dom/org/eclipse/jdt/core/dom/AST.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java,v retrieving revision 1.165 diff -u -r1.165 AST.java --- dom/org/eclipse/jdt/core/dom/AST.java 27 Jun 2008 16:03:46 -0000 1.165 +++ dom/org/eclipse/jdt/core/dom/AST.java 17 Feb 2010 20:36:36 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -267,7 +267,7 @@ ast.setDefaultNodeFlag(ASTNode.ORIGINAL); BindingResolver resolver = null; if (isResolved) { - resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false); + resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false, true); ((DefaultBindingResolver) resolver).isRecoveringBindings = (reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0; ast.setFlag(AST.RESOLVED_BINDINGS); } else { Index: dom/org/eclipse/jdt/core/dom/ASTParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java,v retrieving revision 1.95 diff -u -r1.95 ASTParser.java --- dom/org/eclipse/jdt/core/dom/ASTParser.java 3 Dec 2009 14:29:11 -0000 1.95 +++ dom/org/eclipse/jdt/core/dom/ASTParser.java 17 Feb 2010 20:36:36 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 IBM Corporation and others. + * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,7 +12,9 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; @@ -28,6 +30,7 @@ import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; +import org.eclipse.jdt.internal.compiler.batch.Main; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner; import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData; @@ -132,31 +135,7 @@ * Compiler options. Defaults to JavaCore.getOptions(). */ private Map compilerOptions; - - /** - * Request for bindings. Defaults to false. - */ - private boolean resolveBindings; - - /** - * Request for a partial AST. Defaults to false. - */ - private boolean partial = false; - - /** - * Request for a statements recovery. Defaults to false. - */ - private boolean statementsRecovery; - - /** - * Request to ignore parsing the method bodies. Defaults to false. - */ - private boolean ignoreMethodBodies; - /** - * Request for a bindings recovery. Defaults to false. - */ - private boolean bindingsRecovery; - + /** * The focal point for a partial AST request. * Only used when partial is true. @@ -203,15 +182,35 @@ * null if none. Defaults to none. */ private String unitName = null; + + /** + * Classpath entries to use to resolve bindings when no java project are available. + */ + private String[] classpaths; - /** + /** + * Sourcepath entries to use to resolve bindings when no java project are available. + */ + private String[] sourcepaths; + + /** + * Encoding of the given sourcepaths entries. + */ + private String[] sourcepathsEncodings; + + /** + * Bits used to set the different values from CompilationUnitResolver values. + */ + private int bits; + + /** * Creates a new AST parser for the given API level. *

* N.B. This constructor is package-private. *

* * @param level the API level; one of the LEVEL constants - * declared on AST + * declared on AST */ ASTParser(int level) { if ((level != AST.JLS2_INTERNAL) @@ -219,9 +218,40 @@ throw new IllegalArgumentException(); } this.apiLevel = level; - initializeDefaults(); + initializeDefaults(); } + private List getClasspath() throws IllegalStateException { + Main main = new Main(new PrintWriter(System.out), new PrintWriter(System.err), false/*systemExit*/, null/*options*/, null/*progress*/); + ArrayList allClasspaths = new ArrayList(); + try { + if ((this.bits & CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH) != 0) { + org.eclipse.jdt.internal.compiler.util.Util.collectRunningVMBootclasspath(allClasspaths); + } + if (this.sourcepaths != null) { + for (int i = 0, max = this.sourcepaths.length; i < max; i++) { + String encoding = this.sourcepathsEncodings == null ? null : this.sourcepathsEncodings[i]; + main.processPathEntries( + Main.DEFAULT_SIZE_CLASSPATH, + allClasspaths, this.sourcepaths[i], encoding, true, false); + } + } + if (this.classpaths != null) { + for (int i = 0, max = this.classpaths.length; i < max; i++) { + main.processPathEntries( + Main.DEFAULT_SIZE_CLASSPATH, + allClasspaths, this.classpaths[i], null, false, false); + } + } + ArrayList pendingErrors = main.pendingErrors; + if (pendingErrors != null && pendingErrors.size() != 0) { + throw new IllegalStateException("invalid environment settings"); //$NON-NLS-1$ + } + } catch (IllegalArgumentException e) { + throw new IllegalStateException("invalid environment settings"); //$NON-NLS-1$ + } + return allClasspaths; + } /** * Sets all the setting to their default values. */ @@ -229,14 +259,15 @@ this.astKind = K_COMPILATION_UNIT; this.rawSource = null; this.typeRoot = null; - this.resolveBindings = false; - this.ignoreMethodBodies = false; + this.bits = 0; this.sourceLength = -1; this.sourceOffset = 0; this.workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY; this.unitName = null; this.project = null; - this.partial = false; + this.classpaths = null; + this.sourcepaths = null; + this.sourcepathsEncodings = null; Map options = JavaCore.getOptions(); options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags this.compilerOptions = options; @@ -258,7 +289,44 @@ * @since 3.3 */ public void setBindingsRecovery(boolean enabled) { - this.bindingsRecovery = enabled; + if (enabled) { + this.bits |= CompilationUnitResolver.BINDING_RECOVERY; + } else { + this.bits &= ~CompilationUnitResolver.BINDING_RECOVERY; + } + } + + /** + * Set the environment that can be used when no IJavaProject are available. + * + *

The user has to be sure to include all required types on the classpaths for binary types + * or on the sourcepaths for source types to resolve the given source code.

+ *

All classpath and sourcepath entries are absolute paths.

+ *

If sourcepaths contain units using a specific encoding (not the platform encoding), then the + * given encodings must be set. If the given encodings is set, its length must + * match the length of the sourcepaths parameter or an IllegalArgumentException will be thrown.

+ *

If encodings is not null, the given sourcepathEntries must not be null.

+ * + * @param classpathEntries the given classpath entries to be used to resolve bindings + * @param sourcepathEntries the given sourcepath entries to be used to resolve bindings + * @param encodings the encodings of the corresponding sourcepath entries or null if the plafform encoding + * can be used. + * @param includeRunningVMBootclasspath true if the bootclasspath of the running VM must be prepended to the + * given classpath and false if the bootclasspath of the running VM should be ignored. + * @throws IllegalArgumentException if the size of the given encodings is not equals to the size of the given + * sourcepathEntries + * @since 3.6 + */ + public void setEnvironment(String[] classpathEntries, String[] sourcepathEntries, String[] encodings, boolean includeRunningVMBootclasspath) { + this.classpaths = classpathEntries; + this.sourcepaths = sourcepathEntries; + this.sourcepathsEncodings = encodings; + if (encodings != null) { + if (sourcepathEntries == null || sourcepathEntries.length != encodings.length) { + throw new IllegalArgumentException(); + } + } + this.bits |= CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH; } /** * Sets the compiler options to be used when parsing. @@ -298,12 +366,12 @@ /** * Requests that the compiler should provide binding information for - * the AST nodes it creates. - *

- * Default to false (no bindings). - *

+ * the AST nodes it creates. *

- * If setResolveBindings(true), the various names + * Default to false (no bindings). + *

+ *

+ * If {@link #setResolveBindings(boolean) setResolveBindings(true)}, the various names * and types appearing in the AST can be resolved to "bindings" * by calling the resolveBinding methods. These bindings * draw connections between the different parts of a program, and @@ -318,10 +386,9 @@ * resolveBinding methods in any way; these methods return the * same binding as before the AST was modified (including modifications * that rearrange subtrees by reparenting nodes). - * If setResolveBindings(false) (the default), the analysis + * If {@link #setResolveBindings(boolean) setResolveBindings(false)}, (the default), the analysis * does not go beyond parsing and building the tree, and all - * resolveBinding methods return null from the - * outset. + * resolveBinding methods return null from the outset. *

*

* When bindings are requested, instead of considering compilation units on disk only @@ -329,24 +396,31 @@ * by this owner take precedence over the underlying compilation units when looking * up names and drawing the connections. *

+ *

Note that working copy owner are used only if the org.eclipse.jdt.core + * bundle is initialized.

*

- * Binding information is obtained from the Java model. - * This means that the compilation unit must be located relative to the - * Java model. This happens automatically when the source code comes from - * either {@link #setSource(ICompilationUnit) setSource(ICompilationUnit)} - * or {@link #setSource(IClassFile) setSource(IClassFile)}. - * When source is supplied by {@link #setSource(char[]) setSource(char[])}, - * the location must be extablished explicitly by calling - * {@link #setProject(IJavaProject)} and {@link #setUnitName(String)}. + * Binding information is obtained from the Java model. + * This means that the compilation unit must be located relative to the + * Java model. This happens automatically when the source code comes from + * either {@link #setSource(ICompilationUnit) setSource(ICompilationUnit)} + * or {@link #setSource(IClassFile) setSource(IClassFile)}. + * When source is supplied by {@link #setSource(char[]) setSource(char[])}, + * the location must be established explicitly by setting an environment using + * {@link #setProject(IJavaProject)} or {@link #setEnvironment(String[], String[], String[], boolean)} + * and a unit name {@link #setUnitName(String)}. * Note that the compiler options that affect doc comment checking may also * affect whether any bindings are resolved for nodes within doc comments. *

* - * @param bindings true if bindings are wanted, + * @param enabled true if bindings are wanted, * and false if bindings are not of interest */ - public void setResolveBindings(boolean bindings) { - this.resolveBindings = bindings; + public void setResolveBindings(boolean enabled) { + if (enabled) { + this.bits |= CompilationUnitResolver.RESOLVE_BINDING; + } else { + this.bits &= ~CompilationUnitResolver.RESOLVE_BINDING; + } } /** @@ -389,7 +463,7 @@ * @param position a position into the corresponding body declaration */ public void setFocalPosition(int position) { - this.partial = true; + this.bits |= CompilationUnitResolver.PARTIAL; this.focalPointPosition = position; } @@ -588,7 +662,11 @@ * @since 3.2 */ public void setStatementsRecovery(boolean enabled) { - this.statementsRecovery = enabled; + if (enabled) { + this.bits |= CompilationUnitResolver.STATEMENT_RECOVERY; + } else { + this.bits &= ~CompilationUnitResolver.STATEMENT_RECOVERY; + } } /** @@ -602,7 +680,11 @@ * @since 3.5.2 */ public void setIgnoreMethodBodies(boolean enabled) { - this.ignoreMethodBodies = enabled; + if (enabled) { + this.bits |= CompilationUnitResolver.IGNORE_METHOD_BODIES; + } else { + this.bits &= ~CompilationUnitResolver.IGNORE_METHOD_BODIES; + } } /** @@ -682,55 +764,54 @@ * default values so the object is ready to be reused. *

* - * @param monitor the progress monitor used to report progress and request cancelation, + * @param monitor the progress monitor used to report progress and request cancellation, * or null if none * @return an AST node whose type depends on the kind of parse * requested, with a fallback to a CompilationUnit * in the case of severe parsing errors * @exception IllegalStateException if the settings provided * are insufficient, contradictory, or otherwise unsupported - */ + */ public ASTNode createAST(IProgressMonitor monitor) { - ASTNode result = null; - if (monitor != null) monitor.beginTask("", 1); //$NON-NLS-1$ + ASTNode result = null; + if (monitor != null) monitor.beginTask("", 1); //$NON-NLS-1$ try { if (this.rawSource == null && this.typeRoot == null) { - throw new IllegalStateException("source not specified"); //$NON-NLS-1$ - } - result = internalCreateAST(monitor); + throw new IllegalStateException("source not specified"); //$NON-NLS-1$ + } + result = internalCreateAST(monitor); } finally { - // re-init defaults to allow reuse (and avoid leaking) - initializeDefaults(); - if (monitor != null) monitor.done(); + // reset to defaults to allow reuse (and avoid leaking) + initializeDefaults(); + if (monitor != null) monitor.done(); } - return result; + return result; } /** - * Creates ASTs for a batch of compilation units. - * When bindings are being resolved, processing a - * batch of compilation units is more efficient because much - * of the work involved in resolving bindings can be shared. - *

- * When bindings are being resolved, all compilation units must - * come from the same Java project, which must be set beforehand - * with setProject. - * The compilation units are processed one at a time in no - * specified order. For each of the compilation units in turn, + * Creates ASTs for a batch of compilation units. + *

When bindings are being resolved, processing a + * batch of compilation units is more efficient because much + * of the work involved in resolving bindings can be shared.

+ *

+ * When bindings are being resolved, all compilation units must + * come from the same Java project, which must be set beforehand + * with {@link #setProject(IJavaProject) setProject}.

+ *

The compilation units are processed one at a time in no + * specified order. For each of the compilation units in turn,

* - * Note only ASTs from the given compilation units are reported - * to the requestor. If additional compilation units are required to - * resolve the original ones, the corresponding ASTs are not - * reported to the requestor. - *

+ * Note only ASTs from the given compilation units are reported + * to the requestor. If additional compilation units are required to + * resolve the original ones, the corresponding ASTs are not + * reported to the requestor. + *

*

* Note also the following parser parameters are used, regardless of what * may have been specified: @@ -740,61 +821,161 @@ *

  • The {@linkplain #setFocalPosition(int) focal position} is not set
  • * *

    - *

    - * The bindingKeys parameter specifies bindings keys - * ({@link IBinding#getKey()}) that are to be looked up. These keys may - * be for elements either inside or outside the set of compilation - * units being processed. When bindings are being resolved, - * the keys and corresponding bindings (or null if none) are - * passed to ASTRequestor.acceptBinding. Note that binding keys - * for elements outside the set of compilation units being processed are looked up - * after all ASTRequestor.acceptAST callbacks have been made. - * Binding keys for elements inside the set of compilation units being processed - * are looked up and reported right after the corresponding - * ASTRequestor.acceptAST callback has been made. - * No ASTRequestor.acceptBinding callbacks are made unless - * bindings are being resolved. - *

    - *

    - * A successful call to this method returns all settings to their - * default values so the object is ready to be reused. - *

    - * - * @param compilationUnits the compilation units to create ASTs for - * @param bindingKeys the binding keys to create bindings for - * @param requestor the AST requestor that collects abstract syntax trees and bindings + *

    + * The bindingKeys parameter specifies bindings keys + * ({@link IBinding#getKey()}) that are to be looked up. These keys may + * be for elements either inside or outside the set of compilation + * units being processed. When bindings are being resolved, + * the keys and corresponding bindings (or null if none) are + * passed to {@link ASTRequestor#acceptBinding(String, IBinding) ASTRequestor.acceptBinding}. + * Note that binding keys for elements outside the set of compilation units being processed + * are looked up after all {@link ASTRequestor#acceptAST(ICompilationUnit, CompilationUnit) ASTRequestor.acceptAST} + * callbacks have been made. + * Binding keys for elements inside the set of compilation units being processed + * are looked up and reported right after the corresponding + * {@link ASTRequestor#acceptAST(ICompilationUnit, CompilationUnit) ASTRequestor.acceptAST} callback has been made. + * No {@link ASTRequestor#acceptBinding(String, IBinding) ASTRequestor.acceptBinding} callbacks are made unless + * bindings are being resolved. + *

    + *

    + * A successful call to this method returns all settings to their + * default values so the object is ready to be reused. + *

    + * + * @param compilationUnits the compilation units to create ASTs for + * @param bindingKeys the binding keys to create bindings for + * @param requestor the AST requestor that collects abstract syntax trees and bindings * @param monitor the progress monitor used to report progress and request cancellation, * or null if none * @exception IllegalStateException if the settings provided * are insufficient, contradictory, or otherwise unsupported * @since 3.1 - */ + */ public void createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor, IProgressMonitor monitor) { try { int flags = 0; - if (this.statementsRecovery) flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; - if (this.ignoreMethodBodies) flags |= ICompilationUnit.IGNORE_METHOD_BODIES; - if (this.resolveBindings) { + if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; + } + if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) { + flags |= ICompilationUnit.IGNORE_METHOD_BODIES; + } + if ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0) { if (this.project == null) throw new IllegalStateException("project not specified"); //$NON-NLS-1$ - if (this.bindingsRecovery) flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; + if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; + } CompilationUnitResolver.resolve(compilationUnits, bindingKeys, requestor, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, flags, monitor); } else { CompilationUnitResolver.parse(compilationUnits, requestor, this.apiLevel, this.compilerOptions, flags, monitor); } } finally { - // re-init defaults to allow reuse (and avoid leaking) + // reset to defaults to allow reuse (and avoid leaking) initializeDefaults(); } } /** + * Creates ASTs for a batch of compilation units. + * When bindings are being resolved, processing a + * batch of compilation units is more efficient because much + * of the work involved in resolving bindings can be shared. + *

    + * When bindings are being resolved, all compilation units are resolved using + * the same environment, which must be set beforehand + * with {@link #setEnvironment(String[], String[], String[], boolean) setEnvironment}. + * The compilation units are processed one at a time in no + * specified order. For each of the compilation units in turn, + *

    + * Note only ASTs from the given compilation units are reported + * to the requestor. If additional compilation units are required to + * resolve the original ones, the corresponding ASTs are not + * reported to the requestor. + *

    + *

    + * Note also the following parser parameters are used, regardless of what + * may have been specified: + *

    + *

    + *

    + * The bindingKeys parameter specifies bindings keys + * ({@link IBinding#getKey()}) that are to be looked up. These keys may + * be for elements either inside or outside the set of compilation + * units being processed. When bindings are being resolved, + * the keys and corresponding bindings (or null if none) are + * passed to {@link FileASTRequestor#acceptBinding(String, IBinding) FileASTRequestor.acceptBinding}. Note that binding keys + * for elements outside the set of compilation units being processed are looked up + * after all {@link FileASTRequestor#acceptAST(String, CompilationUnit) ASTRequestor.acceptAST} + * callbacks have been made. + * Binding keys for elements inside the set of compilation units being processed + * are looked up and reported right after the corresponding + * {@link FileASTRequestor#acceptAST(String, CompilationUnit) FileASTRequestor.acceptAST} callback has been made. + * No {@link FileASTRequestor#acceptBinding(String, IBinding) FileASTRequestor.acceptBinding} callbacks are made unless + * bindings are being resolved. + *

    + *

    + * A successful call to this method returns all settings to their + * default values so the object is ready to be reused. + *

    + *

    The given encodings are used to properly parse the given source units. If the platform encoding is sufficient, + * then the given encodings can be set to null.

    + * + * @param sourceFilePaths the compilation units to create ASTs for + * @param encodings the given encoding for the source units + * @param bindingKeys the binding keys to create bindings for + * @param requestor the AST requestor that collects abstract syntax trees and bindings + * @param monitor the progress monitor used to report progress and request cancellation, + * or null if none + * @exception IllegalStateException if the settings provided + * are insufficient, contradictory, or otherwise unsupported + * @since 3.6 + */ + public void createASTs(String[] sourceFilePaths, String[] encodings, String[] bindingKeys, + FileASTRequestor requestor, IProgressMonitor monitor) { + try { + int flags = 0; + if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; + } + if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) { + flags |= ICompilationUnit.IGNORE_METHOD_BODIES; + } + if ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0) { + if (this.classpaths == null && this.sourcepaths == null && ((this.bits & CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH) == 0)) { + throw new IllegalStateException("no environment is specified"); //$NON-NLS-1$ + } + if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; + } + CompilationUnitResolver.resolve(sourceFilePaths, encodings, bindingKeys, requestor, this.apiLevel, this.compilerOptions, getClasspath(), flags, monitor); + } else { + CompilationUnitResolver.parse(sourceFilePaths, encodings, requestor, this.apiLevel, this.compilerOptions, flags, monitor); + } + } finally { + // reset to defaults to allow reuse (and avoid leaking) + initializeDefaults(); + } + } + /** * Creates bindings for a batch of Java elements. These elements are either * enclosed in {@link ICompilationUnit}s or in {@link IClassFile}s. *

    * All enclosing compilation units and class files must * come from the same Java project, which must be set beforehand - * with setProject. + * with {@link #setProject(IJavaProject) setProject}. *

    *

    * All elements must exist. If one doesn't exist, an IllegalStateException @@ -830,20 +1011,26 @@ public IBinding[] createBindings(IJavaElement[] elements, IProgressMonitor monitor) { try { if (this.project == null) - throw new IllegalStateException("project not specified"); //$NON-NLS-1$ + throw new IllegalStateException("project or classpath not specified"); //$NON-NLS-1$ int flags = 0; - if (this.statementsRecovery) flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; - if (this.bindingsRecovery) flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; - if (this.ignoreMethodBodies) flags |= ICompilationUnit.IGNORE_METHOD_BODIES; + if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; + } + if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; + } + if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) { + flags |= ICompilationUnit.IGNORE_METHOD_BODIES; + } return CompilationUnitResolver.resolve(elements, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, flags, monitor); } finally { - // re-init defaults to allow reuse (and avoid leaking) + // reset to defaults to allow reuse (and avoid leaking) initializeDefaults(); } } private ASTNode internalCreateAST(IProgressMonitor monitor) { - boolean needToResolveBindings = this.resolveBindings; + boolean needToResolveBindings = (this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0; switch(this.astKind) { case K_CLASS_BODY_DECLARATIONS : case K_EXPRESSION : @@ -935,25 +1122,39 @@ throw new IllegalStateException(String.valueOf(stringWriter.getBuffer())); } } else if (this.rawSource != null) { - needToResolveBindings = this.resolveBindings && this.unitName != null && this.project != null && this.compilerOptions != null; + needToResolveBindings = + ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0) + && this.unitName != null + && (this.project != null + || this.classpaths != null + || this.sourcepaths != null + || ((this.bits & CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH) != 0)) + && this.compilerOptions != null; sourceUnit = new BasicCompilationUnit(this.rawSource, null, this.unitName == null ? "" : this.unitName, this.project); //$NON-NLS-1$ } else { throw new IllegalStateException(); } - if (this.partial) { + if ((this.bits & CompilationUnitResolver.PARTIAL) != 0) { searcher = new NodeSearcher(this.focalPointPosition); } int flags = 0; - if (this.statementsRecovery) flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; - if (searcher == null && this.ignoreMethodBodies) flags |= ICompilationUnit.IGNORE_METHOD_BODIES; + if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY; + } + if (searcher == null && ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0)) { + flags |= ICompilationUnit.IGNORE_METHOD_BODIES; + } if (needToResolveBindings) { - if (this.bindingsRecovery) flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; + if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) { + flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; + } try { // parse and resolve compilationUnitDeclaration = CompilationUnitResolver.resolve( sourceUnit, this.project, + getClasspath(), searcher, this.compilerOptions, this.workingCopyOwner, @@ -985,11 +1186,13 @@ wcOwner, needToResolveBindings ? new DefaultBindingResolver.BindingTables() : null, flags, - monitor); + monitor, + this.project != null); result.setTypeRoot(this.typeRoot); return result; } finally { - if (compilationUnitDeclaration != null && this.resolveBindings) { + if (compilationUnitDeclaration != null + && ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0)) { compilationUnitDeclaration.cleanUp(); } } @@ -1076,18 +1279,24 @@ AST ast = AST.newAST(this.apiLevel); ast.setDefaultNodeFlag(ASTNode.ORIGINAL); ast.setBindingResolver(new BindingResolver()); - if (this.statementsRecovery) { + if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) { ast.setFlag(ICompilationUnit.ENABLE_STATEMENTS_RECOVERY); } converter.setAST(ast); - CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil(this.ignoreMethodBodies); + CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0); CompilationUnit compilationUnit = ast.newCompilationUnit(); if (this.sourceLength == -1) { this.sourceLength = this.rawSource.length; } switch(this.astKind) { case K_STATEMENTS : - ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true, this.statementsRecovery); + ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements( + this.rawSource, + this.sourceOffset, + this.sourceLength, + this.compilerOptions, + true, + (this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0); RecoveryScannerData data = constructorDeclaration.compilationResult.recoveryScannerData; if(data != null) { Scanner scanner = converter.scanner; @@ -1147,7 +1356,14 @@ return compilationUnit; } case K_CLASS_BODY_DECLARATIONS : - final org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes = codeSnippetParsingUtil.parseClassBodyDeclarations(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true, this.statementsRecovery); + final org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes = + codeSnippetParsingUtil.parseClassBodyDeclarations( + this.rawSource, + this.sourceOffset, + this.sourceLength, + this.compilerOptions, + true, + (this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0); recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation; comments = recordedParsingInformation.commentPositions; if (comments != null) { Index: dom/org/eclipse/jdt/core/dom/ASTRequestor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java,v retrieving revision 1.15 diff -u -r1.15 ASTRequestor.java --- dom/org/eclipse/jdt/core/dom/ASTRequestor.java 7 Mar 2009 01:08:09 -0000 1.15 +++ dom/org/eclipse/jdt/core/dom/ASTRequestor.java 17 Feb 2010 20:36:36 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,18 +14,17 @@ /** * An AST requestor handles ASTs for compilation units passed to - * ASTParser.createASTs. + * {@link ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}. *

    - * ASTRequestor.acceptAST is called for each of the - * compilation units passed to ASTParser.createASTs. + * {@link #acceptAST(ICompilationUnit, CompilationUnit) ASTRequestor.acceptAST} is called for each of the + * compilation units passed to {@link ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}. * After all the compilation units have been processed, - * ASTRequestor.acceptBindings is called for each - * of the binding keys passed to ASTParser.createASTs. + * {@link #acceptBinding(String, IBinding) ASTRequestor.acceptBindings} is called for each + * of the binding keys passed to {@link ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}. *

    *

    * This class is intended to be subclassed by clients. - * AST requestors are serially reusable, but neither reentrant nor - * thread-safe. + * AST requestors are serially reusable, but neither reentrant nor thread-safe. *

    * * @see ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) Index: dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java,v retrieving revision 1.139 diff -u -r1.139 CompilationUnitResolver.java --- dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java 27 Nov 2009 17:51:16 -0000 1.139 +++ dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java 17 Feb 2010 20:36:36 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,9 +10,12 @@ *******************************************************************************/ package org.eclipse.jdt.core.dom; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; @@ -32,6 +35,7 @@ import org.eclipse.jdt.internal.compiler.IProblemFactory; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; import org.eclipse.jdt.internal.compiler.env.INameEnvironment; import org.eclipse.jdt.internal.compiler.env.ISourceType; @@ -47,9 +51,11 @@ import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt; import org.eclipse.jdt.internal.compiler.util.Messages; +import org.eclipse.jdt.internal.compiler.util.Util; import org.eclipse.jdt.internal.core.BinaryMember; import org.eclipse.jdt.internal.core.CancelableNameEnvironment; import org.eclipse.jdt.internal.core.CancelableProblemFactory; +import org.eclipse.jdt.internal.core.INameEnviromentWithProgress; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.NameLookup; import org.eclipse.jdt.internal.core.SourceRefElement; @@ -59,6 +65,12 @@ import org.eclipse.jdt.internal.core.util.DOMFinder; class CompilationUnitResolver extends Compiler { + public static final int RESOLVE_BINDING = 0x1; + public static final int PARTIAL = 0x2; + public static final int STATEMENT_RECOVERY = 0x4; + public static final int IGNORE_METHOD_BODIES = 0x8; + public static final int BINDING_RECOVERY = 0x10; + public static final int INCLUDE_RUNNING_VM_BOOTCLASSPATH = 0x20; /* A list of int */ static class IntArrayList { @@ -74,7 +86,7 @@ /* * The sources that were requested. - * Map from file name (char[]) to ICompilationUnit. + * Map from file name (char[]) to org.eclipse.jdt.internal.compiler.env.ICompilationUnit. */ HashtableOfObject requestedSources; @@ -89,6 +101,11 @@ boolean hasCompilationAborted; private IProgressMonitor monitor; + + /** + * Set to true if the receiver was initialized using a java project name environment + */ + boolean fromJavaProject; /** * Answer a new CompilationUnitVisitor using the given name environment and compiler options. @@ -131,11 +148,13 @@ CompilerOptions compilerOptions, ICompilerRequestor requestor, IProblemFactory problemFactory, - IProgressMonitor monitor) { + IProgressMonitor monitor, + boolean fromJavaProject) { super(environment, policy, compilerOptions, requestor, problemFactory); this.hasCompilationAborted = false; this.monitor =monitor; + this.fromJavaProject = fromJavaProject; } /* @@ -238,18 +257,28 @@ BindingKeyResolver keyResolver = new BindingKeyResolver(key, this, this.lookupEnvironment); Binding compilerBinding = keyResolver.getCompilerBinding(); if (compilerBinding == null) return null; - DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, null/*no owner*/, this.bindingTables, false); + DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, null/*no owner*/, this.bindingTables, false, this.fromJavaProject); return resolver.getBinding(compilerBinding); } - public static CompilationUnit convert(CompilationUnitDeclaration compilationUnitDeclaration, char[] source, int apiLevel, Map options, boolean needToResolveBindings, WorkingCopyOwner owner, DefaultBindingResolver.BindingTables bindingTables, int flags, IProgressMonitor monitor) { + public static CompilationUnit convert( + CompilationUnitDeclaration compilationUnitDeclaration, + char[] source, + int apiLevel, + Map options, + boolean needToResolveBindings, + WorkingCopyOwner owner, + DefaultBindingResolver.BindingTables bindingTables, + int flags, + IProgressMonitor monitor, + boolean fromJavaProject) { BindingResolver resolver = null; AST ast = AST.newAST(apiLevel); ast.setDefaultNodeFlag(ASTNode.ORIGINAL); CompilationUnit compilationUnit = null; ASTConverter converter = new ASTConverter(options, needToResolveBindings, monitor); if (needToResolveBindings) { - resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, owner, bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0); + resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, owner, bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, fromJavaProject); ast.setFlag(flags | AST.RESOLVED_BINDINGS); } else { resolver = new BindingResolver(); @@ -370,7 +399,7 @@ } // convert AST - CompilationUnit node = convert(compilationUnitDeclaration, parser.scanner.getSource(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, flags /* flags */, monitor); + CompilationUnit node = convert(compilationUnitDeclaration, parser.scanner.getSource(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, flags /* flags */, monitor, true); node.setTypeRoot(compilationUnits[i]); // accept AST @@ -382,7 +411,71 @@ if (monitor != null) monitor.done(); } } + public static void parse( + String[] sourceUnits, + String[] encodings, + FileASTRequestor astRequestor, + int apiLevel, + Map options, + int flags, + IProgressMonitor monitor) { + try { + CompilerOptions compilerOptions = new CompilerOptions(options); + compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0; + Parser parser = new CommentRecorderParser( + new ProblemReporter( + DefaultErrorHandlingPolicies.proceedWithAllProblems(), + compilerOptions, + new DefaultProblemFactory()), + false); + int unitLength = sourceUnits.length; + if (monitor != null) monitor.beginTask("", unitLength); //$NON-NLS-1$ + for (int i = 0; i < unitLength; i++) { + char[] contents = null; + String encoding = encodings != null ? encodings[i] : null; + try { + contents = Util.getFileCharContent(new File(sourceUnits[i]), encoding); + } catch(IOException e) { + // go to the next unit + continue; + } + if (contents == null) { + // go to the next unit + continue; + } + org.eclipse.jdt.internal.compiler.batch.CompilationUnit compilationUnit = new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(contents, sourceUnits[i], encoding); + org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationUnit; + CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit); + CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult); + + if (compilationUnitDeclaration.ignoreMethodBodies) { + compilationUnitDeclaration.ignoreFurtherInvestigation = true; + // if initial diet parse did not work, no need to dig into method bodies. + continue; + } + + //fill the methods bodies in order for the code to be generated + //real parse of the method.... + org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types; + if (types != null) { + for (int j = 0, typeLength = types.length; j < typeLength; j++) { + types[j].parseMethods(parser, compilationUnitDeclaration); + } + } + + // convert AST + CompilationUnit node = convert(compilationUnitDeclaration, parser.scanner.getSource(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, flags /* flags */, monitor, true); + node.setTypeRoot(null); + + // accept AST + astRequestor.acceptAST(sourceUnits[i], node); + if (monitor != null) monitor.worked(1); + } + } finally { + if (monitor != null) monitor.done(); + } + } public static CompilationUnitDeclaration parse( org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, NodeSearcher nodeSearcher, @@ -479,7 +572,8 @@ compilerOptions, getRequestor(), problemFactory, - monitor); + monitor, + javaProject != null); resolver.resolve(compilationUnits, bindingKeys, requestor, apiLevel, options, owner, flags); if (NameLookup.VERBOSE) { System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -491,16 +585,66 @@ } finally { if (monitor != null) monitor.done(); if (environment != null) { - environment.monitor = null; // don't hold a reference to this external object + environment.setMonitor(null); // don't hold a reference to this external object } if (problemFactory != null) { problemFactory.monitor = null; // don't hold a reference to this external object } } } + public static void resolve( + String[] sourceUnits, + String[] encodings, + String[] bindingKeys, + FileASTRequestor requestor, + int apiLevel, + Map options, + List classpaths, + int flags, + IProgressMonitor monitor) { + + INameEnviromentWithProgress environment = null; + CancelableProblemFactory problemFactory = null; + try { + if (monitor != null) { + int amountOfWork = (sourceUnits.length + bindingKeys.length) * 2; // 1 for beginToCompile, 1 for resolve + monitor.beginTask("", amountOfWork); //$NON-NLS-1$ + } + Classpath[] allEntries = new Classpath[classpaths.size()]; + classpaths.toArray(allEntries); + environment = new NameEnviromentWithProgress(allEntries, null, monitor); + problemFactory = new CancelableProblemFactory(monitor); + CompilerOptions compilerOptions = getCompilerOptions(options, (flags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); + compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0; + CompilationUnitResolver resolver = + new CompilationUnitResolver( + environment, + getHandlingPolicy(), + compilerOptions, + getRequestor(), + problemFactory, + monitor, + false); + resolver.resolve(sourceUnits, encodings, bindingKeys, requestor, apiLevel, options, flags); + if (NameLookup.VERBOSE && (environment instanceof CancelableNameEnvironment)) { + CancelableNameEnvironment cancelableNameEnvironment = (CancelableNameEnvironment) environment; + System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ + System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } finally { + if (monitor != null) monitor.done(); + if (environment != null) { + environment.setMonitor(null); // don't hold a reference to this external object + } + if (problemFactory != null) { + problemFactory.monitor = null; // don't hold a reference to this external object + } + } + } public static CompilationUnitDeclaration resolve( org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, IJavaProject javaProject, + List classpaths, NodeSearcher nodeSearcher, Map options, WorkingCopyOwner owner, @@ -508,11 +652,17 @@ IProgressMonitor monitor) throws JavaModelException { CompilationUnitDeclaration unit = null; - CancelableNameEnvironment environment = null; + INameEnviromentWithProgress environment = null; CancelableProblemFactory problemFactory = null; CompilationUnitResolver resolver = null; try { - environment = new CancelableNameEnvironment(((JavaProject)javaProject), owner, monitor); + if (javaProject == null) { + Classpath[] allEntries = new Classpath[classpaths.size()]; + classpaths.toArray(allEntries); + environment = new NameEnviromentWithProgress(allEntries, null, monitor); + } else { + environment = new CancelableNameEnvironment((JavaProject) javaProject, owner, monitor); + } problemFactory = new CancelableProblemFactory(monitor); CompilerOptions compilerOptions = getCompilerOptions(options, (flags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); boolean ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0; @@ -524,7 +674,8 @@ compilerOptions, getRequestor(), problemFactory, - monitor); + monitor, + javaProject != null); boolean analyzeAndGenerateCode = !ignoreMethodBodies; unit = resolver.resolve( @@ -546,27 +697,20 @@ } return unitDeclaration; } - if (NameLookup.VERBOSE) { - System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ - System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ + if (NameLookup.VERBOSE && environment instanceof CancelableNameEnvironment) { + CancelableNameEnvironment cancelableNameEnvironment = (CancelableNameEnvironment) environment; + System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ + System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ } return unit; } finally { if (environment != null) { - environment.monitor = null; // don't hold a reference to this external object + // don't hold a reference to this external object + environment.setMonitor(null); } if (problemFactory != null) { problemFactory.monitor = null; // don't hold a reference to this external object } - // first unit cleanup is done by caller, but cleanup all enqueued requested units (not processed) -// if (resolver != null) { -// for (int i = 1; i < resolver.totalUnits; i++) { // could be more requested units -// CompilationUnitDeclaration parsedUnit = resolver.unitsToProcess[i]; -// if (parsedUnit.scope != null) -// parsedUnit.scope.faultInTypes(); // force resolution of signatures, so clients can query DOM AST -// parsedUnit.cleanUp(); -// } -// } } } public static IBinding[] resolve( @@ -680,7 +824,14 @@ } } - private void resolve(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor astRequestor, int apiLevel, Map compilerOptions, WorkingCopyOwner owner, int flags) { + private void resolve( + ICompilationUnit[] compilationUnits, + String[] bindingKeys, + ASTRequestor astRequestor, + int apiLevel, + Map compilerOptions, + WorkingCopyOwner owner, + int flags) { // temporarily connect ourselves to the ASTResolver - must disconnect when done astRequestor.compilationUnitResolver = this; @@ -719,7 +870,7 @@ ast.setFlag(flags | AST.RESOLVED_BINDINGS); ast.setDefaultNodeFlag(ASTNode.ORIGINAL); ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, this.monitor); - BindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0); + BindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, this.fromJavaProject); ast.setBindingResolver(resolver); converter.setAST(ast); CompilationUnit compilationUnit = converter.convert(unit, contents); @@ -763,7 +914,140 @@ } // remaining binding keys - DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, owner, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0); + DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, owner, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, true); + Object[] keys = this.requestedKeys.valueTable; + for (int j = 0, keysLength = keys.length; j < keysLength; j++) { + BindingKeyResolver keyResolver = (BindingKeyResolver) keys[j]; + if (keyResolver == null) continue; + Binding compilerBinding = keyResolver.getCompilerBinding(); + IBinding binding = compilerBinding == null ? null : resolver.getBinding(compilerBinding); + // pass it to requestor + astRequestor.acceptBinding(((BindingKeyResolver) this.requestedKeys.valueTable[j]).getKey(), binding); + worked(1); + } + } catch (OperationCanceledException e) { + throw e; + } catch (AbortCompilation e) { + this.handleInternalException(e, unit); + } catch (Error e) { + this.handleInternalException(e, unit, null); + throw e; // rethrow + } catch (RuntimeException e) { + this.handleInternalException(e, unit, null); + throw e; // rethrow + } finally { + // disconnect ourselves from ast requestor + astRequestor.compilationUnitResolver = null; + } + } + + private void resolve( + String[] sourceCompilationUnits, + String[] encodings, + String[] bindingKeys, + FileASTRequestor astRequestor, + int apiLevel, + Map compilerOptions, + int flags) { + + // temporarily connect ourselves to the ASTResolver - must disconnect when done + astRequestor.compilationUnitResolver = this; + this.bindingTables = new DefaultBindingResolver.BindingTables(); + CompilationUnitDeclaration unit = null; + try { + int length = sourceCompilationUnits.length; + org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] sourceUnits = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[length]; + int count = 0; + for (int i = 0; i < length; i++) { + char[] contents = null; + String encoding = encodings != null ? encodings[i] : null; + String sourceUnitPath = sourceCompilationUnits[i]; + try { + contents = Util.getFileCharContent(new File(sourceUnitPath), encoding); + } catch(IOException e) { + // go to the next unit + continue; + } + if (contents == null) { + // go to the next unit + continue; + } + sourceUnits[count++] = new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(contents, sourceUnitPath, encoding); + } + beginToCompile(sourceUnits, bindingKeys); + // process all units (some more could be injected in the loop by the lookup environment) + for (int i = 0; i < this.totalUnits; i++) { + if (resolvedRequestedSourcesAndKeys(i)) { + // no need to keep resolving if no more ASTs and no more binding keys are needed + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=114935 + // cleanup remaining units + for (; i < this.totalUnits; i++) { + this.unitsToProcess[i].cleanUp(); + this.unitsToProcess[i] = null; + } + break; + } + unit = this.unitsToProcess[i]; + try { + super.process(unit, i); // this.process(...) is optimized to not process already known units + + // requested AST + char[] fileName = unit.compilationResult.getFileName(); + org.eclipse.jdt.internal.compiler.env.ICompilationUnit source = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.requestedSources.get(fileName); + if (source != null) { + // convert AST + CompilationResult compilationResult = unit.compilationResult; + org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationResult.compilationUnit; + char[] contents = sourceUnit.getContents(); + AST ast = AST.newAST(apiLevel); + ast.setFlag(flags | AST.RESOLVED_BINDINGS); + ast.setDefaultNodeFlag(ASTNode.ORIGINAL); + ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, this.monitor); + BindingResolver resolver = new DefaultBindingResolver(unit.scope, null, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, this.fromJavaProject); + ast.setBindingResolver(resolver); + converter.setAST(ast); + CompilationUnit compilationUnit = converter.convert(unit, contents); + compilationUnit.setTypeRoot(null); + compilationUnit.setLineEndTable(compilationResult.getLineSeparatorPositions()); + ast.setDefaultNodeFlag(0); + ast.setOriginalModificationCount(ast.modificationCount()); + + // pass it to requestor + astRequestor.acceptAST(new String(source.getFileName()), compilationUnit); + + worked(1); + + // remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested + this.requestedSources.put(fileName, null); // mark it as removed + } + + // requested binding + Object key = this.requestedKeys.get(fileName); + if (key != null) { + if (key instanceof BindingKeyResolver) { + reportBinding(key, astRequestor, unit); + worked(1); + } else if (key instanceof ArrayList) { + Iterator iterator = ((ArrayList) key).iterator(); + while (iterator.hasNext()) { + reportBinding(iterator.next(), astRequestor, unit); + worked(1); + } + } + + // remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested + this.requestedKeys.put(fileName, null); // mark it as removed + } + } finally { + // cleanup compilation unit result + unit.cleanUp(); + } + this.unitsToProcess[i] = null; // release reference to processed unit declaration + this.requestor.acceptResult(unit.compilationResult.tagAsAccepted()); + } + + // remaining binding keys + DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, null, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, true); Object[] keys = this.requestedKeys.valueTable; for (int j = 0, keysLength = keys.length; j < keysLength; j++) { BindingKeyResolver keyResolver = (BindingKeyResolver) keys[j]; @@ -794,7 +1078,24 @@ BindingKeyResolver keyResolver = (BindingKeyResolver) key; Binding compilerBinding = keyResolver.getCompilerBinding(); if (compilerBinding != null) { - DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables, false); + DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables, false, this.fromJavaProject); + AnnotationBinding annotationBinding = keyResolver.getAnnotationBinding(); + IBinding binding; + if (annotationBinding != null) { + binding = resolver.getAnnotationInstance(annotationBinding); + } else { + binding = resolver.getBinding(compilerBinding); + } + if (binding != null) + astRequestor.acceptBinding(keyResolver.getKey(), binding); + } + } + + private void reportBinding(Object key, FileASTRequestor astRequestor, CompilationUnitDeclaration unit) { + BindingKeyResolver keyResolver = (BindingKeyResolver) key; + Binding compilerBinding = keyResolver.getCompilerBinding(); + if (compilerBinding != null) { + DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, null, this.bindingTables, false, this.fromJavaProject); AnnotationBinding annotationBinding = keyResolver.getAnnotationBinding(); IBinding binding; if (annotationBinding != null) { Index: dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java,v retrieving revision 1.168 diff -u -r1.168 DefaultBindingResolver.java --- dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java 28 Apr 2009 16:53:03 -0000 1.168 +++ dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java 17 Feb 2010 20:36:36 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -134,11 +134,16 @@ * Toggle controlling whether DOM bindings should be created when missing internal compiler bindings.. */ boolean isRecoveringBindings; - + + /** + * Set to true if initialized from a java project + */ + boolean fromJavaProject; + /** * Constructor for DefaultBindingResolver. */ - DefaultBindingResolver(CompilationUnitScope scope, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings) { + DefaultBindingResolver(CompilationUnitScope scope, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings, boolean fromJavaProject) { this.newAstToOldAst = new HashMap(); this.astNodesToBlockScope = new HashMap(); this.bindingsToAstNodes = new HashMap(); @@ -146,9 +151,10 @@ this.scope = scope; this.workingCopyOwner = workingCopyOwner; this.isRecoveringBindings = isRecoveringBindings; + this.fromJavaProject = fromJavaProject; } - DefaultBindingResolver(LookupEnvironment lookupEnvironment, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings) { + DefaultBindingResolver(LookupEnvironment lookupEnvironment, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings, boolean fromJavaProject) { this.newAstToOldAst = new HashMap(); this.astNodesToBlockScope = new HashMap(); this.bindingsToAstNodes = new HashMap(); @@ -156,6 +162,7 @@ this.scope = new CompilationUnitScope(new CompilationUnitDeclaration(null, null, -1), lookupEnvironment); this.workingCopyOwner = workingCopyOwner; this.isRecoveringBindings = isRecoveringBindings; + this.fromJavaProject = fromJavaProject; } /* Index: dom/org/eclipse/jdt/core/dom/FileASTRequestor.java =================================================================== RCS file: dom/org/eclipse/jdt/core/dom/FileASTRequestor.java diff -N dom/org/eclipse/jdt/core/dom/FileASTRequestor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dom/org/eclipse/jdt/core/dom/FileASTRequestor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.dom; + +/** + * An AST requestor handles ASTs for compilation units passed to + * {@link ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}. + *

    + * {@link FileASTRequestor#acceptAST(String, CompilationUnit) FileASTRequestor.acceptAST} is called for each of the + * compilation units passed to {@link ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}. + * After all the compilation units have been processed, + * {@link #acceptBinding(String, IBinding) FileASTRequestor.acceptBinding} is called for each + * of the binding keys passed to {@link ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}. + *

    + *

    + * This class is intended to be subclassed by clients. + * AST requestors are serially reusable, but neither reentrant nor thread-safe. + *

    + * + * @see ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) + * @since 3.6 + */ +public abstract class FileASTRequestor { + + /** + * The compilation unit resolver used to resolve bindings, or + * null if none. Note that this field is non-null + * only within the dynamic scope of a call to + * ASTParser.createASTs. + */ + CompilationUnitResolver compilationUnitResolver = null; + + /** + * Accepts an AST corresponding to the compilation unit. + * That is, ast is an AST for source. + *

    + * The default implementation of this method does nothing. + * Clients should override to process the resulting AST. + *

    + * + * @param sourceFilePath the compilation unit the given ast is coming from + * @param ast the requested abstract syntax tree + */ + public void acceptAST(String sourceFilePath, CompilationUnit ast) { + // do nothing + } + + /** + * Accepts a binding corresponding to the binding key. + * That is, binding is the binding for + * bindingKey; binding is null + * if the key cannot be resolved. + *

    + * The default implementation of this method does nothing. + * Clients should override to process the resulting binding. + *

    + * + * @param bindingKey the key of the requested binding + * @param binding the requested binding, or null if none + */ + public void acceptBinding(String bindingKey, IBinding binding) { + // do nothing + } + + /** + * Resolves bindings for the given binding keys. + * The given binding keys must have been obtained earlier + * using {@link IBinding#getKey()}. + *

    + * If a binding key cannot be resolved, null is put in the resulting array. + * Bindings can only be resolved in the dynamic scope of a ASTParser.createASTs, + * and only if ASTParser.resolveBindings(true) was specified. + *

    + *

    + * Caveat: During an acceptAST callback, there are implementation + * limitations concerning the look up of binding keys representing local elements. + * In some cases, the binding is unavailable, and null will be returned. + * This is only an issue during an acceptAST callback, and only + * when the binding key represents a local element (e.g., local variable, + * local class, method declared in anonymous class). There is no such limitation + * outside of acceptAST callbacks, or for top-level types and their + * members even within acceptAST callbacks. + *

    + * + * @param bindingKeys the binding keys to look up + * @return a list of bindings paralleling the bindingKeys parameter, + * with null entries for keys that could not be resolved + */ + public final IBinding[] createBindings(String[] bindingKeys) { + int length = bindingKeys.length; + IBinding[] result = new IBinding[length]; + for (int i = 0; i < length; i++) { + result[i] = null; + if (this.compilationUnitResolver != null) { + result[i] = this.compilationUnitResolver.createBinding(bindingKeys[i]); + } + } + return result; + } +} Index: dom/org/eclipse/jdt/core/dom/MethodBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java,v retrieving revision 1.93 diff -u -r1.93 MethodBinding.java --- dom/org/eclipse/jdt/core/dom/MethodBinding.java 27 Jun 2008 16:03:47 -0000 1.93 +++ dom/org/eclipse/jdt/core/dom/MethodBinding.java 17 Feb 2010 20:36:38 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,6 +12,7 @@ package org.eclipse.jdt.core.dom; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding; @@ -243,9 +244,13 @@ } private JavaElement getUnresolvedJavaElement() { + if (JavaCore.getPlugin() == null) { + return null; + } if (!(this.resolver instanceof DefaultBindingResolver)) return null; DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; + if (!defaultBindingResolver.fromJavaProject) return null; return Util.getUnresolvedJavaElement( this.binding, defaultBindingResolver.workingCopyOwner, Index: dom/org/eclipse/jdt/core/dom/NameEnviromentWithProgress.java =================================================================== RCS file: dom/org/eclipse/jdt/core/dom/NameEnviromentWithProgress.java diff -N dom/org/eclipse/jdt/core/dom/NameEnviromentWithProgress.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dom/org/eclipse/jdt/core/dom/NameEnviromentWithProgress.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.dom; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jdt.internal.compiler.batch.FileSystem; +import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; +import org.eclipse.jdt.internal.core.INameEnviromentWithProgress; +import org.eclipse.jdt.internal.core.NameLookup; + +/** + * Batch name environment that is cancelable using a monitor. + * @since 3.6 + */ +class NameEnviromentWithProgress extends FileSystem implements INameEnviromentWithProgress { + IProgressMonitor monitor; + + public NameEnviromentWithProgress(Classpath[] paths, String[] initialFileNames, IProgressMonitor monitor) { + super(paths, initialFileNames); + setMonitor(monitor); + } + private void checkCanceled() { + if (this.monitor != null && this.monitor.isCanceled()) { + if (NameLookup.VERBOSE) + System.out.println(Thread.currentThread() + " CANCELLING LOOKUP "); //$NON-NLS-1$ + throw new AbortCompilation(true/*silent*/, new OperationCanceledException()); + } + } + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { + checkCanceled(); + return super.findType(typeName, packageName); + } + public NameEnvironmentAnswer findType(char[][] compoundName) { + checkCanceled(); + return super.findType(compoundName); + } + public boolean isPackage(char[][] compoundName, char[] packageName) { + checkCanceled(); + return super.isPackage(compoundName, packageName); + } + + public void setMonitor(IProgressMonitor monitor) { + this.monitor = monitor; + } +} Index: dom/org/eclipse/jdt/core/dom/TypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java,v retrieving revision 1.145 diff -u -r1.145 TypeBinding.java --- dom/org/eclipse/jdt/core/dom/TypeBinding.java 7 Mar 2009 00:59:01 -0000 1.145 +++ dom/org/eclipse/jdt/core/dom/TypeBinding.java 17 Feb 2010 20:36:38 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,6 +12,7 @@ package org.eclipse.jdt.core.dom; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.Wildcard; @@ -512,15 +513,18 @@ return getUnresolvedJavaElement(this.binding); } private JavaElement getUnresolvedJavaElement(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding ) { + if (JavaCore.getPlugin() == null) { + return null; + } if (this.resolver instanceof DefaultBindingResolver) { DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; + if (!defaultBindingResolver.fromJavaProject) return null; return org.eclipse.jdt.internal.core.util.Util.getUnresolvedJavaElement( typeBinding, defaultBindingResolver.workingCopyOwner, defaultBindingResolver.getBindingsToNodesMap()); - } else { - return org.eclipse.jdt.internal.core.util.Util.getUnresolvedJavaElement(typeBinding, null, null); } + return null; } /* Index: dom/org/eclipse/jdt/core/dom/VariableBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java,v retrieving revision 1.62 diff -u -r1.62 VariableBinding.java --- dom/org/eclipse/jdt/core/dom/VariableBinding.java 27 Jun 2008 16:03:48 -0000 1.62 +++ dom/org/eclipse/jdt/core/dom/VariableBinding.java 17 Feb 2010 20:36:38 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,6 +12,7 @@ package org.eclipse.jdt.core.dom; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.util.IModifierConstants; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; @@ -202,20 +203,25 @@ } private JavaElement getUnresolvedJavaElement() { + if (JavaCore.getPlugin() == null) { + return null; + } if (isField()) { if (this.resolver instanceof DefaultBindingResolver) { DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; + if (!defaultBindingResolver.fromJavaProject) return null; return Util.getUnresolvedJavaElement( (FieldBinding) this.binding, defaultBindingResolver.workingCopyOwner, defaultBindingResolver.getBindingsToNodesMap()); - } else { - return Util.getUnresolvedJavaElement((FieldBinding) this.binding, null, null); } + return null; } // local variable if (!(this.resolver instanceof DefaultBindingResolver)) return null; - VariableDeclaration localVar = (VariableDeclaration) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this); + DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; + if (!defaultBindingResolver.fromJavaProject) return null; + VariableDeclaration localVar = (VariableDeclaration) defaultBindingResolver.bindingsToAstNodes.get(this); if (localVar == null) return null; int nameStart; int nameLength; @@ -244,15 +250,10 @@ // Local variable is declared inside an initializer TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; JavaElement typeHandle = null; - if (this.resolver instanceof DefaultBindingResolver) { - DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver; - typeHandle = Util.getUnresolvedJavaElement( - typeDeclaration.binding, - defaultBindingResolver.workingCopyOwner, - defaultBindingResolver.getBindingsToNodesMap()); - } else { - typeHandle = Util.getUnresolvedJavaElement(typeDeclaration.binding, null, null); - } + typeHandle = Util.getUnresolvedJavaElement( + typeDeclaration.binding, + defaultBindingResolver.workingCopyOwner, + defaultBindingResolver.getBindingsToNodesMap()); parent = Util.getUnresolvedJavaElement(sourceStart, sourceEnd, typeHandle); } else { return null; Index: model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java,v retrieving revision 1.11 diff -u -r1.11 CancelableNameEnvironment.java --- model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java 7 Mar 2009 01:08:08 -0000 1.11 +++ model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java 17 Feb 2010 20:36:38 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 IBM Corporation and others. + * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -19,12 +19,12 @@ import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; -public class CancelableNameEnvironment extends SearchableEnvironment { - public IProgressMonitor monitor; +public class CancelableNameEnvironment extends SearchableEnvironment implements INameEnviromentWithProgress { + private IProgressMonitor monitor; public CancelableNameEnvironment(JavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { super(project, owner); - this.monitor = monitor; + setMonitor(monitor); } private void checkCanceled() { @@ -54,4 +54,8 @@ checkCanceled(); super.findTypes(prefix, findMembers, camelCaseMatch, searchFor, storage, progressMonitor); } + + public void setMonitor(IProgressMonitor monitor) { + this.monitor = monitor; + } } Index: model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java,v retrieving revision 1.65 diff -u -r1.65 CompilationUnitProblemFinder.java --- model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java 26 Nov 2009 16:20:05 -0000 1.65 +++ model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java 17 Feb 2010 20:36:38 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -229,7 +229,7 @@ throw new JavaModelException(e, IJavaModelStatusConstants.COMPILER_FAILURE); } finally { if (environment != null) - environment.monitor = null; // don't hold a reference to this external object + environment.setMonitor(null); // don't hold a reference to this external object if (problemFactory != null) problemFactory.monitor = null; // don't hold a reference to this external object // NB: unit.cleanUp() is done by caller Index: model/org/eclipse/jdt/internal/core/INameEnviromentWithProgress.java =================================================================== RCS file: model/org/eclipse/jdt/internal/core/INameEnviromentWithProgress.java diff -N model/org/eclipse/jdt/internal/core/INameEnviromentWithProgress.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ model/org/eclipse/jdt/internal/core/INameEnviromentWithProgress.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,8 @@ +package org.eclipse.jdt.internal.core; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.internal.compiler.env.INameEnvironment; + +public interface INameEnviromentWithProgress extends INameEnvironment { + void setMonitor(IProgressMonitor monitor); +} #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java,v retrieving revision 1.83 diff -u -r1.83 TestAll.java --- src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java 21 Oct 2009 16:19:39 -0000 1.83 +++ src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java 17 Feb 2010 20:36:39 -0000 @@ -15,6 +15,7 @@ import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.jdt.core.tests.dom.StandAloneASTParserTest; import org.eclipse.jdt.core.tests.junit.extension.TestCase; import org.eclipse.jdt.core.tests.util.AbstractCompilerTest; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; @@ -101,6 +102,7 @@ // Build final test suite TestSuite all = new TestSuite(TestAll.class.getName()); + all.addTest(new TestSuite(StandAloneASTParserTest.class)); int possibleComplianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); if ((possibleComplianceLevels & AbstractCompilerTest.F_1_3) != 0) { ArrayList tests_1_3 = (ArrayList)standardTests.clone(); Index: src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java =================================================================== RCS file: src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java diff -N src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jdt/core/tests/dom/StandAloneASTParserTest.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (c) 2010 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.dom; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.List; + +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.FileASTRequestor; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.VariableDeclarationStatement; +import org.eclipse.jdt.core.tests.compiler.regression.AbstractRegressionTest; + +public class StandAloneASTParserTest extends AbstractRegressionTest { + public StandAloneASTParserTest(String name) { + super(name); + } + public ASTNode runConversion( + int astLevel, + String source, + boolean resolveBindings, + boolean statementsRecovery, + boolean bindingsRecovery, + String unitName) { + + ASTParser parser = ASTParser.newParser(astLevel); + parser.setSource(source.toCharArray()); + parser.setEnvironment(null, null, null, true); + parser.setResolveBindings(resolveBindings); + parser.setStatementsRecovery(statementsRecovery); + parser.setBindingsRecovery(bindingsRecovery); + parser.setCompilerOptions(getCompilerOptions()); + parser.setUnitName(unitName); + return parser.createAST(null); + } + public void test1() { + String contents = + "package p;\n" + + "public class X {\n" + + " public int i;\n" + + " public static void main(String[] args) {\n" + + " int length = args.length;\n" + + " System.out.println(length);\n" + + " }\n" + + "}"; + ASTNode node = runConversion(AST.JLS3, contents, true, true, true, "p/X.java"); + assertTrue("Should be a compilation unit", node instanceof CompilationUnit); + CompilationUnit unit = (CompilationUnit) node; + List types = unit.types(); + TypeDeclaration typeDeclaration = (TypeDeclaration) types.get(0); + ITypeBinding binding = typeDeclaration.resolveBinding(); + assertNotNull("No binding", binding); + assertNull("Got a java element", binding.getJavaElement()); + assertEquals("Wrong name", "p.X", binding.getQualifiedName()); + MethodDeclaration methodDeclaration = (MethodDeclaration) typeDeclaration.bodyDeclarations().get(1); + IMethodBinding methodBinding = methodDeclaration.resolveBinding(); + assertNotNull("No binding", methodBinding); + assertNull("Got a java element", methodBinding.getJavaElement()); + Block body = methodDeclaration.getBody(); + VariableDeclarationStatement statement = (VariableDeclarationStatement) body.statements().get(0); + VariableDeclarationFragment fragment = (VariableDeclarationFragment) statement.fragments().get(0); + IVariableBinding variableBinding = fragment.resolveBinding(); + assertNotNull("No binding", variableBinding); + assertNull("Got a java element", variableBinding.getJavaElement()); + ExpressionStatement statement2 = (ExpressionStatement) body.statements().get(1); + Expression expression = statement2.getExpression(); + MethodInvocation invocation = (MethodInvocation) expression; + Expression expression2 = invocation.getExpression(); + assertNotNull("No binding", expression2.resolveTypeBinding()); + + FieldDeclaration fieldDeclaration = (FieldDeclaration) typeDeclaration.bodyDeclarations().get(0); + VariableDeclarationFragment fragment2 = (VariableDeclarationFragment) fieldDeclaration.fragments().get(0); + IVariableBinding variableBinding2 = fragment2.resolveBinding(); + assertNotNull("No binding", variableBinding2); + assertNull("Got a java element", variableBinding2.getJavaElement()); + } + + public void test2() { + ASTParser parser = ASTParser.newParser(AST.JLS3); + parser.setEnvironment(null, null, null, true); + parser.setResolveBindings(true); + parser.setStatementsRecovery(true); + parser.setBindingsRecovery(true); + parser.setCompilerOptions(getCompilerOptions()); + + final String key = "Ljava/lang/String;"; + final IBinding[] bindings = new IBinding[1]; + + FileASTRequestor requestor = new FileASTRequestor() { + public void acceptBinding(String bindingKey, IBinding binding) { + if (key.equals(bindingKey)) { + bindings[0] = binding; + } + } + }; + + parser.createASTs(new String[] {}, null, new String[] {key}, requestor, null); + + assertNotNull("No binding", bindings[0]); + assertEquals("Wrong type of binding", IBinding.TYPE, bindings[0].getKind()); + ITypeBinding typeBinding = (ITypeBinding) bindings[0]; + assertEquals("Wrong binding", "java.lang.String", typeBinding.getQualifiedName()); + assertNull("No java element", typeBinding.getJavaElement()); + } + + public void test3() throws IOException { + File rootDir = new File(System.getProperty("java.io.tmpdir")); + ASTParser parser = ASTParser.newParser(AST.JLS3); + parser.setEnvironment(null, null, null, true); + parser.setResolveBindings(true); + parser.setStatementsRecovery(true); + parser.setBindingsRecovery(true); + parser.setCompilerOptions(getCompilerOptions()); + + final String key = "Lp/X;"; + final IBinding[] bindings = new IBinding[1]; + + String contents = + "package p;\n" + + "public class X extends Y {\n" + + " public int i;\n" + + " public static void main(String[] args) {\n" + + " int length = args.length;\n" + + " System.out.println(length);\n" + + " }\n" + + "}"; + + File packageDir = new File(rootDir, "p"); + File file = new File(packageDir, "X.java"); + Writer writer = null; + try { + writer = new BufferedWriter(new FileWriter(file)); + writer.write(contents); + } finally { + if (writer != null) { + try { + writer.close(); + } catch(IOException e) { + // ignore + } + } + } + + String contents2 = + "package p;\n" + + "public class Y {}"; + File fileY = new File(packageDir, "Y.java"); + Writer writer2 = null; + try { + writer2 = new BufferedWriter(new FileWriter(fileY)); + writer2.write(contents2); + } finally { + if (writer2 != null) { + try { + writer2.close(); + } catch(IOException e) { + // ignore + } + } + } + + final String canonicalPath = file.getCanonicalPath(); + final CompilationUnit[] units = new CompilationUnit[1]; + + FileASTRequestor requestor = new FileASTRequestor() { + public void acceptBinding(String bindingKey, IBinding binding) { + if (key.equals(bindingKey)) { + bindings[0] = binding; + } + } + public void acceptAST(String sourceFilePath, CompilationUnit ast) { + if (canonicalPath.equals(sourceFilePath)) { + units[0] = ast; + } + } + }; + + parser.setEnvironment(null, new String[] { rootDir.getCanonicalPath() }, null, true); + + parser.createASTs(new String[] {canonicalPath}, null, new String[] {key}, requestor, null); + + assertNotNull("No binding", bindings[0]); + assertEquals("Wrong type of binding", IBinding.TYPE, bindings[0].getKind()); + ITypeBinding typeBinding = (ITypeBinding) bindings[0]; + assertEquals("Wrong binding", "p.X", typeBinding.getQualifiedName()); + assertNull("No java element", typeBinding.getJavaElement()); + assertNotNull("No ast", units[0]); + assertEquals("No problem", 0, units[0].getProblems().length); + } + + public void test4() { + ASTParser parser = ASTParser.newParser(AST.JLS3); + try { + parser.setEnvironment(null, null, new String[] {"UTF-8"}, true); + assertTrue("Should have failed", false); + } catch(IllegalArgumentException e) { + // ignore + } + } + + public void test5() { + ASTParser parser = ASTParser.newParser(AST.JLS3); + try { + parser.setEnvironment(null, new String[] {}, new String[] {"UTF-8"}, true); + assertTrue("Should have failed", false); + } catch(IllegalArgumentException e) { + // ignore + } + } +}