diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java index 098f4d9b23b..afd5cc891ee 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java @@ -965,15 +965,23 @@ public void createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) { flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; } - this.unitResolver.resolve(Arrays.copyOf(compilationUnits, compilationUnits.length), Arrays.copyOf(bindingKeys, bindingKeys.length), requestor, this.apiLevel, Collections.unmodifiableMap(this.compilerOptions), this.project, this.workingCopyOwner, flags, monitor); + this.unitResolver.resolve(safeCopyOf(compilationUnits), safeCopyOf(bindingKeys), requestor, this.apiLevel, safeUnmodifiableMap(this.compilerOptions), this.project, this.workingCopyOwner, flags, monitor); } else { - this.unitResolver.parse(Arrays.copyOf(compilationUnits, compilationUnits.length), requestor, this.apiLevel, Collections.unmodifiableMap(this.compilerOptions), flags, monitor); + this.unitResolver.parse(safeCopyOf(compilationUnits), requestor, this.apiLevel, safeUnmodifiableMap(this.compilerOptions), flags, monitor); } } finally { // reset to defaults to allow reuse (and avoid leaking) initializeDefaults(); } } + @SuppressWarnings("unchecked") + private static T[] safeCopyOf(T[] original) { + return original == null ? null : Arrays.copyOf(original, original.length); + } + + private static Map safeUnmodifiableMap(Map m) { + return m == null ? null : Collections.unmodifiableMap(m); + } /** * Creates ASTs for a batch of compilation units. @@ -1060,9 +1068,9 @@ public void createASTs(String[] sourceFilePaths, String[] encodings, String[] bi if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) { flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY; } - this.unitResolver.resolve(Arrays.copyOf(sourceFilePaths, sourceFilePaths.length), Arrays.copyOf(encodings, encodings.length), Arrays.copyOf(bindingKeys, bindingKeys.length), requestor, this.apiLevel, Collections.unmodifiableMap(this.compilerOptions), getClasspath(), flags, monitor); + this.unitResolver.resolve(safeCopyOf(sourceFilePaths), safeCopyOf(encodings), safeCopyOf(bindingKeys), requestor, this.apiLevel, safeUnmodifiableMap(this.compilerOptions), getClasspath(), flags, monitor); } else { - this.unitResolver.parse(Arrays.copyOf(sourceFilePaths, sourceFilePaths.length), Arrays.copyOf(encodings, encodings.length), requestor, this.apiLevel, Collections.unmodifiableMap(this.compilerOptions), flags, monitor); + this.unitResolver.parse(safeCopyOf(sourceFilePaths), safeCopyOf(encodings), requestor, this.apiLevel, safeUnmodifiableMap(this.compilerOptions), flags, monitor); } } finally { // reset to defaults to allow reuse (and avoid leaking) @@ -1252,7 +1260,7 @@ private ASTNode internalCreateASTCached(IProgressMonitor monitor) { } } - CompilationUnit result2 = this.unitResolver.toCompilationUnit(sourceUnit, needToResolveBindings, this.project, getClasspath(), useSearcher ? this.focalPointPosition : -1, this.apiLevel, Collections.unmodifiableMap(this.compilerOptions), this.workingCopyOwner, wcOwner, flags, monitor); + CompilationUnit result2 = this.unitResolver.toCompilationUnit(sourceUnit, needToResolveBindings, this.project, getClasspath(), useSearcher ? this.focalPointPosition : -1, this.apiLevel, safeUnmodifiableMap(this.compilerOptions), this.workingCopyOwner, wcOwner, flags, monitor); result2.setTypeRoot(this.typeRoot); return result2; } finally {