diff options
author | aclement <aclement> | 2007-01-11 16:04:29 +0000 |
---|---|---|
committer | aclement <aclement> | 2007-01-11 16:04:29 +0000 |
commit | cfd711b9628154e0b2eb2df174124699cf831f83 (patch) | |
tree | 83b9afa0e996777cf4cdcdff23f3b69f72df031b /ajde.core/src | |
parent | 41fefd58f8b716468b2bdba2335eb921e5eb3a7b (diff) | |
download | aspectj-cfd711b9628154e0b2eb2df174124699cf831f83.tar.gz aspectj-cfd711b9628154e0b2eb2df174124699cf831f83.zip |
new ajde.core module
Diffstat (limited to 'ajde.core/src')
10 files changed, 1062 insertions, 0 deletions
diff --git a/ajde.core/src/org/aspectj/ajde/core/AjCompiler.java b/ajde.core/src/org/aspectj/ajde/core/AjCompiler.java new file mode 100644 index 000000000..9f2672414 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/AjCompiler.java @@ -0,0 +1,141 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core; + +import org.aspectj.ajde.core.internal.AjdeCoreBuildManager; +import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.Message; +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; + +/** + * The class to be used by tools to drive a build. An AjCompiler is created + * with a unique id (for example the absolute pathname of a project + * or .lst file) along with implementations of ICompilerConfiguration, + * IBuildProgressMonitor and IBuildMessageHandler. Tools then call + * build() or buildFresh() on this AjCompiler. + * + * <p>An AjCompiler is associated with one id, therefore a new one + * needs to be created for a new id (project, .lst file etc.). It is the + * responsibility of the tools to manage the lifecycle of the AjCompiler's. + */ +public class AjCompiler { + + private ICompilerConfiguration compilerConfig; + private IBuildProgressMonitor monitor; + private IBuildMessageHandler handler; + private String compilerId; + + private AjdeCoreBuildManager buildManager; + + /** + * Creates a new AjCompiler for the given id, ICompilerConfiguration, + * IBuildProgressMonitor and IBuildMessageHandler. None of the arguments + * can be null. + * + * @param compilerId - Unique String used to identify this AjCompiler + * @param compilerConfig - ICompilerConfiguration implementation + * @param buildProgressMonitor - IBuildProgressMonitor implementation + * @param buildMessageHandler - IBuildMessageHandler implementation + */ + public AjCompiler( + String compilerId, + ICompilerConfiguration compilerConfig, + IBuildProgressMonitor buildProgressMonitor, + IBuildMessageHandler buildMessageHandler) { + this.compilerConfig = compilerConfig; + this.monitor = buildProgressMonitor; + this.handler = buildMessageHandler; + this.compilerId = compilerId; + + buildManager = new AjdeCoreBuildManager(this); + } + + /** + * @return the id for this AjCompiler + */ + public String getId() { + return compilerId; + } + + /** + * @return the ICompilerConfiguration associated with this AjCompiler + */ + public ICompilerConfiguration getCompilerConfiguration() { + return compilerConfig; + } + + /** + * @return the IBuildProgressMonitor associated with this AjCompiler + */ + public IBuildProgressMonitor getBuildProgressMonitor() { + return monitor; + } + + /** + * @return the IBuildMessageHandler associated with this AjCompiler + */ + public IBuildMessageHandler getMessageHandler() { + return handler; + } + + /** + * Perform an incremental build if possible, otherwise it will + * default to a full build. + */ + public void build() { + if (hasValidId()) { + buildManager.doBuild(false); + } + } + + /** + * Perform a full build + */ + public void buildFresh() { + if (hasValidId()) { + buildManager.doBuild(true); + } + } + + /** + * Clear the incremental state associated with this AjCompiler + * from the IncrementalStateManager. This is necessary until AjState + * is reworked and there's an AjState associated with an AjCompiler + * rather than requiring a map of them. + */ + public void clearLastState() { + IncrementalStateManager.removeIncrementalStateInformationFor(compilerId); + } + + /** + * @return true if the underlying version of the compiler + * is compatible with Java 6, returns false otherwise. + */ + public boolean isJava6Compatible() { + return CompilerOptions.versionToJdkLevel(JavaOptions.VERSION_16) != 0; + } + + /** + * Ensures that the id associated with this compiler is non-null. If + * it is null then sends an ABORT message to the messageHandler + */ + private boolean hasValidId() { + if (compilerId == null) { + Message msg = new Message("compiler didn't have an id associated " + + "with it",IMessage.ABORT,null,null); + handler.handleMessage(msg); + return false; + } + return true; + } + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java b/ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java new file mode 100644 index 000000000..064e37c92 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/IBuildMessageHandler.java @@ -0,0 +1,56 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; + +/** + * Interface that handles messages sent from the compiler. + * Implementations define which messages are logged and whether + * the handler aborts the process. + */ +public interface IBuildMessageHandler { + + /** + * Handle message by reporting and/or throwing an AbortException. + * + * @param message the IMessage to handle - never null + * @return true if this message was handled by this handler + * @throws IllegalArgumentException if message is null + * @throws AbortException depending on handler logic. + */ + boolean handleMessage(IMessage message) throws AbortException; + + /** + * Signal whether this will ignore messages of a given type. + * Clients may use this to avoid constructing or sending + * certain messages. + * + * @return true if this handler is ignoring all messages of this type + */ + boolean isIgnoring(IMessage.Kind kind); + + /** + * Allow fine grained configuration after initialization. + * + * @param kind + */ + void dontIgnore(IMessage.Kind kind); + + /** + * Allow fine grained configuration after initialization. + * + * @param kind + */ + void ignore(IMessage.Kind kind); + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java b/ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java new file mode 100644 index 000000000..120dda25a --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/IBuildProgressMonitor.java @@ -0,0 +1,50 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core; + +/** + * Interface that presents the user with information about the + * progress of the build + */ +public interface IBuildProgressMonitor { + + /** + * Start the progress monitor + */ + public void begin(); + + /** + * Sets the label describing the current progress phase. + */ + public void setProgressText(String text); + + /** + * Stop the progress monitor + * + * @param wasFullBuild - true if was a full build, false otherwise + */ + public void finish(boolean wasFullBuild); + + /** + * Sets the current progress done + * + * @param percentDone + */ + public void setProgress(double percentDone); + + /** + * Checks whether the user has chosen to cancel the progress monitor + * + * @return true if progress monitor has been cancelled and false otherwise + */ + public boolean isCancelRequested(); + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java new file mode 100644 index 000000000..35a8eb51c --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java @@ -0,0 +1,95 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Inteface that contains all the configuration required for the + * compiler to be able to perform a build + */ +public interface ICompilerConfiguration { + + /** + * Returns the table of the current custom java options. + * <p> + * For a complete description of the configurable options, see + * {@link org.aspectj.ajde.core.JavaOptions#getDefaultJavaOptions} + * or {@link org.aspectj.org.eclipse.jdt.core.IJavaProject#getOptions(boolean)} + * </p> + * + * @return table of current settings of all options + * (key type: <code>String</code>; value type: <code>String</code>) + * @see org.aspectj.ajde.core.JavaOptions#getDefaultJavaOptions or + * org.aspectj.org.eclipse.jdt.core.IJavaProject#getOptions(boolean) + */ + public Map /*String --> String */getJavaOptionsMap(); + + /** + * The non-standard options, typically prefaced with -X when used + * with a command line compiler. The default is no non-standard + * options. Options should be separated by a space, for example + * "-showWeaveInfo -XnoInline" + */ + public String getNonStandardOptions(); + + /** + * @return a list of those files to include in the build + */ + public List /*String*/ getProjectSourceFiles(); + + /** + * @return the classpath to use + */ + public String getClasspath(); + + /** + * @return the IOutputLocationManager associated with this + * compiler configuration + */ + public IOutputLocationManager getOutputLocationManager(); + + /** + * @return the set of input path elements for this compilation. + * Set members should be of the type java.io.File. + * An empty set or null is acceptable for this option. + * From -inpath + */ + public Set /*java.io.File*/ getInpath(); + + /** + * @return the output jar file for the compilation results. + * Return null to leave classfiles unjar'd in output directory + * From -outjar + */ + public String getOutJar(); + + /** + * @return the set of aspect jar files to be used for the compilation. + * Returning null or an empty set disables this option. Set members + * should be of type java.io.File. + * From -aspectpath + */ + public Set /*java.io.File*/ getAspectPath(); + + /** + * Get the set of non-Java resources for this compilation. + * Set members should be of type java.io.File. + * An empty set or null is acceptable for this option. + * + * @return map from unique resource name to absolute path to source + * resource (String to File) + */ + public Map /*String --> java.io.File */getSourcePathResources(); + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java b/ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java new file mode 100644 index 000000000..7025f44b0 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/IOutputLocationManager.java @@ -0,0 +1,56 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors.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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * Helen Hawkins bug 166580 and 148190 + * ******************************************************************/ +package org.aspectj.ajde.core; + +import java.io.File; +import java.util.List; + +/** + * Interface that handles where the compilation output is sent. Allows + * for the output folder to be different for different source files. + */ +public interface IOutputLocationManager { + + /** + * Return the directory root under which the results of compiling the given + * source file. For example, if the source file contains the type a.b.C, and + * this method returns "target/classes" the resulting class file will be written + * to "target/classes/a/b/C.class" + * + * @param compilationUnit the compilation unit that has been compiled + * @return a File object representing the root directory under which compilation results for this + * unit should be written + */ + File getOutputLocationForClass(File compilationUnit); + + /** + * When copying resources from source folders to output location, return the + * root directory under which the resource should be copied. + * + * @param resource the resource to be copied + * @return a File object representing the root directory under which this resource + * should be copied + */ + File getOutputLocationForResource(File resource); + + /** + * Return a list of all output locations handled by this OutputLocationManager + */ + List /*File*/ getAllOutputLocations(); + + /** + * Return the default output location (for example, <my_project>/bin). This is + * where classes which are on the inpath will be placed. + */ + File getDefaultOutputLocation(); + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/JavaOptions.java b/ajde.core/src/org/aspectj/ajde/core/JavaOptions.java new file mode 100644 index 000000000..765e36a37 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/JavaOptions.java @@ -0,0 +1,126 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.util.HashMap; +import java.util.Map; + +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; + +/** + * Class containing the current custom java options + */ +public final class JavaOptions { + + public static final String COMPLIANCE_LEVEL = CompilerOptions.OPTION_Compliance; + public static final String SOURCE_COMPATIBILITY_LEVEL = CompilerOptions.OPTION_Source; + public static final String TARGET_COMPATIBILITY_LEVEL = CompilerOptions.OPTION_TargetPlatform; + // Version constants + public static final String VERSION_13 = CompilerOptions.VERSION_1_3; + public static final String VERSION_14 = CompilerOptions.VERSION_1_4; + public static final String VERSION_15 = CompilerOptions.VERSION_1_5; + public static final String VERSION_16 = "1.6"; // current version of the compiler doesn't support java6 + + // by default will use the platform default encoding + public static final String CHARACTER_ENCODING = CompilerOptions.OPTION_Encoding; + + // indicates if unused/optimizable local variables need to be preserved (debugging purpose) + public static final String PRESERVE_ALL_LOCALS = CompilerOptions.OPTION_PreserveUnusedLocal; + public static final String PRESERVE = CompilerOptions.PRESERVE; + public static final String OPTIMIZE = CompilerOptions.OPTIMIZE_OUT; + + // Warning constants + public static final String WARN_METHOD_WITH_CONSTRUCTOR_NAME = CompilerOptions.OPTION_ReportMethodWithConstructorName; + public static final String WARN_OVERRIDING_PACKAGE_DEFAULT_METHOD = CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod; + public static final String WARN_DEPRECATION = CompilerOptions.OPTION_ReportDeprecation; + public static final String WARN_HIDDEN_CATCH_BLOCKS = CompilerOptions.OPTION_ReportHiddenCatchBlock; + public static final String WARN_UNUSED_LOCALS = CompilerOptions.OPTION_ReportUnusedLocal; + public static final String WARN_UNUSED_PARAMETER = CompilerOptions.OPTION_ReportUnusedParameter; + public static final String WARN_UNUSED_IMPORTS = CompilerOptions.OPTION_ReportUnusedImport; + public static final String WARN_SYNTHETIC_ACCESS = CompilerOptions.OPTION_ReportSyntheticAccessEmulation; + public static final String WARN_ASSERT_IDENITIFIER = CompilerOptions.OPTION_ReportAssertIdentifier; + public static final String WARN_NON_NLS = CompilerOptions.OPTION_ReportNonExternalizedStringLiteral; + // warning option constants + public static final String IGNORE = CompilerOptions.IGNORE; + public static final String WARNING = CompilerOptions.WARNING; + + // Debug constants + public static final String DEBUG_SOURCE = CompilerOptions.OPTION_SourceFileAttribute; + public static final String DEBUG_LINES = CompilerOptions.OPTION_LocalVariableAttribute; + public static final String DEBUG_VARS = CompilerOptions.OPTION_LineNumberAttribute; + // Debug option constants + public static final String GENERATE = CompilerOptions.GENERATE; + public static final String DO_NOT_GENERATE = CompilerOptions.DO_NOT_GENERATE; + + private static Map defaultOptionsMap; + + /** + * @return the java options map with the default settings + */ + public static Map getDefaultJavaOptions() { + if (defaultOptionsMap != null) return defaultOptionsMap; + + defaultOptionsMap = new HashMap(); + defaultOptionsMap.put(COMPLIANCE_LEVEL, VERSION_14); + defaultOptionsMap.put(SOURCE_COMPATIBILITY_LEVEL, VERSION_13); + defaultOptionsMap.put(PRESERVE_ALL_LOCALS, OPTIMIZE); + defaultOptionsMap.put(WARN_METHOD_WITH_CONSTRUCTOR_NAME, IGNORE); + defaultOptionsMap.put(WARN_OVERRIDING_PACKAGE_DEFAULT_METHOD, IGNORE); + defaultOptionsMap.put(WARN_DEPRECATION, IGNORE); + defaultOptionsMap.put(WARN_HIDDEN_CATCH_BLOCKS, IGNORE); + defaultOptionsMap.put(WARN_UNUSED_LOCALS, IGNORE); + defaultOptionsMap.put(WARN_UNUSED_PARAMETER, IGNORE); + defaultOptionsMap.put(WARN_UNUSED_IMPORTS, IGNORE); + defaultOptionsMap.put(WARN_SYNTHETIC_ACCESS, IGNORE); + defaultOptionsMap.put(WARN_ASSERT_IDENITIFIER, IGNORE); + defaultOptionsMap.put(WARN_NON_NLS, IGNORE); + defaultOptionsMap.put(DEBUG_SOURCE, GENERATE); + defaultOptionsMap.put(DEBUG_LINES, GENERATE); + defaultOptionsMap.put(DEBUG_VARS, DO_NOT_GENERATE); + + return defaultOptionsMap; + } + + /** + * @return true if the given value is a valid JVM version + * (JavaOptions.VERSION_13, JavaOptions.VERSION_134, JavaOptions.VERSION_15, + * JavaOptions.VERSION_16) and false otherwise + */ + public static boolean isValidJvmVersion(String value) { + return VERSION_13.equals(value) || VERSION_14.equals(value) + || VERSION_15.equals(value) || VERSION_16.equals(value); + } + + /** + * @return true if the given option is JavaOptions.PRESERVE or + * JavaOptions.OPTIMIZE and false otherwise + */ + public static boolean isValidPreserveAllLocalsOption(String option) { + return PRESERVE.equals(option) || OPTIMIZE.equals(option); + } + + /** + * @return true if the given option is JavaOptions.IGNORE or + * JavaOptions.WARNING and false otherwise + */ + public static boolean isIgnoreOrWarning(String option) { + return IGNORE.equals(option) || WARNING.equals(option); + } + + /** + * @return true if the given option is JavaOptions.GENERATE or + * JavaOptions.DO_NOT_GENERATE and false otherwise + */ + public static boolean isGenerateOrNot(String option) { + return GENERATE.equals(option) || DO_NOT_GENERATE.equals(option); + } + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java new file mode 100644 index 000000000..46db93884 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java @@ -0,0 +1,393 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core.internal; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +import org.aspectj.ajde.core.AjCompiler; +import org.aspectj.ajde.core.ICompilerConfiguration; +import org.aspectj.ajde.core.IOutputLocationManager; +import org.aspectj.ajde.core.JavaOptions; +import org.aspectj.ajdt.ajc.AjdtCommand; +import org.aspectj.ajdt.ajc.BuildArgParser; +import org.aspectj.ajdt.internal.core.builder.AjBuildConfig; +import org.aspectj.ajdt.internal.core.builder.AjBuildManager; +import org.aspectj.ajdt.internal.core.builder.AjState; +import org.aspectj.ajdt.internal.core.builder.IncrementalStateManager; +import org.aspectj.asm.AsmManager; +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.CountingMessageHandler; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.Message; +import org.aspectj.bridge.SourceLocation; +import org.aspectj.bridge.context.CompilationAndWeavingContext; +import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.aspectj.util.ConfigParser; +import org.aspectj.util.LangUtil; + +/** + * Build Manager which drives the build for a given AjCompiler. + * Tools call build on the AjCompiler which drives this. + */ +public class AjdeCoreBuildManager { + + private AjCompiler compiler; + + private AjdeCoreBuildNotifierAdapter currNotifier = null; + private AjBuildManager ajBuildManager; + private IMessageHandler msgHandlerAdapter; + + public AjdeCoreBuildManager(AjCompiler compiler) { + this.compiler = compiler; + msgHandlerAdapter = new AjdeCoreMessageHandlerAdapter(compiler.getMessageHandler()); + ajBuildManager = new AjBuildManager(msgHandlerAdapter); + ajBuildManager.environmentSupportsIncrementalCompilation(true); + // this static information needs to be set to ensure + // incremental compilation works correctly + IncrementalStateManager.recordIncrementalStates=true; + IncrementalStateManager.debugIncrementalStates=true; + AsmManager.attemptIncrementalModelRepairs = true; + } + + /** + * @param buildFresh - true if want to force a full build, false otherwise + */ + public void doBuild(boolean buildFresh) { + if (!buildFresh) { + buildFresh = updateAsmManagerInformation(); + } + try { + startNotifiers(); + + // record the options passed to the compiler + handleMessage(new Message(getFormattedOptionsString(),IMessage.INFO,null,null)); + + CompilationAndWeavingContext.reset(); + AjBuildConfig buildConfig = genAjBuildConfig(); + if (buildConfig == null) return; + + if (buildFresh) { + ajBuildManager.batchBuild(buildConfig,msgHandlerAdapter); + } else { + ajBuildManager.incrementalBuild(buildConfig,msgHandlerAdapter); + } + IncrementalStateManager.recordSuccessfulBuild(compiler.getId(),ajBuildManager.getState()); + + } catch (ConfigParser.ParseException pe) { + handleMessage(new Message("Config file entry invalid, file: " + pe.getFile().getPath() + + ", line number: " + pe.getLine(),IMessage.WARNING,null,null)); + } catch (AbortException e) { + final IMessage message = e.getIMessage(); + if (message == null) { + handleMessage(new Message(LangUtil.unqualifiedClassName(e) + " thrown: " + + e.getMessage(),IMessage.ERROR,e,null)); + } else { + handleMessage(new Message(message.getMessage() + "\n" + + CompilationAndWeavingContext.getCurrentContext(),IMessage.ERROR,e,null)); + }; + } catch (Throwable t) { + handleMessage(new Message("Compile error: " + LangUtil.unqualifiedClassName(t) + " thrown: " + + "" + t.getMessage(),IMessage.ABORT,t,null)); + } finally { + compiler.getBuildProgressMonitor().finish(ajBuildManager.wasFullBuild()); + } + } + + /** + * Starts the various notifiers which are interested in the build progress + */ + private void startNotifiers() { + compiler.getBuildProgressMonitor().begin(); + currNotifier = new AjdeCoreBuildNotifierAdapter(compiler.getBuildProgressMonitor()); + ajBuildManager.setProgressListener(currNotifier); + } + + /** + * Switches the relationshipMap and hierarchy used by AsmManager to be + * the one for the current compiler - this will not be necessary once + * the static nature is removed from the asm. + */ + private boolean updateAsmManagerInformation() { + AjState updatedState = IncrementalStateManager.retrieveStateFor(compiler.getId()); + if (updatedState == null) { + return true; + } else { + AsmManager.getDefault().setRelationshipMap(updatedState.getRelationshipMap()); + AsmManager.getDefault().setHierarchy(updatedState.getStructureModel()); + } + return false; + } + + // AMC - updated for AspectJ 1.1 options + private String getFormattedOptionsString() { + ICompilerConfiguration compilerConfig = compiler.getCompilerConfiguration(); + return "Building with settings: " + + "\n-> output paths: " + formatCollection(compilerConfig.getOutputLocationManager() + .getAllOutputLocations()) + + "\n-> classpath: " + compilerConfig.getClasspath() + + "\n-> -inpath " + formatCollection(compilerConfig.getInpath()) + + "\n-> -outjar " + formatOptionalString(compilerConfig.getOutJar()) + + "\n-> -aspectpath " + formatCollection(compilerConfig.getAspectPath()) + + "\n-> -sourcePathResources " + formatMap(compilerConfig.getSourcePathResources()) + + "\n-> non-standard options: " + compilerConfig.getNonStandardOptions() + + "\n-> javaoptions:" + formatMap(compilerConfig.getJavaOptionsMap()); + } + + private String formatCollection( Collection options ) { + if ( options == null ) return "<default>"; + if ( options.isEmpty() ) return "none"; + + StringBuffer formattedOptions = new StringBuffer(); + Iterator it = options.iterator(); + while (it.hasNext()) { + String o = it.next().toString(); + if (formattedOptions.length() > 0) formattedOptions.append(", "); + formattedOptions.append( o ); + } + return formattedOptions.toString(); + } + + private String formatMap( Map options) { + if (options == null) return "<default>"; + if (options.isEmpty()) return "none"; + + return options.toString(); + } + + private String formatOptionalString( String s ) { + if ( s == null ) { return "" ; } + else { return s; } + } + + /** + * Generate a new AjBuildConfig from the compiler configuration + * associated with this AjdeCoreBuildManager + * + * @return null if invalid configuration, corresponding + * AjBuildConfig otherwise + */ + public AjBuildConfig genAjBuildConfig() { + File configFile = new File(compiler.getId()); + String[] args = null; + if (configFile.exists() && configFile.isFile()) { + args = new String[] { "@" + configFile.getAbsolutePath() }; + } else { + List l = compiler.getCompilerConfiguration().getProjectSourceFiles(); + if (l == null) return null; + args = new String[l.size()]; + int counter = 0; + for (Iterator iter = l.iterator(); iter.hasNext();) { + String element = (String) iter.next(); + args[counter] = element; + counter++; + } + } + CountingMessageHandler handler = CountingMessageHandler.makeCountingMessageHandler( + msgHandlerAdapter); + BuildArgParser parser = new BuildArgParser(handler); + + AjBuildConfig config = new AjBuildConfig(); + parser.populateBuildConfig(config, args, false, configFile); + configureCompilerOptions(config); + + ISourceLocation location = null; + if (config.getConfigFile() != null) { + location = new SourceLocation(config.getConfigFile(), 0); + } + + String message = parser.getOtherMessages(true); + if (null != message) { + IMessage m = new Message(message, IMessage.ERROR, null, location); + handler.handleMessage(m); + } + + // always force model generation in AJDE + config.setGenerateModelMode(true); + // always be in incremental mode in AJDE + config.setIncrementalMode(true); + return config; + } + + /** + * Check that the user hasn't specified Java 6 for the compliance, source and + * target levels. If they have then an error is thrown. + */ + private void checkNotAskedForJava6Compliance() { + // bug 164384 - Throwing an IMessage.ERRROR rather than an IMessage.ABORT + // means that we'll continue to try to compile the code. This means that + // the user may see other errors (for example, if they're using annotations + // then they'll get errors saying that they require 5.0 compliance). + // Throwing IMessage.ABORT would prevent this, however, 'abort' is really + // for compiler exceptions. + Map javaOptions = compiler.getCompilerConfiguration().getJavaOptionsMap(); + if (javaOptions != null){ + String version = (String)javaOptions.get(CompilerOptions.OPTION_Compliance); + String sourceVersion = (String)javaOptions.get(CompilerOptions.OPTION_Source); + String targetVersion = (String)javaOptions.get(CompilerOptions.OPTION_TargetPlatform); + if (version!=null && version.equals(JavaOptions.VERSION_16)) { + String msg = "Java 6.0 compliance level is unsupported"; + IMessage m = new Message(msg, IMessage.ERROR, null, null); + compiler.getMessageHandler().handleMessage(m); + } else if (sourceVersion!=null && sourceVersion.equals(JavaOptions.VERSION_16)) { + String msg = "Java 6.0 source level is unsupported"; + IMessage m = new Message(msg, IMessage.ERROR, null, null); + compiler.getMessageHandler().handleMessage(m); + } else if (targetVersion!=null && targetVersion.equals(JavaOptions.VERSION_16)) { + String msg = "Java 6.0 target level is unsupported"; + IMessage m = new Message(msg, IMessage.ERROR, null, null); + compiler.getMessageHandler().handleMessage(m); + } + } + } + + /** + * Configure the given AjBuildConfig with the options found in the + * ICompilerConfiguration implementation associated with the AjCompiler + * for this AjdeCoreBuildManager + * + * @param config + */ + private void configureCompilerOptions(AjBuildConfig config) { + checkNotAskedForJava6Compliance(); + + String propcp = compiler.getCompilerConfiguration().getClasspath(); + if (!LangUtil.isEmpty(propcp)) { + StringTokenizer st = new StringTokenizer(propcp, File.pathSeparator); + List configClasspath = config.getClasspath(); + ArrayList toAdd = new ArrayList(); + while (st.hasMoreTokens()) { + String entry = st.nextToken(); + if (!configClasspath.contains(entry)) { + toAdd.add(entry); + } + } + if (0 < toAdd.size()) { + ArrayList both = new ArrayList(configClasspath.size() + toAdd.size()); + both.addAll(configClasspath); + both.addAll(toAdd); + config.setClasspath(both); + } + } + + // set the outputjar + if (config.getOutputJar() == null) { + String outJar = compiler.getCompilerConfiguration().getOutJar(); + if (!LangUtil.isEmpty(outJar)) { + config.setOutputJar(new File( outJar ) ); + } + } + + // set compilation result destination manager + IOutputLocationManager outputLocationManager = compiler.getCompilerConfiguration().getOutputLocationManager(); + if (config.getCompilationResultDestinationManager() == null && outputLocationManager != null) { + config.setCompilationResultDestinationManager(new OutputLocationAdapter(outputLocationManager)); + } + + join(config.getInpath(),compiler.getCompilerConfiguration().getInpath()); + // bug 168840 - calling 'setInPath(..)' creates BinarySourceFiles which + // are used to see if there have been changes in classes on the inpath + if (config.getInpath() != null) config.setInPath(config.getInpath()); + config.setSourcePathResources(compiler.getCompilerConfiguration().getSourcePathResources()); + join(config.getAspectpath(), compiler.getCompilerConfiguration().getAspectPath()); + + Map jom = compiler.getCompilerConfiguration().getJavaOptionsMap(); + if (jom!=null) { + String version = (String)jom.get(CompilerOptions.OPTION_Compliance); + if (version!=null && version.equals(CompilerOptions.VERSION_1_5)) { + config.setBehaveInJava5Way(true); + } + config.getOptions().set(jom); + } + + configureNonStandardOptions(config); + } + + private void join(Collection target, Collection source) { + if ((null == target) || (null == source)) { + return; + } + for (Iterator iter = source.iterator(); iter.hasNext();) { + Object next = iter.next(); + if (! target.contains(next)) { + target.add(next); + } + } + } + + /** + * Helper method for configure build options. This reads all command-line + * options specified in the non-standard options text entry and sets any + * corresponding unset values in config. + */ + private void configureNonStandardOptions(AjBuildConfig config) { + + String nonStdOptions = compiler.getCompilerConfiguration().getNonStandardOptions(); + if (LangUtil.isEmpty(nonStdOptions)) { + return; + } + + // Break a string into a string array of non-standard options. + // Allows for one option to include a ' '. i.e. assuming it has been quoted, it + // won't accidentally get treated as a pair of options (can be needed for xlint props file option) + List tokens = new ArrayList(); + int ind = nonStdOptions.indexOf('\"'); + int ind2 = nonStdOptions.indexOf('\"',ind+1); + if ((ind > -1) && (ind2 > -1)) { // dont tokenize within double quotes + String pre = nonStdOptions.substring(0,ind); + String quoted = nonStdOptions.substring(ind+1,ind2); + String post = nonStdOptions.substring(ind2+1,nonStdOptions.length()); + tokens.addAll(tokenizeString(pre)); + tokens.add(quoted); + tokens.addAll(tokenizeString(post)); + } else { + tokens.addAll(tokenizeString(nonStdOptions)); + } + String[] args = (String[])tokens.toArray(new String[]{}); + + + // set the non-standard options in an alternate build config + // (we don't want to lose the settings we already have) + CountingMessageHandler counter + = CountingMessageHandler.makeCountingMessageHandler(msgHandlerAdapter); + AjBuildConfig altConfig = AjdtCommand.genBuildConfig(args, counter); + if (counter.hasErrors()) { + return; + } + // copy globals where local is not set + config.installGlobals(altConfig); + } + + /** Local helper method for splitting option strings */ + private List tokenizeString(String str) { + List tokens = new ArrayList(); + StringTokenizer tok = new StringTokenizer(str); + while ( tok.hasMoreTokens() ) { + tokens.add(tok.nextToken()); + } + return tokens; + } + + /** + * Helper method to ask the messagehandler to handle the + * given message + */ + private void handleMessage(Message msg) { + compiler.getMessageHandler().handleMessage(msg); + } +} diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java new file mode 100644 index 000000000..9cc5ecfc9 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildNotifierAdapter.java @@ -0,0 +1,50 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 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: + * Xerox/PARC initial implementation + * Helen Hawkins converted to new interface (pr148190) + * ******************************************************************/ + + +package org.aspectj.ajde.core.internal; + +import org.aspectj.ajde.core.IBuildProgressMonitor; +import org.aspectj.bridge.IProgressListener; + +/** + * Enables the compiler/weaver progres to be related to the user via the + * IBuildProgressMonitor as well as relating whether or not the user has + * cancelled the build progress back to the compiler/weaver. + */ +public class AjdeCoreBuildNotifierAdapter implements IProgressListener { + + private IBuildProgressMonitor progressMonitor; + + public AjdeCoreBuildNotifierAdapter(IBuildProgressMonitor progressMonitor) { + this.progressMonitor = progressMonitor; + } + + public void setProgress(double percentDone) { + progressMonitor.setProgress(percentDone); + } + + public void setText(String text) { + progressMonitor.setProgressText(text); + } + + public boolean isCancelledRequested() { + return progressMonitor.isCancelRequested(); + } + + public void setCancelledRequested(boolean cancelRequested) { + // do nothing - since ask the progressMonitor whether + // cancel has been requested + } + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java new file mode 100644 index 000000000..8cb53e047 --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreMessageHandlerAdapter.java @@ -0,0 +1,47 @@ +/******************************************************************** + * Copyright (c) 2007 Contributors. 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://eclipse.org/legal/epl-v10.html + * + * Contributors: IBM Corporation - initial API and implementation + * Helen Hawkins - initial version (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core.internal; + +import org.aspectj.ajde.core.IBuildMessageHandler; +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.IMessage.Kind; + +/** + * Enables the messages from the compiler/weaver to be passed on + * to the tool's implementation so they can handle it as they wish + */ +public class AjdeCoreMessageHandlerAdapter implements IMessageHandler { + + private IBuildMessageHandler handler; + + public AjdeCoreMessageHandlerAdapter(IBuildMessageHandler messageHandler) { + this.handler = messageHandler; + } + + public void dontIgnore(Kind kind) { + handler.dontIgnore(kind); + } + + public boolean handleMessage(IMessage message) throws AbortException { + return handler.handleMessage(message); + } + + public void ignore(Kind kind) { + handler.ignore(kind); + } + + public boolean isIgnoring(Kind kind) { + return handler.isIgnoring(kind); + } + +} diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java b/ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java new file mode 100644 index 000000000..95c12daee --- /dev/null +++ b/ajde.core/src/org/aspectj/ajde/core/internal/OutputLocationAdapter.java @@ -0,0 +1,48 @@ +/******************************************************************** + * Copyright (c) 2006 Contributors.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://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer Initial implementation + * Helen Hawkins converted to new interface (bug 148190) + * + *******************************************************************/ +package org.aspectj.ajde.core.internal; + +import java.io.File; +import java.util.List; + +import org.aspectj.ajde.core.IOutputLocationManager; +import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager; + +/** + * Enables the output locations detailed by the IOutputLocationManager + * implementation to be related to the comipler/weaver. + */ +public class OutputLocationAdapter implements CompilationResultDestinationManager { + + private IOutputLocationManager locationManager; + + public OutputLocationAdapter(IOutputLocationManager mgr) { + this.locationManager = mgr; + } + + public File getOutputLocationForClass(File compilationUnit) { + return this.locationManager.getOutputLocationForClass(compilationUnit); + } + + public File getOutputLocationForResource(File resource) { + return this.locationManager.getOutputLocationForResource(resource); + } + + public List getAllOutputLocations() { + return this.locationManager.getAllOutputLocations(); + } + + public File getDefaultOutputLocation() { + return this.locationManager.getDefaultOutputLocation(); + } +} |