PageRenderTime 27ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java

https://gitlab.com/unofficial-mirrors/eclipse-che
Java | 287 lines | 174 code | 25 blank | 88 comment | 62 complexity | 710ec9e03db2e07f087a1d0535e35aa7 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2012-2015 Codenvy, S.A.
  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. * Codenvy, S.A. - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.jdt.internal.core;
  12. import org.eclipse.jdt.core.ICompilationUnit;
  13. import org.eclipse.jdt.core.IJavaElement;
  14. import org.eclipse.jdt.core.IJavaModelStatus;
  15. import org.eclipse.jdt.core.IJavaModelStatusConstants;
  16. import org.eclipse.jdt.core.IProblemRequestor;
  17. import org.eclipse.jdt.core.JavaModelException;
  18. import org.eclipse.jdt.core.WorkingCopyOwner;
  19. import org.eclipse.jdt.core.compiler.CategorizedProblem;
  20. import org.eclipse.jdt.core.dom.CheAST;
  21. import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
  22. import org.eclipse.jdt.internal.core.util.Messages;
  23. import java.util.HashMap;
  24. import java.util.Iterator;
  25. import java.util.Map;
  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. @SuppressWarnings({"rawtypes"})
  43. public class ReconcileWorkingCopyOperation extends JavaModelOperation {
  44. public static boolean PERF = false;
  45. public int astLevel;
  46. public boolean resolveBindings;
  47. public HashMap problems;
  48. public int reconcileFlags;
  49. public org.eclipse.jdt.core.dom.CompilationUnit ast;
  50. public JavaElementDeltaBuilder deltaBuilder;
  51. public boolean requestorIsActive;
  52. WorkingCopyOwner workingCopyOwner;
  53. public ReconcileWorkingCopyOperation(IJavaElement workingCopy, int astLevel, int reconcileFlags, WorkingCopyOwner workingCopyOwner
  54. ) {
  55. super(new IJavaElement[]{workingCopy});
  56. this.astLevel = astLevel;
  57. this.reconcileFlags = reconcileFlags;
  58. this.workingCopyOwner = workingCopyOwner;
  59. }
  60. /**
  61. * @throws org.eclipse.jdt.core.JavaModelException
  62. * if setting the source
  63. * of the original compilation unit fails
  64. */
  65. protected void executeOperation() throws JavaModelException {
  66. checkCanceled();
  67. try {
  68. beginTask(Messages.element_reconciling, 2);
  69. CompilationUnit workingCopy = getWorkingCopy();
  70. boolean wasConsistent = workingCopy.isConsistent();
  71. // check is problem requestor is active
  72. IProblemRequestor problemRequestor = workingCopy.getPerWorkingCopyInfo();
  73. if (problemRequestor != null)
  74. problemRequestor = ((JavaModelManager.PerWorkingCopyInfo)problemRequestor).getProblemRequestor();
  75. boolean defaultRequestorIsActive = problemRequestor != null && problemRequestor.isActive();
  76. IProblemRequestor ownerProblemRequestor = this.workingCopyOwner.getProblemRequestor(workingCopy);
  77. boolean ownerRequestorIsActive =
  78. ownerProblemRequestor != null && ownerProblemRequestor != problemRequestor && ownerProblemRequestor.isActive();
  79. this.requestorIsActive = defaultRequestorIsActive || ownerRequestorIsActive;
  80. // create the delta builder (this remembers the current content of the cu)
  81. this.deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
  82. // make working copy consistent if needed and compute AST if needed
  83. makeConsistent(workingCopy);
  84. // notify reconcile participants only if working copy was not consistent or if forcing problem detection
  85. // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=177319)
  86. if (!wasConsistent || ((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0)) {
  87. notifyParticipants(workingCopy);
  88. // recreate ast if one participant reset it
  89. if (this.ast == null)
  90. makeConsistent(workingCopy);
  91. }
  92. // report problems
  93. if (this.problems != null && (((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) || !wasConsistent)) {
  94. if (defaultRequestorIsActive) {
  95. reportProblems(workingCopy, problemRequestor);
  96. }
  97. if (ownerRequestorIsActive) {
  98. reportProblems(workingCopy, ownerProblemRequestor);
  99. }
  100. }
  101. // report delta
  102. JavaElementDelta delta = this.deltaBuilder.delta;
  103. if (delta != null) {
  104. addReconcileDelta(workingCopy, delta);
  105. }
  106. } finally {
  107. done();
  108. }
  109. }
  110. /**
  111. * Report working copy problems to a given requestor.
  112. *
  113. * @param workingCopy
  114. * @param problemRequestor
  115. */
  116. private void reportProblems(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
  117. try {
  118. problemRequestor.beginReporting();
  119. for (Iterator iteraror = this.problems.values().iterator(); iteraror.hasNext(); ) {
  120. CategorizedProblem[] categorizedProblems = (CategorizedProblem[])iteraror.next();
  121. if (categorizedProblems == null) continue;
  122. for (int i = 0, length = categorizedProblems.length; i < length; i++) {
  123. CategorizedProblem problem = categorizedProblems[i];
  124. if (JavaModelManager.VERBOSE) {
  125. System.out.println("PROBLEM FOUND while reconciling : " + problem.getMessage());//$NON-NLS-1$
  126. }
  127. if (this.progressMonitor != null && this.progressMonitor.isCanceled()) break;
  128. problemRequestor.acceptProblem(problem);
  129. }
  130. }
  131. } finally {
  132. problemRequestor.endReporting();
  133. }
  134. }
  135. /**
  136. * Returns the working copy this operation is working on.
  137. */
  138. protected CompilationUnit getWorkingCopy() {
  139. return (CompilationUnit)getElementToProcess();
  140. }
  141. /* (non-Javadoc)
  142. * @see org.eclipse.jdt.internal.core.JavaModelOperation#isReadOnly()
  143. */
  144. public boolean isReadOnly() {
  145. return true;
  146. }
  147. /*
  148. * Makes the given working copy consistent, computes the delta and computes an AST if needed.
  149. * Returns the AST.
  150. */
  151. public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(CompilationUnit workingCopy) throws JavaModelException {
  152. if (!workingCopy.isConsistent()) {
  153. // make working copy consistent
  154. if (this.problems == null) this.problems = new HashMap();
  155. this.resolveBindings = this.requestorIsActive;
  156. this.ast = workingCopy
  157. .makeConsistent(this.astLevel, this.resolveBindings, this.reconcileFlags, this.problems, this.progressMonitor);
  158. this.deltaBuilder.buildDeltas();
  159. if (this.ast != null && this.deltaBuilder.delta != null)
  160. this.deltaBuilder.delta.changedAST(this.ast);
  161. return this.ast;
  162. }
  163. if (this.ast != null)
  164. return this.ast; // no need to recompute AST if known already
  165. CompilationUnitDeclaration unit = null;
  166. try {
  167. JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE);
  168. CompilationUnit source = workingCopy.cloneCachingContents();
  169. // find problems if needed
  170. if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject())
  171. && (this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) {
  172. this.resolveBindings = this.requestorIsActive;
  173. if (this.problems == null)
  174. this.problems = new HashMap();
  175. unit =
  176. CompilationUnitProblemFinder.process(
  177. source,
  178. this.workingCopyOwner,
  179. this.problems,
  180. this.astLevel != ICompilationUnit.NO_AST/*creating AST if level is not NO_AST */,
  181. this.reconcileFlags,
  182. this.progressMonitor);
  183. if (this.progressMonitor != null) this.progressMonitor.worked(1);
  184. }
  185. // create AST if needed
  186. if (this.astLevel != ICompilationUnit.NO_AST
  187. && unit !=
  188. null/*unit is null if working copy is consistent && (problem detection not forced || non-Java project) -> don't create
  189. AST as per API*/) {
  190. Map options = workingCopy.getJavaProject().getOptions(true);
  191. // convert AST
  192. this.ast =
  193. CheAST.convertCompilationUnit(
  194. this.astLevel,
  195. unit,
  196. options,
  197. this.resolveBindings,
  198. source,
  199. this.reconcileFlags,
  200. this.progressMonitor);
  201. if (this.ast != null) {
  202. if (this.deltaBuilder.delta == null) {
  203. this.deltaBuilder.delta = new JavaElementDelta(workingCopy);
  204. }
  205. this.deltaBuilder.delta.changedAST(this.ast);
  206. }
  207. if (this.progressMonitor != null) this.progressMonitor.worked(1);
  208. }
  209. } catch (JavaModelException e) {
  210. if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject()))
  211. throw e;
  212. // else JavaProject has lost its nature (or most likely was closed/deleted) while reconciling -> ignore
  213. // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=100919)
  214. } finally {
  215. JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null);
  216. if (unit != null) {
  217. unit.cleanUp();
  218. }
  219. }
  220. return this.ast;
  221. }
  222. private void notifyParticipants(final CompilationUnit workingCopy) {
  223. // IJavaProject javaProject = getWorkingCopy().getJavaProject();
  224. // CompilationParticipant[] participants = manager.compilationParticipants.getCompilationParticipants
  225. // (javaProject);
  226. // if (participants == null) return;
  227. //
  228. // final ReconcileContext context = new ReconcileContext(this, workingCopy);
  229. // for (int i = 0, length = participants.length; i < length; i++) {
  230. // final CompilationParticipant participant = participants[i];
  231. // SafeRunner.run(new ISafeRunnable() {
  232. // public void handleException(Throwable exception) {
  233. // if (exception instanceof Error) {
  234. // throw (Error)exception; // errors are not supposed to be caught
  235. // } else if (exception instanceof OperationCanceledException)
  236. // throw (OperationCanceledException)exception;
  237. // else if (exception instanceof UnsupportedOperationException) {
  238. // // might want to disable participant as it tried to modify the buffer of the working copy being reconciled
  239. // Util.log(exception,
  240. // "Reconcile participant attempted to modify the buffer of the working copy being reconciled"); //$NON-NLS-1$
  241. // } else
  242. // Util.log(exception, "Exception occurred in reconcile participant"); //$NON-NLS-1$
  243. // }
  244. //
  245. // public void run() throws Exception {
  246. // participant.reconcile(context);
  247. // }
  248. // });
  249. // }
  250. }
  251. protected IJavaModelStatus verify() {
  252. IJavaModelStatus status = super.verify();
  253. if (!status.isOK()) {
  254. return status;
  255. }
  256. CompilationUnit workingCopy = getWorkingCopy();
  257. if (!workingCopy.isWorkingCopy()) {
  258. return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy); //was destroyed
  259. }
  260. return status;
  261. }
  262. }