PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.jdt.core.source_3.7.1.v_B76_R37x/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 275 lines | 190 code | 24 blank | 61 comment | 70 complexity | 666ede4fcf7d362b9363c2f960e0f0f8 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2008 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.jdt.internal.core;
  12. import java.util.HashMap;
  13. import java.util.Iterator;
  14. import java.util.Map;
  15. import org.eclipse.core.runtime.ISafeRunnable;
  16. import org.eclipse.core.runtime.OperationCanceledException;
  17. import org.eclipse.core.runtime.SafeRunner;
  18. import org.eclipse.jdt.core.*;
  19. import org.eclipse.jdt.core.compiler.CategorizedProblem;
  20. import org.eclipse.jdt.core.compiler.CompilationParticipant;
  21. import org.eclipse.jdt.core.compiler.ReconcileContext;
  22. import org.eclipse.jdt.core.dom.AST;
  23. import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
  24. import org.eclipse.jdt.internal.core.util.Messages;
  25. import org.eclipse.jdt.internal.core.util.Util;
  26. /**
  27. * Reconcile a working copy and signal the changes through a delta.
  28. * <p>
  29. * High level summmary of what a reconcile does:
  30. * <ul>
  31. * <li>populates the model with the new working copy contents</li>
  32. * <li>fires a fine grained delta (flag F_FINE_GRAINED) describing the difference between the previous content
  33. * and the new content (which method was added/removed, which field was changed, etc.)</li>
  34. * <li>computes problems and reports them to the IProblemRequestor (begingReporting(), n x acceptProblem(...), endReporting()) iff
  35. * (working copy is not consistent with its buffer || forceProblemDetection is set)
  36. * && problem requestor is active
  37. * </li>
  38. * <li>produces a DOM AST (either JLS_2, JLS_3 or NO_AST) that is resolved if flag is set</li>
  39. * <li>notifies compilation participants of the reconcile allowing them to participate in this operation and report problems</li>
  40. * </ul>
  41. */
  42. public class ReconcileWorkingCopyOperation extends JavaModelOperation {
  43. public static boolean PERF = false;
  44. public int astLevel;
  45. public boolean resolveBindings;
  46. public HashMap problems;
  47. public int reconcileFlags;
  48. WorkingCopyOwner workingCopyOwner;
  49. public org.eclipse.jdt.core.dom.CompilationUnit ast;
  50. public JavaElementDeltaBuilder deltaBuilder;
  51. public boolean requestorIsActive;
  52. public ReconcileWorkingCopyOperation(IJavaElement workingCopy, int astLevel, int reconcileFlags, WorkingCopyOwner workingCopyOwner) {
  53. super(new IJavaElement[] {workingCopy});
  54. this.astLevel = astLevel;
  55. this.reconcileFlags = reconcileFlags;
  56. this.workingCopyOwner = workingCopyOwner;
  57. }
  58. /**
  59. * @exception JavaModelException if setting the source
  60. * of the original compilation unit fails
  61. */
  62. protected void executeOperation() throws JavaModelException {
  63. checkCanceled();
  64. try {
  65. beginTask(Messages.element_reconciling, 2);
  66. CompilationUnit workingCopy = getWorkingCopy();
  67. boolean wasConsistent = workingCopy.isConsistent();
  68. // check is problem requestor is active
  69. IProblemRequestor problemRequestor = workingCopy.getPerWorkingCopyInfo();
  70. if (problemRequestor != null)
  71. problemRequestor = ((JavaModelManager.PerWorkingCopyInfo)problemRequestor).getProblemRequestor();
  72. boolean defaultRequestorIsActive = problemRequestor != null && problemRequestor.isActive();
  73. IProblemRequestor ownerProblemRequestor = this.workingCopyOwner.getProblemRequestor(workingCopy);
  74. boolean ownerRequestorIsActive = ownerProblemRequestor != null && ownerProblemRequestor != problemRequestor && ownerProblemRequestor.isActive();
  75. this.requestorIsActive = defaultRequestorIsActive || ownerRequestorIsActive;
  76. // create the delta builder (this remembers the current content of the cu)
  77. this.deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
  78. // make working copy consistent if needed and compute AST if needed
  79. makeConsistent(workingCopy);
  80. // notify reconcile participants only if working copy was not consistent or if forcing problem detection
  81. // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=177319)
  82. if (!wasConsistent || ((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0)) {
  83. notifyParticipants(workingCopy);
  84. // recreate ast if one participant reset it
  85. if (this.ast == null)
  86. makeConsistent(workingCopy);
  87. }
  88. // report problems
  89. if (this.problems != null && (((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) || !wasConsistent)) {
  90. if (defaultRequestorIsActive) {
  91. reportProblems(workingCopy, problemRequestor);
  92. }
  93. if (ownerRequestorIsActive) {
  94. reportProblems(workingCopy, ownerProblemRequestor);
  95. }
  96. }
  97. // report delta
  98. JavaElementDelta delta = this.deltaBuilder.delta;
  99. if (delta != null) {
  100. addReconcileDelta(workingCopy, delta);
  101. }
  102. } finally {
  103. done();
  104. }
  105. }
  106. /**
  107. * Report working copy problems to a given requestor.
  108. *
  109. * @param workingCopy
  110. * @param problemRequestor
  111. */
  112. private void reportProblems(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
  113. try {
  114. problemRequestor.beginReporting();
  115. for (Iterator iteraror = this.problems.values().iterator(); iteraror.hasNext();) {
  116. CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror.next();
  117. if (categorizedProblems == null) continue;
  118. for (int i = 0, length = categorizedProblems.length; i < length; i++) {
  119. CategorizedProblem problem = categorizedProblems[i];
  120. if (JavaModelManager.VERBOSE){
  121. System.out.println("PROBLEM FOUND while reconciling : " + problem.getMessage());//$NON-NLS-1$
  122. }
  123. if (this.progressMonitor != null && this.progressMonitor.isCanceled()) break;
  124. problemRequestor.acceptProblem(problem);
  125. }
  126. }
  127. } finally {
  128. problemRequestor.endReporting();
  129. }
  130. }
  131. /**
  132. * Returns the working copy this operation is working on.
  133. */
  134. protected CompilationUnit getWorkingCopy() {
  135. return (CompilationUnit)getElementToProcess();
  136. }
  137. /* (non-Javadoc)
  138. * @see org.eclipse.jdt.internal.core.JavaModelOperation#isReadOnly()
  139. */
  140. public boolean isReadOnly() {
  141. return true;
  142. }
  143. /*
  144. * Makes the given working copy consistent, computes the delta and computes an AST if needed.
  145. * Returns the AST.
  146. */
  147. public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(CompilationUnit workingCopy) throws JavaModelException {
  148. if (!workingCopy.isConsistent()) {
  149. // make working copy consistent
  150. if (this.problems == null) this.problems = new HashMap();
  151. this.resolveBindings = this.requestorIsActive;
  152. this.ast = workingCopy.makeConsistent(this.astLevel, this.resolveBindings, this.reconcileFlags, this.problems, this.progressMonitor);
  153. this.deltaBuilder.buildDeltas();
  154. if (this.ast != null && this.deltaBuilder.delta != null)
  155. this.deltaBuilder.delta.changedAST(this.ast);
  156. return this.ast;
  157. }
  158. if (this.ast != null)
  159. return this.ast; // no need to recompute AST if known already
  160. CompilationUnitDeclaration unit = null;
  161. try {
  162. JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE);
  163. CompilationUnit source = workingCopy.cloneCachingContents();
  164. // find problems if needed
  165. if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject())
  166. && (this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) {
  167. this.resolveBindings = this.requestorIsActive;
  168. if (this.problems == null)
  169. this.problems = new HashMap();
  170. unit =
  171. CompilationUnitProblemFinder.process(
  172. source,
  173. this.workingCopyOwner,
  174. this.problems,
  175. this.astLevel != ICompilationUnit.NO_AST/*creating AST if level is not NO_AST */,
  176. this.reconcileFlags,
  177. this.progressMonitor);
  178. if (this.progressMonitor != null) this.progressMonitor.worked(1);
  179. }
  180. // create AST if needed
  181. if (this.astLevel != ICompilationUnit.NO_AST
  182. && unit !=null/*unit is null if working copy is consistent && (problem detection not forced || non-Java project) -> don't create AST as per API*/) {
  183. Map options = workingCopy.getJavaProject().getOptions(true);
  184. // convert AST
  185. this.ast =
  186. AST.convertCompilationUnit(
  187. this.astLevel,
  188. unit,
  189. options,
  190. this.resolveBindings,
  191. source,
  192. this.reconcileFlags,
  193. this.progressMonitor);
  194. if (this.ast != null) {
  195. if (this.deltaBuilder.delta == null) {
  196. this.deltaBuilder.delta = new JavaElementDelta(workingCopy);
  197. }
  198. this.deltaBuilder.delta.changedAST(this.ast);
  199. }
  200. if (this.progressMonitor != null) this.progressMonitor.worked(1);
  201. }
  202. } catch (JavaModelException e) {
  203. if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject()))
  204. throw e;
  205. // else JavaProject has lost its nature (or most likely was closed/deleted) while reconciling -> ignore
  206. // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=100919)
  207. } finally {
  208. JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null);
  209. if (unit != null) {
  210. unit.cleanUp();
  211. }
  212. }
  213. return this.ast;
  214. }
  215. private void notifyParticipants(final CompilationUnit workingCopy) {
  216. IJavaProject javaProject = getWorkingCopy().getJavaProject();
  217. CompilationParticipant[] participants = JavaModelManager.getJavaModelManager().compilationParticipants.getCompilationParticipants(javaProject);
  218. if (participants == null) return;
  219. final ReconcileContext context = new ReconcileContext(this, workingCopy);
  220. for (int i = 0, length = participants.length; i < length; i++) {
  221. final CompilationParticipant participant = participants[i];
  222. SafeRunner.run(new ISafeRunnable() {
  223. public void handleException(Throwable exception) {
  224. if (exception instanceof Error) {
  225. throw (Error) exception; // errors are not supposed to be caught
  226. } else if (exception instanceof OperationCanceledException)
  227. throw (OperationCanceledException) exception;
  228. else if (exception instanceof UnsupportedOperationException) {
  229. // might want to disable participant as it tried to modify the buffer of the working copy being reconciled
  230. Util.log(exception, "Reconcile participant attempted to modify the buffer of the working copy being reconciled"); //$NON-NLS-1$
  231. } else
  232. Util.log(exception, "Exception occurred in reconcile participant"); //$NON-NLS-1$
  233. }
  234. public void run() throws Exception {
  235. participant.reconcile(context);
  236. }
  237. });
  238. }
  239. }
  240. protected IJavaModelStatus verify() {
  241. IJavaModelStatus status = super.verify();
  242. if (!status.isOK()) {
  243. return status;
  244. }
  245. CompilationUnit workingCopy = getWorkingCopy();
  246. if (!workingCopy.isWorkingCopy()) {
  247. return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy); //was destroyed
  248. }
  249. return status;
  250. }
  251. }