/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
Java | 287 lines | 174 code | 25 blank | 88 comment | 62 complexity | 710ec9e03db2e07f087a1d0535e35aa7 MD5 | raw file
- /*******************************************************************************
- * Copyright (c) 2012-2015 Codenvy, S.A.
- * 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:
- * Codenvy, S.A. - initial API and implementation
- *******************************************************************************/
- package org.eclipse.jdt.internal.core;
- import org.eclipse.jdt.core.ICompilationUnit;
- import org.eclipse.jdt.core.IJavaElement;
- import org.eclipse.jdt.core.IJavaModelStatus;
- import org.eclipse.jdt.core.IJavaModelStatusConstants;
- import org.eclipse.jdt.core.IProblemRequestor;
- import org.eclipse.jdt.core.JavaModelException;
- import org.eclipse.jdt.core.WorkingCopyOwner;
- import org.eclipse.jdt.core.compiler.CategorizedProblem;
- import org.eclipse.jdt.core.dom.CheAST;
- import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
- import org.eclipse.jdt.internal.core.util.Messages;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- /**
- * Reconcile a working copy and signal the changes through a delta.
- * <p/>
- * High level summmary of what a reconcile does:
- * <ul>
- * <li>populates the model with the new working copy contents</li>
- * <li>fires a fine grained delta (flag F_FINE_GRAINED) describing the difference between the previous content
- * and the new content (which method was added/removed, which field was changed, etc.)</li>
- * <li>computes problems and reports them to the IProblemRequestor (begingReporting(), n x acceptProblem(...), endReporting()) iff
- * (working copy is not consistent with its buffer || forceProblemDetection is set)
- * && problem requestor is active
- * </li>
- * <li>produces a DOM AST (either JLS_2, JLS_3 or NO_AST) that is resolved if flag is set</li>
- * <li>notifies compilation participants of the reconcile allowing them to participate in this operation and report problems</li>
- * </ul>
- */
- @SuppressWarnings({"rawtypes"})
- public class ReconcileWorkingCopyOperation extends JavaModelOperation {
- public static boolean PERF = false;
- public int astLevel;
- public boolean resolveBindings;
- public HashMap problems;
- public int reconcileFlags;
- public org.eclipse.jdt.core.dom.CompilationUnit ast;
- public JavaElementDeltaBuilder deltaBuilder;
- public boolean requestorIsActive;
- WorkingCopyOwner workingCopyOwner;
- public ReconcileWorkingCopyOperation(IJavaElement workingCopy, int astLevel, int reconcileFlags, WorkingCopyOwner workingCopyOwner
- ) {
- super(new IJavaElement[]{workingCopy});
- this.astLevel = astLevel;
- this.reconcileFlags = reconcileFlags;
- this.workingCopyOwner = workingCopyOwner;
- }
- /**
- * @throws org.eclipse.jdt.core.JavaModelException
- * if setting the source
- * of the original compilation unit fails
- */
- protected void executeOperation() throws JavaModelException {
- checkCanceled();
- try {
- beginTask(Messages.element_reconciling, 2);
- CompilationUnit workingCopy = getWorkingCopy();
- boolean wasConsistent = workingCopy.isConsistent();
- // check is problem requestor is active
- IProblemRequestor problemRequestor = workingCopy.getPerWorkingCopyInfo();
- if (problemRequestor != null)
- problemRequestor = ((JavaModelManager.PerWorkingCopyInfo)problemRequestor).getProblemRequestor();
- boolean defaultRequestorIsActive = problemRequestor != null && problemRequestor.isActive();
- IProblemRequestor ownerProblemRequestor = this.workingCopyOwner.getProblemRequestor(workingCopy);
- boolean ownerRequestorIsActive =
- ownerProblemRequestor != null && ownerProblemRequestor != problemRequestor && ownerProblemRequestor.isActive();
- this.requestorIsActive = defaultRequestorIsActive || ownerRequestorIsActive;
- // create the delta builder (this remembers the current content of the cu)
- this.deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
- // make working copy consistent if needed and compute AST if needed
- makeConsistent(workingCopy);
- // notify reconcile participants only if working copy was not consistent or if forcing problem detection
- // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=177319)
- if (!wasConsistent || ((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0)) {
- notifyParticipants(workingCopy);
- // recreate ast if one participant reset it
- if (this.ast == null)
- makeConsistent(workingCopy);
- }
- // report problems
- if (this.problems != null && (((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) || !wasConsistent)) {
- if (defaultRequestorIsActive) {
- reportProblems(workingCopy, problemRequestor);
- }
- if (ownerRequestorIsActive) {
- reportProblems(workingCopy, ownerProblemRequestor);
- }
- }
- // report delta
- JavaElementDelta delta = this.deltaBuilder.delta;
- if (delta != null) {
- addReconcileDelta(workingCopy, delta);
- }
- } finally {
- done();
- }
- }
- /**
- * Report working copy problems to a given requestor.
- *
- * @param workingCopy
- * @param problemRequestor
- */
- private void reportProblems(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
- try {
- problemRequestor.beginReporting();
- for (Iterator iteraror = this.problems.values().iterator(); iteraror.hasNext(); ) {
- CategorizedProblem[] categorizedProblems = (CategorizedProblem[])iteraror.next();
- if (categorizedProblems == null) continue;
- for (int i = 0, length = categorizedProblems.length; i < length; i++) {
- CategorizedProblem problem = categorizedProblems[i];
- if (JavaModelManager.VERBOSE) {
- System.out.println("PROBLEM FOUND while reconciling : " + problem.getMessage());//$NON-NLS-1$
- }
- if (this.progressMonitor != null && this.progressMonitor.isCanceled()) break;
- problemRequestor.acceptProblem(problem);
- }
- }
- } finally {
- problemRequestor.endReporting();
- }
- }
- /**
- * Returns the working copy this operation is working on.
- */
- protected CompilationUnit getWorkingCopy() {
- return (CompilationUnit)getElementToProcess();
- }
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.core.JavaModelOperation#isReadOnly()
- */
- public boolean isReadOnly() {
- return true;
- }
- /*
- * Makes the given working copy consistent, computes the delta and computes an AST if needed.
- * Returns the AST.
- */
- public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(CompilationUnit workingCopy) throws JavaModelException {
- if (!workingCopy.isConsistent()) {
- // make working copy consistent
- if (this.problems == null) this.problems = new HashMap();
- this.resolveBindings = this.requestorIsActive;
- this.ast = workingCopy
- .makeConsistent(this.astLevel, this.resolveBindings, this.reconcileFlags, this.problems, this.progressMonitor);
- this.deltaBuilder.buildDeltas();
- if (this.ast != null && this.deltaBuilder.delta != null)
- this.deltaBuilder.delta.changedAST(this.ast);
- return this.ast;
- }
- if (this.ast != null)
- return this.ast; // no need to recompute AST if known already
- CompilationUnitDeclaration unit = null;
- try {
- JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE);
- CompilationUnit source = workingCopy.cloneCachingContents();
- // find problems if needed
- if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject())
- && (this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) {
- this.resolveBindings = this.requestorIsActive;
- if (this.problems == null)
- this.problems = new HashMap();
- unit =
- CompilationUnitProblemFinder.process(
- source,
- this.workingCopyOwner,
- this.problems,
- this.astLevel != ICompilationUnit.NO_AST/*creating AST if level is not NO_AST */,
- this.reconcileFlags,
- this.progressMonitor);
- if (this.progressMonitor != null) this.progressMonitor.worked(1);
- }
- // create AST if needed
- if (this.astLevel != ICompilationUnit.NO_AST
- && unit !=
- null/*unit is null if working copy is consistent && (problem detection not forced || non-Java project) -> don't create
- AST as per API*/) {
- Map options = workingCopy.getJavaProject().getOptions(true);
- // convert AST
- this.ast =
- CheAST.convertCompilationUnit(
- this.astLevel,
- unit,
- options,
- this.resolveBindings,
- source,
- this.reconcileFlags,
- this.progressMonitor);
- if (this.ast != null) {
- if (this.deltaBuilder.delta == null) {
- this.deltaBuilder.delta = new JavaElementDelta(workingCopy);
- }
- this.deltaBuilder.delta.changedAST(this.ast);
- }
- if (this.progressMonitor != null) this.progressMonitor.worked(1);
- }
- } catch (JavaModelException e) {
- if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject()))
- throw e;
- // else JavaProject has lost its nature (or most likely was closed/deleted) while reconciling -> ignore
- // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=100919)
- } finally {
- JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null);
- if (unit != null) {
- unit.cleanUp();
- }
- }
- return this.ast;
- }
- private void notifyParticipants(final CompilationUnit workingCopy) {
- // IJavaProject javaProject = getWorkingCopy().getJavaProject();
- // CompilationParticipant[] participants = manager.compilationParticipants.getCompilationParticipants
- // (javaProject);
- // if (participants == null) return;
- //
- // final ReconcileContext context = new ReconcileContext(this, workingCopy);
- // for (int i = 0, length = participants.length; i < length; i++) {
- // final CompilationParticipant participant = participants[i];
- // SafeRunner.run(new ISafeRunnable() {
- // public void handleException(Throwable exception) {
- // if (exception instanceof Error) {
- // throw (Error)exception; // errors are not supposed to be caught
- // } else if (exception instanceof OperationCanceledException)
- // throw (OperationCanceledException)exception;
- // else if (exception instanceof UnsupportedOperationException) {
- // // might want to disable participant as it tried to modify the buffer of the working copy being reconciled
- // Util.log(exception,
- // "Reconcile participant attempted to modify the buffer of the working copy being reconciled"); //$NON-NLS-1$
- // } else
- // Util.log(exception, "Exception occurred in reconcile participant"); //$NON-NLS-1$
- // }
- //
- // public void run() throws Exception {
- // participant.reconcile(context);
- // }
- // });
- // }
- }
- protected IJavaModelStatus verify() {
- IJavaModelStatus status = super.verify();
- if (!status.isOK()) {
- return status;
- }
- CompilationUnit workingCopy = getWorkingCopy();
- if (!workingCopy.isWorkingCopy()) {
- return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy); //was destroyed
- }
- return status;
- }
- }