All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.ajdt.internal.core.builder.AspectJBuilder Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aspectj.ajdt.internal.core.builder;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.function.BooleanSupplier;

import org.aspectj.ajdt.core.AspectJCore;
import org.aspectj.ajdt.internal.compiler.CompilerAdapter;
import org.aspectj.ajdt.internal.compiler.IBinarySourceProvider;
import org.aspectj.ajdt.internal.compiler.ICompilerAdapter;
import org.aspectj.ajdt.internal.compiler.ICompilerAdapterFactory;
import org.aspectj.ajdt.internal.compiler.IIntermediateResultsRequestor;
import org.aspectj.ajdt.internal.compiler.IOutputClassFileNameProvider;
import org.aspectj.ajdt.internal.compiler.InterimCompilationResult;
import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
import org.aspectj.ajdt.internal.compiler.problem.AjProblemReporter;
import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.bridge.IMessage.Kind;
import org.aspectj.org.eclipse.jdt.core.IJavaModelMarker;
import org.aspectj.org.eclipse.jdt.core.JavaCore;
import org.aspectj.org.eclipse.jdt.core.JavaModelException;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.Compiler;
import org.aspectj.org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.aspectj.org.eclipse.jdt.internal.core.builder.BatchImageBuilder;
import org.aspectj.org.eclipse.jdt.internal.core.builder.BuildNotifier;
import org.aspectj.org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder;
import org.aspectj.org.eclipse.jdt.internal.core.builder.JavaBuilder;
import org.aspectj.weaver.Lint;
import org.aspectj.weaver.bcel.BcelWeaver;
import org.aspectj.weaver.bcel.BcelWorld;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;

/**
 * @author colyer
 *
 *         This is the builder class used by AJDT, and that the org.eclipse.ajdt.core plugin references.
 */
public class AspectJBuilder extends JavaBuilder implements ICompilerAdapterFactory {

	// One builder instance per project (important)
	private BcelWeaver myWeaver = null;
	private BcelWorld myBcelWorld = null;
	private EclipseClassPathManager cpManager = null;
	private UnwovenResultCollector unwovenResultCollector = null;
	private OutputFileNameProvider fileNameProvider = null;

	private boolean isBatchBuild = false;

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException {
		// super method always causes construction of a new XXXImageBuilder, which
		// causes construction of a new Compiler, so we will be detected as the
		// adapter.
		CompilerAdapter.setCompilerAdapterFactory(this);
		return super.build(kind, ignored, monitor);
	}

	protected BatchImageBuilder getBatchImageBuilder() {
		isBatchBuild = true;
		return new AjBatchImageBuilder(this);
	}

	protected IncrementalImageBuilder getIncrementalImageBuilder() {
		isBatchBuild = false;
		return new AjIncrementalImageBuilder(this);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.internal.compiler.ICompilerAdapterFactory#getAdapter(org.eclipse.jdt.internal.compiler.Compiler)
	 */
	public ICompilerAdapter getAdapter(Compiler forCompiler) {
		Map javaOptions = forCompiler.options.getMap();
		// TODO get aspectj options from project and add into map before...
		AjCompilerOptions ajOptions = new AjCompilerOptions(javaOptions);
		forCompiler.options = ajOptions;

		if (isBatchBuild || myBcelWorld == null || myWeaver == null) {
			initWorldAndWeaver(ajOptions);
		} else {
			// update the nameEnvironment each time we compile...
			cpManager.setNameEnvironment(nameEnvironment);
		}

		// * an eclipse factory -- create from AjLookupEnvironment, need to hide AjBuildManager field
		AjProblemReporter pr = new AjProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(), forCompiler.options,
				new DefaultProblemFactory(Locale.getDefault()));
		forCompiler.problemReporter = pr;
		AjLookupEnvironment le = new AjLookupEnvironment(forCompiler, forCompiler.options, pr, nameEnvironment);
		EclipseFactory eFactory = new EclipseFactory(le, myBcelWorld, ajOptions.xSerializableAspects);
		le.factory = eFactory;
		forCompiler.lookupEnvironment = le;

		// AjBuildNotifier ajNotifier = (AjBuildNotifier) notifier;
		if (fileNameProvider == null)
			fileNameProvider = new OutputFileNameProvider(getProject());

		// * the set of binary source entries for this compile -- from analyzing deltas, or everything if batch
		// * the full set of binary source entries for the project -- from IAspectJProject
		// TODO deal with inpath, injars here...
		// IBinarySourceProvider bsProvider = new NullBinarySourceProvider();
		// Map fullBinarySourceEntries = new HashMap();

		// * the intermediate result set from the last batch compile
		if (isBatchBuild) {
			unwovenResultCollector = new UnwovenResultCollector();
		}
		// Collection resultSetForFullWeave =
		unwovenResultCollector.getIntermediateResults();

		throw new UnsupportedOperationException("Is anyone actually using the AspectJBuilder class??");
		// return new AjCompilerAdapter(forCompiler,isBatchBuild,myBcelWorld,
		// myWeaver,eFactory,unwovenResultCollector,ajNotifier,fileNameProvider,bsProvider,
		// fullBinarySourceEntries,resultSetForFullWeave,
		// ajOptions.noWeave,ajOptions.proceedOnError,ajOptions.noAtAspectJProcessing);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.internal.core.builder.JavaBuilder#createBuildNotifier(org.eclipse.core.runtime.IProgressMonitor,
	 * org.eclipse.core.resources.IProject)
	 */
	protected BuildNotifier createBuildNotifier(IProgressMonitor monitor, int buildKind, BooleanSupplier interruptSupplier) {
		return new AjBuildNotifier(monitor, buildKind, interruptSupplier);
	}

