Skip to content

Commit

Permalink
Creation of extension point to swap out CompilationUnitResolver imple…
Browse files Browse the repository at this point in the history
…mentations

Signed-off-by: Rob Stryker <[email protected]>

exsd cleanup

Signed-off-by: Rob Stryker <[email protected]>

Cleanup

Signed-off-by: Rob Stryker <[email protected]>

Javadoc for added interface

Signed-off-by: Rob Stryker <[email protected]>

More docs
  • Loading branch information
Rob Stryker committed Jun 12, 2024
1 parent fb7c13b commit 20af383
Show file tree
Hide file tree
Showing 7 changed files with 417 additions and 60 deletions.
84 changes: 24 additions & 60 deletions org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
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.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
Expand Down Expand Up @@ -221,6 +220,8 @@ public static ASTParser newParser(int level) {
*/
private int bits;

private final ICompilationUnitResolver unitResolver;

/**
* Creates a new AST parser for the given API level.
* <p>
Expand All @@ -233,6 +234,7 @@ public static ASTParser newParser(int level) {
ASTParser(int level) {
DOMASTUtil.checkASTLevel(level);
this.apiLevel = level;
this.unitResolver = CompilationUnitResolverDiscovery.getInstance();
initializeDefaults();
}

Expand All @@ -245,10 +247,13 @@ private List<Classpath> getClasspath() throws IllegalStateException {
}
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);
String sourcePath = this.sourcepaths[i];
if (sourcePath != null) {
String encoding = this.sourcepathsEncodings == null ? null : this.sourcepathsEncodings[i];
main.processPathEntries(
Main.DEFAULT_SIZE_CLASSPATH,
allClasspaths, sourcePath, encoding, true, false);
}
}
}
if (this.classpaths != null) {
Expand Down Expand Up @@ -957,9 +962,9 @@ public void createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys
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);
this.unitResolver.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);
this.unitResolver.parse(compilationUnits, requestor, this.apiLevel, this.compilerOptions, flags, monitor);
}
} finally {
// reset to defaults to allow reuse (and avoid leaking)
Expand Down Expand Up @@ -1052,9 +1057,9 @@ public void createASTs(String[] sourceFilePaths, String[] encodings, String[] bi
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);
this.unitResolver.resolve(sourceFilePaths, encodings, bindingKeys, requestor, this.apiLevel, this.compilerOptions, getClasspath(), flags, monitor);
} else {
CompilationUnitResolver.parse(sourceFilePaths, encodings, requestor, this.apiLevel, this.compilerOptions, flags, monitor);
this.unitResolver.parse(sourceFilePaths, encodings, requestor, this.apiLevel, this.compilerOptions, flags, monitor);
}
} finally {
// reset to defaults to allow reuse (and avoid leaking)
Expand Down Expand Up @@ -1159,9 +1164,8 @@ private ASTNode internalCreateASTCached(IProgressMonitor monitor) {
}
break;
case K_COMPILATION_UNIT :
CompilationUnitDeclaration compilationUnitDeclaration = null;
try {
NodeSearcher searcher = null;
boolean useSearcher = false;
org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = null;
WorkingCopyOwner wcOwner = this.workingCopyOwner;
if (this.typeRoot instanceof ClassFileWorkingCopy) {
Expand Down Expand Up @@ -1229,68 +1233,28 @@ private ASTNode internalCreateASTCached(IProgressMonitor monitor) {
throw new IllegalStateException();
}
if ((this.bits & CompilationUnitResolver.PARTIAL) != 0) {
searcher = new NodeSearcher(this.focalPointPosition);
useSearcher = true;
}
int flags = 0;
if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) {
flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
}
if (searcher == null && ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0)) {
if (!useSearcher && ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0)) {
flags |= ICompilationUnit.IGNORE_METHOD_BODIES;
}

if (needToResolveBindings) {
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,
flags,
monitor);
} catch (JavaModelException e) {
flags &= ~ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
compilationUnitDeclaration = CompilationUnitResolver.parse(
sourceUnit,
searcher,
this.compilerOptions,
flags);
needToResolveBindings = false;
}
} else {
compilationUnitDeclaration = CompilationUnitResolver.parse(
sourceUnit,
searcher,
this.compilerOptions,
flags,
this.project);
needToResolveBindings = false;
}
CompilationUnit result = CompilationUnitResolver.convert(
compilationUnitDeclaration,
sourceUnit.getContents(),
this.apiLevel,
this.compilerOptions,
needToResolveBindings,
wcOwner,
needToResolveBindings ? new DefaultBindingResolver.BindingTables() : null,
flags,
monitor,
this.project != null,
this.project);
result.setTypeRoot(this.typeRoot);
return result;

CompilationUnit result2 = this.unitResolver.toCompilationUnit(sourceUnit, needToResolveBindings, this.project, getClasspath(), useSearcher ? this.focalPointPosition : -1, this.apiLevel, this.compilerOptions, this.workingCopyOwner, wcOwner, flags, monitor);
result2.setTypeRoot(this.typeRoot);
return result2;
} finally {
if (compilationUnitDeclaration != null
&& ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0)) {
compilationUnitDeclaration.cleanUp();
}
// unitResolver should already handle this.
// Leaving this finally in place to avoid changing indentation
}
}
throw new IllegalStateException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,45 @@

@SuppressWarnings({ "rawtypes", "unchecked" })
class CompilationUnitResolver extends Compiler {

private static final class ECJCompilationUnitResolver implements ICompilationUnitResolver {

@Override
public void resolve(String[] sourceFilePaths, String[] encodings, String[] bindingKeys,
FileASTRequestor requestor, int apiLevel, Map<String, String> compilerOptions, List<Classpath> classpath,
int flags, IProgressMonitor monitor) {
CompilationUnitResolver.resolve(sourceFilePaths, encodings, bindingKeys, requestor, apiLevel, compilerOptions, classpath, flags, monitor);
}

@Override
public void parse(ICompilationUnit[] compilationUnits, ASTRequestor requestor, int apiLevel,
Map<String, String> compilerOptions, int flags, IProgressMonitor monitor) {
CompilationUnitResolver.parse(compilationUnits, requestor, apiLevel, compilerOptions, flags, monitor);
}

@Override
public void parse(String[] sourceFilePaths, String[] encodings, FileASTRequestor requestor, int apiLevel,
Map<String, String> compilerOptions, int flags, IProgressMonitor monitor) {
CompilationUnitResolver.parse(sourceFilePaths, encodings, requestor, apiLevel, compilerOptions, flags, monitor);
}

@Override
public void resolve(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor,
int apiLevel, Map<String, String> compilerOptions, IJavaProject project,
WorkingCopyOwner workingCopyOwner, int flags, IProgressMonitor monitor) {
CompilationUnitResolver.resolve(compilationUnits, bindingKeys, requestor, apiLevel, compilerOptions, project, workingCopyOwner, flags, monitor);
}

@Override
public CompilationUnit toCompilationUnit(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, final boolean initialNeedsToResolveBinding, IJavaProject project, List<Classpath> classpaths, int focalPosition,
int apiLevel, Map<String, String> compilerOptions, WorkingCopyOwner parsedUnitWorkingCopyOwner, WorkingCopyOwner typeRootWorkingCopyOwner, int flags, IProgressMonitor monitor) {
return CompilationUnitResolver.toCompilationUnit(sourceUnit, initialNeedsToResolveBinding, project,
classpaths, focalPosition == -1 ? null : new NodeSearcher(focalPosition), apiLevel, compilerOptions, parsedUnitWorkingCopyOwner, typeRootWorkingCopyOwner, flags, monitor);
}
}

public static final ECJCompilationUnitResolver FACADE = new ECJCompilationUnitResolver();

public static final int RESOLVE_BINDING = 0x1;
public static final int PARTIAL = 0x2;
public static final int STATEMENT_RECOVERY = 0x4;
Expand Down Expand Up @@ -1408,6 +1447,62 @@ public CompilationUnitDeclaration resolve(
generateCode);
}

public static CompilationUnit toCompilationUnit(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, final boolean initialNeedsToResolveBinding, IJavaProject project, List<Classpath> classpaths, NodeSearcher nodeSearcher,
int apiLevel, Map<String, String> compilerOptions, WorkingCopyOwner parsedUnitWorkingCopyOwner, WorkingCopyOwner typeRootWorkingCopyOwner, int flags, IProgressMonitor monitor) {
// this -> astParser, pass as args
CompilationUnitDeclaration compilationUnitDeclaration = null;
boolean needsToResolveBindingsState = initialNeedsToResolveBinding;
try {
if (initialNeedsToResolveBinding) {
try {
// parse and resolve
compilationUnitDeclaration =
CompilationUnitResolver.resolve(
sourceUnit,
project,
classpaths,
nodeSearcher,
compilerOptions,
parsedUnitWorkingCopyOwner,
flags,
monitor);
} catch (JavaModelException e) {
flags &= ~ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
compilationUnitDeclaration = CompilationUnitResolver.parse(
sourceUnit,
nodeSearcher,
compilerOptions,
flags);
needsToResolveBindingsState = false;
}
} else {
compilationUnitDeclaration = CompilationUnitResolver.parse(
sourceUnit,
nodeSearcher,
compilerOptions,
flags,
project);
needsToResolveBindingsState = false;
}
return CompilationUnitResolver.convert(
compilationUnitDeclaration,
sourceUnit.getContents(),
apiLevel,
compilerOptions,
needsToResolveBindingsState,
typeRootWorkingCopyOwner,
needsToResolveBindingsState ? new DefaultBindingResolver.BindingTables() : null,
flags,
monitor,
project != null,
project);
} finally {
if (compilationUnitDeclaration != null && initialNeedsToResolveBinding) {
compilationUnitDeclaration.cleanUp();
}
}
}

private void worked(int work) {
if (this.monitor != null) {
if (this.monitor.isCanceled())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.jdt.core.dom;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.JavaCore;

class CompilationUnitResolverDiscovery {
private static final String COMPILATION_UNIT_RESOLVER_EXTPOINT_ID = "compilationUnitResolver" ; //$NON-NLS-1$
private static boolean ERROR_LOGGED = false;


@SuppressWarnings("unchecked")
static ICompilationUnitResolver getInstance() {
String compilationUnitResolverId = System.getProperty(ICompilationUnitResolver.class.getSimpleName());
IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, COMPILATION_UNIT_RESOLVER_EXTPOINT_ID);
if (extension != null && compilationUnitResolverId != null && !compilationUnitResolverId.isEmpty()) {
IExtension[] extensions = extension.getExtensions();
for (IExtension ext : extensions) {
IConfigurationElement[] configElements = ext.getConfigurationElements();
for (final IConfigurationElement configElement : configElements) {
String elementId = configElement.getAttribute("id");
if( compilationUnitResolverId.equals(elementId)) {
String elementName =configElement.getName();
if (!("resolver".equals(elementName))) { //$NON-NLS-1$
continue;
}
try {
Object executableExtension = configElement.createExecutableExtension("class");
if( executableExtension instanceof ICompilationUnitResolver icur) {
return icur;
}
} catch (CoreException e) {
e.printStackTrace();
if( !ERROR_LOGGED) {
ILog.get().error("Could not instantiate ICompilationUnitResolver: '" + elementId + "' with class: " + configElement.getAttribute("class"), e); //$NON-NLS-1$
ERROR_LOGGED = true;
}
}
}
}
}
}
return CompilationUnitResolver.FACADE;
}

}
Loading

0 comments on commit 20af383

Please sign in to comment.