You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AspectJBuilder.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*******************************************************************************
  2. * Copyright (c) 2004 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 v 2.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.aspectj.ajdt.internal.core.builder;
  12. import java.util.ArrayList;
  13. import java.util.Collection;
  14. import java.util.HashMap;
  15. import java.util.Locale;
  16. import java.util.Map;
  17. import java.util.Properties;
  18. import java.util.function.BooleanSupplier;
  19. import org.aspectj.ajdt.core.AspectJCore;
  20. import org.aspectj.ajdt.internal.compiler.CompilerAdapter;
  21. import org.aspectj.ajdt.internal.compiler.IBinarySourceProvider;
  22. import org.aspectj.ajdt.internal.compiler.ICompilerAdapter;
  23. import org.aspectj.ajdt.internal.compiler.ICompilerAdapterFactory;
  24. import org.aspectj.ajdt.internal.compiler.IIntermediateResultsRequestor;
  25. import org.aspectj.ajdt.internal.compiler.IOutputClassFileNameProvider;
  26. import org.aspectj.ajdt.internal.compiler.InterimCompilationResult;
  27. import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
  28. import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
  29. import org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter;
  30. import org.aspectj.bridge.AbortException;
  31. import org.aspectj.bridge.IMessage;
  32. import org.aspectj.bridge.IMessageHandler;
  33. import org.aspectj.bridge.IMessage.Kind;
  34. import org.aspectj.org.eclipse.jdt.core.IJavaModelMarker;
  35. import org.aspectj.org.eclipse.jdt.core.JavaCore;
  36. import org.aspectj.org.eclipse.jdt.core.JavaModelException;
  37. import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.Compiler;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
  41. import org.aspectj.org.eclipse.jdt.internal.core.builder.BatchImageBuilder;
  42. import org.aspectj.org.eclipse.jdt.internal.core.builder.BuildNotifier;
  43. import org.aspectj.org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder;
  44. import org.aspectj.org.eclipse.jdt.internal.core.builder.JavaBuilder;
  45. import org.aspectj.weaver.Lint;
  46. import org.aspectj.weaver.bcel.BcelWeaver;
  47. import org.aspectj.weaver.bcel.BcelWorld;
  48. import org.eclipse.core.resources.IMarker;
  49. import org.eclipse.core.resources.IProject;
  50. import org.eclipse.core.runtime.CoreException;
  51. import org.eclipse.core.runtime.IPath;
  52. import org.eclipse.core.runtime.IProgressMonitor;
  53. import org.eclipse.core.runtime.Path;
  54. /**
  55. * @author colyer
  56. *
  57. * This is the builder class used by AJDT, and that the org.eclipse.ajdt.core plugin references.
  58. */
  59. public class AspectJBuilder extends JavaBuilder implements ICompilerAdapterFactory {
  60. // One builder instance per project (important)
  61. private BcelWeaver myWeaver = null;
  62. private BcelWorld myBcelWorld = null;
  63. private EclipseClassPathManager cpManager = null;
  64. private UnwovenResultCollector unwovenResultCollector = null;
  65. private OutputFileNameProvider fileNameProvider = null;
  66. private boolean isBatchBuild = false;
  67. /*
  68. * (non-Javadoc)
  69. *
  70. * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
  71. */
  72. protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException {
  73. // super method always causes construction of a new XXXImageBuilder, which
  74. // causes construction of a new Compiler, so we will be detected as the
  75. // adapter.
  76. CompilerAdapter.setCompilerAdapterFactory(this);
  77. return super.build(kind, ignored, monitor);
  78. }
  79. protected BatchImageBuilder getBatchImageBuilder() {
  80. isBatchBuild = true;
  81. return new AjBatchImageBuilder(this);
  82. }
  83. protected IncrementalImageBuilder getIncrementalImageBuilder() {
  84. isBatchBuild = false;
  85. return new AjIncrementalImageBuilder(this);
  86. }
  87. /*
  88. * (non-Javadoc)
  89. *
  90. * @see org.eclipse.jdt.internal.compiler.ICompilerAdapterFactory#getAdapter(org.eclipse.jdt.internal.compiler.Compiler)
  91. */
  92. public ICompilerAdapter getAdapter(Compiler forCompiler) {
  93. Map<String, String> javaOptions = forCompiler.options.getMap();
  94. // TODO get aspectj options from project and add into map before...
  95. AjCompilerOptions ajOptions = new AjCompilerOptions(javaOptions);
  96. forCompiler.options = ajOptions;
  97. if (isBatchBuild || myBcelWorld == null || myWeaver == null) {
  98. initWorldAndWeaver(ajOptions);
  99. } else {
  100. // update the nameEnvironment each time we compile...
  101. cpManager.setNameEnvironment(nameEnvironment);
  102. }
  103. // * an eclipse factory -- create from AjLookupEnvironment, need to hide AjBuildManager field
  104. AjProblemReporter pr = new AjProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(), forCompiler.options,
  105. new DefaultProblemFactory(Locale.getDefault()));
  106. forCompiler.problemReporter = pr;
  107. AjLookupEnvironment le = new AjLookupEnvironment(forCompiler, forCompiler.options, pr, nameEnvironment);
  108. EclipseFactory eFactory = new EclipseFactory(le, myBcelWorld, ajOptions.xSerializableAspects);
  109. le.factory = eFactory;
  110. forCompiler.lookupEnvironment = le;
  111. // AjBuildNotifier ajNotifier = (AjBuildNotifier) notifier;
  112. if (fileNameProvider == null)
  113. fileNameProvider = new OutputFileNameProvider(getProject());
  114. // * the set of binary source entries for this compile -- from analyzing deltas, or everything if batch
  115. // * the full set of binary source entries for the project -- from IAspectJProject
  116. // TODO deal with inpath, injars here...
  117. // IBinarySourceProvider bsProvider = new NullBinarySourceProvider();
  118. // Map fullBinarySourceEntries = new HashMap();
  119. // * the intermediate result set from the last batch compile
  120. if (isBatchBuild) {
  121. unwovenResultCollector = new UnwovenResultCollector();
  122. }
  123. // Collection resultSetForFullWeave =
  124. unwovenResultCollector.getIntermediateResults();
  125. throw new UnsupportedOperationException("Is anyone actually using the AspectJBuilder class??");
  126. // return new AjCompilerAdapter(forCompiler,isBatchBuild,myBcelWorld,
  127. // myWeaver,eFactory,unwovenResultCollector,ajNotifier,fileNameProvider,bsProvider,
  128. // fullBinarySourceEntries,resultSetForFullWeave,
  129. // ajOptions.noWeave,ajOptions.proceedOnError,ajOptions.noAtAspectJProcessing);
  130. }
  131. /*
  132. * (non-Javadoc)
  133. *
  134. * @see org.eclipse.jdt.internal.core.builder.JavaBuilder#createBuildNotifier(org.eclipse.core.runtime.IProgressMonitor,
  135. * org.eclipse.core.resources.IProject)
  136. */
  137. protected BuildNotifier createBuildNotifier(IProgressMonitor monitor, int buildKind, BooleanSupplier interruptSupplier) {
  138. return new AjBuildNotifier(monitor, buildKind, interruptSupplier);
  139. }
  140. private void initWorldAndWeaver(AjCompilerOptions options) {
  141. cpManager = new EclipseClassPathManager(nameEnvironment);
  142. myBcelWorld = new BcelWorld(cpManager, new UnhandledMessageHandler(getProject()), null /* (xrefHandler) */);
  143. myBcelWorld.setBehaveInJava5Way(options.behaveInJava5Way);
  144. myBcelWorld.setTargetAspectjRuntimeLevel(options.targetAspectjRuntimeLevel);
  145. myBcelWorld.setXnoInline(options.xNoInline);
  146. myBcelWorld.setXlazyTjp(options.xLazyThisJoinPoint);
  147. myBcelWorld.setXHasMemberSupportEnabled(options.xHasMember);
  148. myBcelWorld.setPinpointMode(options.xdevPinpoint);
  149. setLintProperties(myBcelWorld, options);
  150. myWeaver = new BcelWeaver(myBcelWorld);
  151. myWeaver.setReweavableMode(options.xNotReweavable);
  152. // TODO deal with injars, inpath, and aspectpath here...
  153. }
  154. private void setLintProperties(BcelWorld world, AjCompilerOptions options) {
  155. Properties p = new Properties();
  156. Lint lintSettings = world.getLint();
  157. Map<String, String> map = options.getMap();
  158. p.put(lintSettings.invalidAbsoluteTypeName.getName(), map.get(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName));
  159. p.put(lintSettings.invalidWildcardTypeName.getName(), map.get(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName));
  160. p.put(lintSettings.unresolvableMember.getName(), map.get(AjCompilerOptions.OPTION_ReportUnresolvableMember));
  161. p.put(lintSettings.typeNotExposedToWeaver.getName(), map.get(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver));
  162. p.put(lintSettings.shadowNotInStructure.getName(), map.get(AjCompilerOptions.OPTION_ReportShadowNotInStructure));
  163. p.put(lintSettings.unmatchedSuperTypeInCall.getName(), map.get(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall));
  164. p.put(lintSettings.canNotImplementLazyTjp.getName(), map.get(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP));
  165. p.put(lintSettings.needsSerialVersionUIDField.getName(), map.get(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField));
  166. p.put(lintSettings.serialVersionUIDBroken.getName(), map.get(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion));
  167. lintSettings.setFromProperties(p);
  168. }
  169. private static class UnwovenResultCollector implements IIntermediateResultsRequestor {
  170. private Collection<InterimCompilationResult> results = new ArrayList<>();
  171. /*
  172. * (non-Javadoc)
  173. *
  174. * @seeorg.aspectj.ajdt.internal.compiler.IIntermediateResultsRequestor#acceptResult(org.aspectj.ajdt.internal.compiler.
  175. * InterimCompilationResult)
  176. */
  177. public void acceptResult(InterimCompilationResult intRes) {
  178. results.add(intRes);
  179. }
  180. public Collection getIntermediateResults() {
  181. return results;
  182. }
  183. }
  184. // this class will only get messages that the weaver adapter couldn't tie into
  185. // an originating resource in the project - make them messages on the project
  186. // itself.
  187. private static class UnhandledMessageHandler implements IMessageHandler {
  188. private IProject project;
  189. public UnhandledMessageHandler(IProject p) {
  190. this.project = p;
  191. }
  192. /*
  193. * (non-Javadoc)
  194. *
  195. * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
  196. */
  197. public boolean handleMessage(IMessage message) throws AbortException {
  198. try {
  199. IMarker marker = project.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
  200. marker.setAttribute(IMarker.MESSAGE, message.getMessage());
  201. marker.setAttribute(IMarker.SEVERITY, message.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING);
  202. } catch (CoreException e) {
  203. AspectJCore.getPlugin().getLog().log(e.getStatus());
  204. }
  205. return true;
  206. }
  207. /*
  208. * (non-Javadoc)
  209. *
  210. * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
  211. */
  212. public boolean isIgnoring(Kind kind) {
  213. if (kind == IMessage.DEBUG || kind == IMessage.INFO)
  214. return true;
  215. return false;
  216. }
  217. /**
  218. * No-op
  219. *
  220. * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
  221. * @param kind
  222. */
  223. public void dontIgnore(IMessage.Kind kind) {
  224. }
  225. public void ignore(Kind kind) {
  226. }
  227. }
  228. private static class OutputFileNameProvider implements IOutputClassFileNameProvider {
  229. private IPath outputLocation;
  230. public OutputFileNameProvider(IProject p) {
  231. try {
  232. outputLocation = JavaCore.create(p).getOutputLocation();
  233. } catch (JavaModelException e) {
  234. outputLocation = new Path(".");
  235. AspectJCore.getPlugin().getLog().log(e.getStatus());
  236. }
  237. }
  238. /*
  239. * (non-Javadoc)
  240. *
  241. * @see org.aspectj.ajdt.internal.compiler.IOutputClassFileNameProvider#getOutputClassFileName(char[],
  242. * org.eclipse.jdt.internal.compiler.CompilationResult)
  243. */
  244. public String getOutputClassFileName(char[] eclipseClassFileName, CompilationResult result) {
  245. // In the AJDT implementation, the name provided here will be ignored, we write the results
  246. // out in xxxImageBuilder.acceptResult() instead.
  247. // simply return the default output directory for the project.
  248. String filename = new String(eclipseClassFileName);
  249. IPath out = outputLocation.append(filename);
  250. out.addFileExtension(".class");
  251. return out.toOSString();
  252. }
  253. }
  254. // default impl class until the implementation is extended to cope with inpath, injars
  255. private static class NullBinarySourceProvider implements IBinarySourceProvider {
  256. /*
  257. * (non-Javadoc)
  258. *
  259. * @see org.aspectj.ajdt.internal.compiler.IBinarySourceProvider#getBinarySourcesForThisWeave()
  260. */
  261. public Map getBinarySourcesForThisWeave() {
  262. return new HashMap();
  263. }
  264. }
  265. }