	private void initWorldAndWeaver(AjCompilerOptions options) {
		cpManager = new EclipseClassPathManager(nameEnvironment);
		myBcelWorld = new BcelWorld(cpManager, new UnhandledMessageHandler(getProject()), null /* (xrefHandler) */);
		myBcelWorld.setBehaveInJava5Way(options.behaveInJava5Way);
		myBcelWorld.setTargetAspectjRuntimeLevel(options.targetAspectjRuntimeLevel);
		myBcelWorld.setXnoInline(options.xNoInline);
		myBcelWorld.setXlazyTjp(options.xLazyThisJoinPoint);
		myBcelWorld.setXHasMemberSupportEnabled(options.xHasMember);
		myBcelWorld.setPinpointMode(options.xdevPinpoint);
		setLintProperties(myBcelWorld, options);
		myWeaver = new BcelWeaver(myBcelWorld);
		myWeaver.setReweavableMode(options.xNotReweavable);
		// TODO deal with injars, inpath, and aspectpath here...
	}

	private void setLintProperties(BcelWorld world, AjCompilerOptions options) {
		Properties p = new Properties();
		Lint lintSettings = world.getLint();
		Map map = options.getMap();
		p.put(lintSettings.invalidAbsoluteTypeName.getName(), map.get(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName));
		p.put(lintSettings.invalidWildcardTypeName.getName(), map.get(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName));
		p.put(lintSettings.unresolvableMember.getName(), map.get(AjCompilerOptions.OPTION_ReportUnresolvableMember));
		p.put(lintSettings.typeNotExposedToWeaver.getName(), map.get(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver));
		p.put(lintSettings.shadowNotInStructure.getName(), map.get(AjCompilerOptions.OPTION_ReportShadowNotInStructure));
		p.put(lintSettings.unmatchedSuperTypeInCall.getName(), map.get(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall));
		p.put(lintSettings.canNotImplementLazyTjp.getName(), map.get(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP));
		p.put(lintSettings.needsSerialVersionUIDField.getName(), map.get(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField));
		p.put(lintSettings.serialVersionUIDBroken.getName(), map.get(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion));
		lintSettings.setFromProperties(p);
	}

	private static class UnwovenResultCollector implements IIntermediateResultsRequestor {

		private Collection results = new ArrayList<>();

		/*
		 * (non-Javadoc)
		 *
		 * @seeorg.aspectj.ajdt.internal.compiler.IIntermediateResultsRequestor#acceptResult(org.aspectj.ajdt.internal.compiler.
		 * InterimCompilationResult)
		 */
		public void acceptResult(InterimCompilationResult intRes) {
			results.add(intRes);
		}

		public Collection getIntermediateResults() {
			return results;
		}

	}

	// this class will only get messages that the weaver adapter couldn't tie into
	// an originating resource in the project - make them messages on the project
	// itself.
	private static class UnhandledMessageHandler implements IMessageHandler {

		private IProject project;

		public UnhandledMessageHandler(IProject p) {
			this.project = p;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.aspectj.bridge.IMessageHandler#handleMessage(org.aspectj.bridge.IMessage)
		 */
		public boolean handleMessage(IMessage message) throws AbortException {
			try {
				IMarker marker = project.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
				marker.setAttribute(IMarker.MESSAGE, message.getMessage());
				marker.setAttribute(IMarker.SEVERITY, message.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING);
			} catch (CoreException e) {
				AspectJCore.getPlugin().getLog().log(e.getStatus());
			}
			return true;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
		 */
		public boolean isIgnoring(Kind kind) {
			if (kind == IMessage.DEBUG || kind == IMessage.INFO)
				return true;
			return false;
		}

		/**
		 * No-op
		 *
		 * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
		 * @param kind
		 */
		public void dontIgnore(IMessage.Kind kind) {

		}

		public void ignore(Kind kind) {
		}

	}

	private static class OutputFileNameProvider implements IOutputClassFileNameProvider {

		private IPath outputLocation;

		public OutputFileNameProvider(IProject p) {
			try {
				outputLocation = JavaCore.create(p).getOutputLocation();
			} catch (JavaModelException e) {
				outputLocation = new Path(".");
				AspectJCore.getPlugin().getLog().log(e.getStatus());
			}
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.aspectj.ajdt.internal.compiler.IOutputClassFileNameProvider#getOutputClassFileName(char[],
		 * org.eclipse.jdt.internal.compiler.CompilationResult)
		 */
		public String getOutputClassFileName(char[] eclipseClassFileName, CompilationResult result) {
			// In the AJDT implementation, the name provided here will be ignored, we write the results
			// out in xxxImageBuilder.acceptResult() instead.
			// simply return the default output directory for the project.
			String filename = new String(eclipseClassFileName);
			IPath out = outputLocation.append(filename);
			out.addFileExtension(".class");
			return out.toOSString();
		}

	}

	// default impl class until the implementation is extended to cope with inpath, injars
	private static class NullBinarySourceProvider implements IBinarySourceProvider {

		/*
		 * (non-Javadoc)
		 *
		 * @see org.aspectj.ajdt.internal.compiler.IBinarySourceProvider#getBinarySourcesForThisWeave()
		 */
		public Map getBinarySourcesForThisWeave() {
			return new HashMap();
		}

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy