| /******************************************************************************* |
| * Copyright (c) 2005, 2013 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: |
| * mkaufman@bea.com - initial API and implementation |
| * IBM - renamed from PreReconcileCompilationResult to ReconcileContext |
| * IBM - rewrote spec |
| * |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.core.compiler; |
| |
| import java.util.HashMap; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElementDelta; |
| import org.eclipse.jdt.core.IJavaModelMarker; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTParser; |
| import org.eclipse.jdt.internal.core.CompilationUnit; |
| import org.eclipse.jdt.internal.core.JavaProject; |
| import org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation; |
| |
| /** |
| * The context of a reconcile event that is notified to interested compilation |
| * participants while a reconcile operation is running. |
| * <p> |
| * A reconcile participant can get the AST for the reconcile-operation using |
| * {@link #getAST4()}. If the participant modifies in any way the AST |
| * (either by modifying the source of the working copy, or modifying another entity |
| * that would result in different bindings for the AST), it is expected to reset the |
| * AST in the context using {@link #resetAST()}. |
| * </p><p> |
| * A reconcile participant can also create and return problems using |
| * {@link #putProblems(String, CategorizedProblem[])}. These problems are then reported |
| * to the problem requestor of the reconcile operation. |
| * </p> |
| * |
| * @see CompilationParticipant#reconcile(ReconcileContext) |
| * @since 3.2 |
| * @noinstantiate This class is not intended to be instantiated by clients. |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class ReconcileContext { |
| |
| private ReconcileWorkingCopyOperation operation; |
| private CompilationUnit workingCopy; |
| |
| /** |
| * Creates a reconcile context for the given reconcile operation. |
| * |
| * @param operation the reconcile operation |
| * @noreference This constructor is not intended to be called by clients. |
| */ |
| public ReconcileContext(ReconcileWorkingCopyOperation operation, CompilationUnit workingCopy) { |
| this.operation = operation; |
| this.workingCopy = workingCopy; |
| } |
| |
| /** |
| * Returns a resolved AST with {@link AST#JLS3 JLS3} level. |
| * It is created from the current state of the working copy. |
| * Creates one if none exists yet. |
| * Returns <code>null</code> if the current state of the working copy |
| * doesn't allow the AST to be created (e.g. if the working copy's content |
| * cannot be parsed). |
| * <p> |
| * If the AST level requested during reconciling is not {@link AST#JLS3} |
| * or if binding resolutions was not requested, then a different AST is created. |
| * Note that this AST does not become the current AST and it is only valid for |
| * the requestor. |
| * </p> |
| * |
| * @return the AST created from the current state of the working copy, |
| * or <code>null</code> if none could be created |
| * @exception JavaModelException if the contents of the working copy |
| * cannot be accessed. Reasons include: |
| * <ul> |
| * <li> The working copy does not exist (ELEMENT_DOES_NOT_EXIST)</li> |
| * </ul> |
| * @deprecated JLS3 has been deprecated. This method has been replaced by {@link #getAST4()} which returns an AST |
| * with JLS4 level. |
| */ |
| public org.eclipse.jdt.core.dom.CompilationUnit getAST3() throws JavaModelException { |
| if (this.operation.astLevel != AST.JLS3 || !this.operation.resolveBindings) { |
| // create AST (optionally resolving bindings) |
| ASTParser parser = ASTParser.newParser(AST.JLS3); |
| parser.setCompilerOptions(this.workingCopy.getJavaProject().getOptions(true)); |
| if (JavaProject.hasJavaNature(this.workingCopy.getJavaProject().getProject())) |
| parser.setResolveBindings(true); |
| parser.setStatementsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); |
| parser.setBindingsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0); |
| parser.setSource(this.workingCopy); |
| parser.setIgnoreMethodBodies((this.operation.reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0); |
| return (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(this.operation.progressMonitor); |
| } |
| return this.operation.makeConsistent(this.workingCopy); |
| } |
| /** |
| * Returns a resolved AST with {@link AST#JLS4 JLS4} level. |
| * It is created from the current state of the working copy. |
| * Creates one if none exists yet. |
| * Returns <code>null</code> if the current state of the working copy |
| * doesn't allow the AST to be created (e.g. if the working copy's content |
| * cannot be parsed). |
| * <p> |
| * If the AST level requested during reconciling is not {@link AST#JLS4} |
| * or if binding resolutions was not requested, then a different AST is created. |
| * Note that this AST does not become the current AST and it is only valid for |
| * the requestor. |
| * </p> |
| * |
| * @return the AST created from the current state of the working copy, |
| * or <code>null</code> if none could be created |
| * @exception JavaModelException if the contents of the working copy |
| * cannot be accessed. Reasons include: |
| * <ul> |
| * <li> The working copy does not exist (ELEMENT_DOES_NOT_EXIST)</li> |
| * </ul> |
| * @deprecated JLS4 has been deprecated. This method has been replaced by {@link #getAST8()} which returns an AST |
| * with JLS8 level. |
| * @since 3.7.1 |
| */ |
| public org.eclipse.jdt.core.dom.CompilationUnit getAST4() throws JavaModelException { |
| if (this.operation.astLevel != AST.JLS4 || !this.operation.resolveBindings) { |
| // create AST (optionally resolving bindings) |
| ASTParser parser = ASTParser.newParser(AST.JLS4); |
| parser.setCompilerOptions(this.workingCopy.getJavaProject().getOptions(true)); |
| if (JavaProject.hasJavaNature(this.workingCopy.getJavaProject().getProject())) |
| parser.setResolveBindings(true); |
| parser.setStatementsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); |
| parser.setBindingsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0); |
| parser.setSource(this.workingCopy); |
| parser.setIgnoreMethodBodies((this.operation.reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0); |
| return (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(this.operation.progressMonitor); |
| } |
| return this.operation.makeConsistent(this.workingCopy); |
| } |
| /** |
| * Returns a resolved AST with {@link AST#JLS8 JLS8} level. |
| * It is created from the current state of the working copy. |
| * Creates one if none exists yet. |
| * Returns <code>null</code> if the current state of the working copy |
| * doesn't allow the AST to be created (e.g. if the working copy's content |
| * cannot be parsed). |
| * <p> |
| * If the AST level requested during reconciling is not {@link AST#JLS8} |
| * or if binding resolutions was not requested, then a different AST is created. |
| * Note that this AST does not become the current AST and it is only valid for |
| * the requestor. |
| * </p> |
| * |
| * @return the AST created from the current state of the working copy, |
| * or <code>null</code> if none could be created |
| * @exception JavaModelException if the contents of the working copy |
| * cannot be accessed. Reasons include: |
| * <ul> |
| * <li> The working copy does not exist (ELEMENT_DOES_NOT_EXIST)</li> |
| * </ul> |
| * @since 3.9 BETA_JAVA8 |
| */ |
| public org.eclipse.jdt.core.dom.CompilationUnit getAST8() throws JavaModelException { |
| if (this.operation.astLevel != AST.JLS8 || !this.operation.resolveBindings) { |
| // create AST (optionally resolving bindings) |
| ASTParser parser = ASTParser.newParser(AST.JLS8); |
| parser.setCompilerOptions(this.workingCopy.getJavaProject().getOptions(true)); |
| if (JavaProject.hasJavaNature(this.workingCopy.getJavaProject().getProject())) |
| parser.setResolveBindings(true); |
| parser.setStatementsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); |
| parser.setBindingsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0); |
| parser.setSource(this.workingCopy); |
| parser.setIgnoreMethodBodies((this.operation.reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0); |
| return (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(this.operation.progressMonitor); |
| } |
| return this.operation.makeConsistent(this.workingCopy); |
| } |
| |
| /** |
| * Returns the AST level requested by the reconcile operation. |
| * It is either {@link ICompilationUnit#NO_AST}, or one of the JLS constants defined on {@link AST}. |
| * |
| * @return the AST level requested by the reconcile operation |
| */ |
| public int getASTLevel() { |
| return this.operation.astLevel; |
| } |
| |
| /** |
| * Returns whether the reconcile operation is resolving bindings. |
| * |
| * @return whether the reconcile operation is resolving bindings |
| */ |
| public boolean isResolvingBindings() { |
| return this.operation.resolveBindings; |
| } |
| /** |
| * Returns the reconcile flag of this context. This flag is a bitwise value of the constant defined |
| * in {@link ICompilationUnit}. |
| * |
| * @return the reconcile flag of this context |
| * @since 3.6 |
| * |
| * @see ICompilationUnit#ENABLE_BINDINGS_RECOVERY |
| * @see ICompilationUnit#ENABLE_STATEMENTS_RECOVERY |
| * @see ICompilationUnit#IGNORE_METHOD_BODIES |
| */ |
| public int getReconcileFlags() { |
| return this.operation.reconcileFlags; |
| } |
| /** |
| * Returns the delta describing the change to the working copy being reconciled. |
| * Returns <code>null</code> if there is no change. |
| * Note that the delta's AST is not yet positioned at this stage. Use {@link #getAST4()} |
| * to get the current AST. |
| * |
| * @return the delta describing the change, or <code>null</code> if none |
| */ |
| public IJavaElementDelta getDelta() { |
| return this.operation.deltaBuilder.delta; |
| } |
| |
| /** |
| * Returns the problems to be reported to the problem requestor of the reconcile operation |
| * for the given marker type. |
| * Returns <code>null</code> if no problems need to be reported for this marker type. |
| * |
| * @param markerType the given marker type |
| * @return problems to be reported to the problem requestor |
| */ |
| public CategorizedProblem[] getProblems(String markerType) { |
| if (this.operation.problems == null) return null; |
| return (CategorizedProblem[]) this.operation.problems.get(markerType); |
| } |
| |
| /** |
| * Returns the working copy this context refers to. |
| * |
| * @return the working copy this context refers to |
| */ |
| public ICompilationUnit getWorkingCopy() { |
| return this.workingCopy; |
| } |
| |
| /** |
| * Resets the AST carried by this context. |
| * A compilation participant that modifies the environment that would result in different |
| * bindings for the AST is expected to reset the AST on this context, so that other |
| * participants don't get a stale AST. |
| * <p> |
| * Note that resetting the AST will not restart the reconcile process. Only further |
| * participants will see the new AST. Thus participants running before the one that |
| * resets the AST will have a stale view of the AST and its problems. Use |
| * the compilation participant extension point to order the participants. |
| * </p> |
| */ |
| public void resetAST() { |
| this.operation.ast = null; |
| putProblems(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, null); |
| putProblems(IJavaModelMarker.TASK_MARKER, null); |
| } |
| |
| /** |
| * Sets the problems to be reported to the problem requestor of the reconcile operation |
| * for the given marker type. |
| * <code>null</code> indicates that no problems need to be reported. |
| * <p> |
| * Using this functionality, a participant that resolves problems for a given marker type |
| * can hide those problems since they don't exist any longer. |
| * </p> |
| * |
| * @param markerType the marker type of the given problems |
| * @param problems the problems to be reported to the problem requestor of the reconcile operation, |
| * or <code>null</code> if none |
| */ |
| public void putProblems(String markerType, CategorizedProblem[] problems) { |
| if (this.operation.problems == null) |
| this.operation.problems = new HashMap(); |
| this.operation.problems.put(markerType, problems); |
| } |
| |
| } |