From: aclement Date: Thu, 11 Jan 2007 16:04:29 +0000 (+0000) Subject: new ajde.core module X-Git-Tag: Root_extensions~44 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=cfd711b9628154e0b2eb2df174124699cf831f83;p=aspectj.git new ajde.core module --- diff --git a/ajde.core/.classpath b/ajde.core/.classpath new file mode 100644 index 000000000..10c7d9acc --- /dev/null +++ b/ajde.core/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/ajde.core/.project b/ajde.core/.project new file mode 100644 index 000000000..f3d567292 --- /dev/null +++ b/ajde.core/.project @@ -0,0 +1,17 @@ + + + ajde.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/ajde.core/build.xml b/ajde.core/build.xml new file mode 100644 index 000000000..f51fa5690 --- /dev/null +++ b/ajde.core/build.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/ajde.core/coverage.ajsym b/ajde.core/coverage.ajsym new file mode 100644 index 000000000..6fbf05142 Binary files /dev/null and b/ajde.core/coverage.ajsym differ 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. + * + *

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. + *

+ * 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)} + *

+ * + * @return table of current settings of all options + * (key type: String; value type: String) + * @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, /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 ""; + 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 ""; + 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(); + } +} diff --git a/ajde.core/testdata/BuildCancelling/.cvsignore b/ajde.core/testdata/BuildCancelling/.cvsignore new file mode 100644 index 000000000..ba077a403 --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/ajde.core/testdata/BuildCancelling/A1.aj b/ajde.core/testdata/BuildCancelling/A1.aj new file mode 100644 index 000000000..35963153d --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/A1.aj @@ -0,0 +1,9 @@ + +public aspect A1 { + + pointcut m1(): execution(* main(..)); + + before(): m1() { + System.err.println("Before main runs"); + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/A2.aj b/ajde.core/testdata/BuildCancelling/A2.aj new file mode 100644 index 000000000..21755f62e --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/A2.aj @@ -0,0 +1,9 @@ + +public aspect A2 { + + pointcut m1(): execution(* main(..)); + + after(): m1() { + System.err.println("After main runs"); + } +} diff --git a/ajde.core/testdata/BuildCancelling/A3.aj b/ajde.core/testdata/BuildCancelling/A3.aj new file mode 100644 index 000000000..fa7caa9e0 --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/A3.aj @@ -0,0 +1,9 @@ + +public aspect A3 { + + pointcut m1(): call(* *print*(..)); + + before(): m1() { + System.err.println("Calling print"); + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/A4.aj b/ajde.core/testdata/BuildCancelling/A4.aj new file mode 100644 index 000000000..aa999438c --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/A4.aj @@ -0,0 +1,9 @@ + +public aspect A4 { + + pointcut m1(): call(* *print*(..)); + + after(): m1() { + System.err.println("After call to print"); + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/Cl1.java b/ajde.core/testdata/BuildCancelling/Cl1.java new file mode 100644 index 000000000..7652142c6 --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/Cl1.java @@ -0,0 +1,4 @@ +public class Cl1 { + public static void main(String[] args) { + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/Cl2.java b/ajde.core/testdata/BuildCancelling/Cl2.java new file mode 100644 index 000000000..8ba3e49ed --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/Cl2.java @@ -0,0 +1,4 @@ +public class Cl2 { + public static void main(String[] args) { + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/Cl3.java b/ajde.core/testdata/BuildCancelling/Cl3.java new file mode 100644 index 000000000..0b3b301df --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/Cl3.java @@ -0,0 +1,4 @@ +public class Cl3 { + public static void callPrint(String s) { + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/EvenMoreCode.lst b/ajde.core/testdata/BuildCancelling/EvenMoreCode.lst new file mode 100644 index 000000000..e75c6c190 --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/EvenMoreCode.lst @@ -0,0 +1,10 @@ +A1.aj +Cl1.java +A2.aj +Cl2.java +HW.java +A3.aj +Cl3.java +A4.aj +-verbose +-noExit diff --git a/ajde.core/testdata/BuildCancelling/HW.java b/ajde.core/testdata/BuildCancelling/HW.java new file mode 100644 index 000000000..3f8aaf831 --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/HW.java @@ -0,0 +1,13 @@ + +public class HW { + public static void main(String[] args) { + callPrint("Hello"); + callPrint(" "); + callPrint("World"); + callPrint("\n"); + } + + public static void callPrint(String s) { + System.out.print(s); + } +} \ No newline at end of file diff --git a/ajde.core/testdata/BuildCancelling/LoadsaCode.lst b/ajde.core/testdata/BuildCancelling/LoadsaCode.lst new file mode 100644 index 000000000..7a8b6979e --- /dev/null +++ b/ajde.core/testdata/BuildCancelling/LoadsaCode.lst @@ -0,0 +1,7 @@ +A1.aj +A2.aj +HW.java +A3.aj +A4.aj +-verbose +-noExit diff --git a/ajde.core/testdata/DuplicateManifestTest/META-INF/MANIFEST.MF b/ajde.core/testdata/DuplicateManifestTest/META-INF/MANIFEST.MF new file mode 100644 index 000000000..4df943e3b --- /dev/null +++ b/ajde.core/testdata/DuplicateManifestTest/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: DuplicateManifestTest + diff --git a/ajde.core/testdata/DuplicateManifestTest/META-INF/test.xml b/ajde.core/testdata/DuplicateManifestTest/META-INF/test.xml new file mode 100644 index 000000000..f9efa1f1f --- /dev/null +++ b/ajde.core/testdata/DuplicateManifestTest/META-INF/test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/ajde.core/testdata/DuplicateManifestTest/aspectjar.jar b/ajde.core/testdata/DuplicateManifestTest/aspectjar.jar new file mode 100644 index 000000000..5cd3fa0b2 Binary files /dev/null and b/ajde.core/testdata/DuplicateManifestTest/aspectjar.jar differ diff --git a/ajde.core/testdata/DuplicateManifestTest/injar.jar b/ajde.core/testdata/DuplicateManifestTest/injar.jar new file mode 100644 index 000000000..b5a7bd5dc Binary files /dev/null and b/ajde.core/testdata/DuplicateManifestTest/injar.jar differ diff --git a/ajde.core/testdata/DuplicateManifestTest/update-injar.xml b/ajde.core/testdata/DuplicateManifestTest/update-injar.xml new file mode 100644 index 000000000..7ce4c1452 --- /dev/null +++ b/ajde.core/testdata/DuplicateManifestTest/update-injar.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ajde.core/testdata/InpathTest/build.lst b/ajde.core/testdata/InpathTest/build.lst new file mode 100644 index 000000000..6ea6b7117 --- /dev/null +++ b/ajde.core/testdata/InpathTest/build.lst @@ -0,0 +1 @@ +src1/Main.java diff --git a/ajde.core/testdata/InpathTest/build2.lst b/ajde.core/testdata/InpathTest/build2.lst new file mode 100644 index 000000000..0a8c84b41 --- /dev/null +++ b/ajde.core/testdata/InpathTest/build2.lst @@ -0,0 +1 @@ +src2/Aspect.java diff --git a/ajde.core/testdata/InpathTest/indir1/META-INF/MANIFEST.MF b/ajde.core/testdata/InpathTest/indir1/META-INF/MANIFEST.MF new file mode 100644 index 000000000..97e745a4f --- /dev/null +++ b/ajde.core/testdata/InpathTest/indir1/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: 1.3.1_04 (Sun Microsystems Inc.) + diff --git a/ajde.core/testdata/InpathTest/indir1/META-INF/test.xml b/ajde.core/testdata/InpathTest/indir1/META-INF/test.xml new file mode 100644 index 000000000..f9efa1f1f --- /dev/null +++ b/ajde.core/testdata/InpathTest/indir1/META-INF/test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/ajde.core/testdata/InpathTest/indir1/test/TestProperties.class b/ajde.core/testdata/InpathTest/indir1/test/TestProperties.class new file mode 100644 index 000000000..a58740c20 Binary files /dev/null and b/ajde.core/testdata/InpathTest/indir1/test/TestProperties.class differ diff --git a/ajde.core/testdata/InpathTest/indir1/test/test.props b/ajde.core/testdata/InpathTest/indir1/test/test.props new file mode 100644 index 000000000..8462a7ab6 --- /dev/null +++ b/ajde.core/testdata/InpathTest/indir1/test/test.props @@ -0,0 +1 @@ +test=test2 \ No newline at end of file diff --git a/ajde.core/testdata/InpathTest/indir2/example/HelloWorld.class b/ajde.core/testdata/InpathTest/indir2/example/HelloWorld.class new file mode 100644 index 000000000..e333988e6 Binary files /dev/null and b/ajde.core/testdata/InpathTest/indir2/example/HelloWorld.class differ diff --git a/ajde.core/testdata/InpathTest/indir2/example/HelloWorld.java b/ajde.core/testdata/InpathTest/indir2/example/HelloWorld.java new file mode 100644 index 000000000..476abc7ee --- /dev/null +++ b/ajde.core/testdata/InpathTest/indir2/example/HelloWorld.java @@ -0,0 +1,12 @@ +package example; + +public class HelloWorld { + + public static void say(String msg) { + System.err.println(msg); + } + + public static void main(String []argv) { + say("hello world"); + } +} diff --git a/ajde.core/testdata/InpathTest/injar.jar b/ajde.core/testdata/InpathTest/injar.jar new file mode 100644 index 000000000..7dcd06f97 Binary files /dev/null and b/ajde.core/testdata/InpathTest/injar.jar differ diff --git a/ajde.core/testdata/InpathTest/src1/Main.java b/ajde.core/testdata/InpathTest/src1/Main.java new file mode 100644 index 000000000..417fc6809 --- /dev/null +++ b/ajde.core/testdata/InpathTest/src1/Main.java @@ -0,0 +1,22 @@ +import java.io.IOException; + +/* + * Created on 30-Jul-03 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ + +/** + * @author websterm + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class Main { + + public static void main(String[] args) throws IOException { + String propsName = (args.length > 0)? args[0] : "test.props"; + new test.TestProperties().load(propsName); + } +} diff --git a/ajde.core/testdata/InpathTest/src2/Aspect.java b/ajde.core/testdata/InpathTest/src2/Aspect.java new file mode 100644 index 000000000..c70994870 --- /dev/null +++ b/ajde.core/testdata/InpathTest/src2/Aspect.java @@ -0,0 +1,7 @@ +public aspect Aspect { + pointcut sayCalls(): call(* say(..)); + + before(): sayCalls() { + System.err.println("Before say()"); + } +} diff --git a/ajde.core/testdata/JarManifestTest/noweave.lst b/ajde.core/testdata/JarManifestTest/noweave.lst new file mode 100644 index 000000000..823461cc1 --- /dev/null +++ b/ajde.core/testdata/JarManifestTest/noweave.lst @@ -0,0 +1,3 @@ +src/Main.java +src/Logging.aj +-XterminateAfterCompilation \ No newline at end of file diff --git a/ajde.core/testdata/JarManifestTest/src/Logging.aj b/ajde.core/testdata/JarManifestTest/src/Logging.aj new file mode 100644 index 000000000..6521a537e --- /dev/null +++ b/ajde.core/testdata/JarManifestTest/src/Logging.aj @@ -0,0 +1,13 @@ +public aspect Logging { + + pointcut methods () : + execution(* *..*(..)) && !within(Logging); + + before () : methods () { + System.err.println("> " + thisJoinPoint.getSignature().toLongString()); + } + + after () : methods () { + System.err.println("< " + thisJoinPoint.getSignature().toLongString()); + } +} diff --git a/ajde.core/testdata/JarManifestTest/src/Main.java b/ajde.core/testdata/JarManifestTest/src/Main.java new file mode 100644 index 000000000..94369dd8e --- /dev/null +++ b/ajde.core/testdata/JarManifestTest/src/Main.java @@ -0,0 +1,25 @@ +import java.io.IOException; + +/* + * Created on 30-Jul-03 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ + +/** + * @author websterm + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class Main { + + public void println () { + System.out.println("Main."); + } + + public static void main(String[] args) throws IOException { + new Main().println(); + } +} diff --git a/ajde.core/testdata/JarManifestTest/weave.lst b/ajde.core/testdata/JarManifestTest/weave.lst new file mode 100644 index 000000000..32a7c1649 --- /dev/null +++ b/ajde.core/testdata/JarManifestTest/weave.lst @@ -0,0 +1,2 @@ +src/Main.java +src/Logging.aj diff --git a/ajde.core/testdata/OutxmlTest/outxml-to-file.lst b/ajde.core/testdata/OutxmlTest/outxml-to-file.lst new file mode 100644 index 000000000..596118fab --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/outxml-to-file.lst @@ -0,0 +1,5 @@ +src/TestClass.java +src/TestInterface.java +src/TestAbstractAspect.aj +src/TestConcreteAspect.aj +-outxml diff --git a/ajde.core/testdata/OutxmlTest/outxml-to-outjar-with-aop_xml.ajsym b/ajde.core/testdata/OutxmlTest/outxml-to-outjar-with-aop_xml.ajsym new file mode 100644 index 000000000..e2b8cc250 --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/outxml-to-outjar-with-aop_xml.ajsym @@ -0,0 +1 @@ +’ \ No newline at end of file diff --git a/ajde.core/testdata/OutxmlTest/outxml-to-outjar-with-aop_xml.lst b/ajde.core/testdata/OutxmlTest/outxml-to-outjar-with-aop_xml.lst new file mode 100644 index 000000000..87c980224 --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/outxml-to-outjar-with-aop_xml.lst @@ -0,0 +1 @@ +-outxml diff --git a/ajde.core/testdata/OutxmlTest/outxml-to-outjar.lst b/ajde.core/testdata/OutxmlTest/outxml-to-outjar.lst new file mode 100644 index 000000000..596118fab --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/outxml-to-outjar.lst @@ -0,0 +1,5 @@ +src/TestClass.java +src/TestInterface.java +src/TestAbstractAspect.aj +src/TestConcreteAspect.aj +-outxml diff --git a/ajde.core/testdata/OutxmlTest/outxmlfile-to-file.lst b/ajde.core/testdata/OutxmlTest/outxmlfile-to-file.lst new file mode 100644 index 000000000..e29e8220f --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/outxmlfile-to-file.lst @@ -0,0 +1,6 @@ +src/TestClass.java +src/TestInterface.java +src/TestAbstractAspect.aj +src/TestConcreteAspect.aj +-outxmlfile +custom/aop.xml diff --git a/ajde.core/testdata/OutxmlTest/outxmlfile-to-outjar.lst b/ajde.core/testdata/OutxmlTest/outxmlfile-to-outjar.lst new file mode 100644 index 000000000..e29e8220f --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/outxmlfile-to-outjar.lst @@ -0,0 +1,6 @@ +src/TestClass.java +src/TestInterface.java +src/TestAbstractAspect.aj +src/TestConcreteAspect.aj +-outxmlfile +custom/aop.xml diff --git a/ajde.core/testdata/OutxmlTest/src-resources/META-INF/aop-ajc.xml b/ajde.core/testdata/OutxmlTest/src-resources/META-INF/aop-ajc.xml new file mode 100644 index 000000000..77505c753 --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/src-resources/META-INF/aop-ajc.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/ajde.core/testdata/OutxmlTest/src-resources/testjar.jar b/ajde.core/testdata/OutxmlTest/src-resources/testjar.jar new file mode 100644 index 000000000..3da389fdf Binary files /dev/null and b/ajde.core/testdata/OutxmlTest/src-resources/testjar.jar differ diff --git a/ajde.core/testdata/OutxmlTest/src/TestAbstractAspect.aj b/ajde.core/testdata/OutxmlTest/src/TestAbstractAspect.aj new file mode 100644 index 000000000..df7596863 --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/src/TestAbstractAspect.aj @@ -0,0 +1,3 @@ +public abstract aspect TestAbstractAspect { + +} diff --git a/ajde.core/testdata/OutxmlTest/src/TestClass.java b/ajde.core/testdata/OutxmlTest/src/TestClass.java new file mode 100644 index 000000000..38bf5906b --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/src/TestClass.java @@ -0,0 +1,3 @@ +public class TestClass { + +} diff --git a/ajde.core/testdata/OutxmlTest/src/TestConcreteAspect.aj b/ajde.core/testdata/OutxmlTest/src/TestConcreteAspect.aj new file mode 100644 index 000000000..deb065e02 --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/src/TestConcreteAspect.aj @@ -0,0 +1,3 @@ +public aspect TestConcreteAspect { + +} diff --git a/ajde.core/testdata/OutxmlTest/src/TestInterface.java b/ajde.core/testdata/OutxmlTest/src/TestInterface.java new file mode 100644 index 000000000..86d3ce968 --- /dev/null +++ b/ajde.core/testdata/OutxmlTest/src/TestInterface.java @@ -0,0 +1,3 @@ +public interface TestInterface { + +} diff --git a/ajde.core/testdata/ReweavableTest/CalculatePI.java b/ajde.core/testdata/ReweavableTest/CalculatePI.java new file mode 100644 index 000000000..84ae08583 --- /dev/null +++ b/ajde.core/testdata/ReweavableTest/CalculatePI.java @@ -0,0 +1,26 @@ +import java.util.Random; + +public class CalculatePI { + + static Random r = new Random(); + static double piApproximation = 1.0f; + static int repetitions = 500000; + static int iteration = 0; + static double inSquare = 0; + static double inCircle = 0; + + public static void main(String[] args) { + for (iteration = 0;iteration + + + + + + + + + + + + + + + diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt new file mode 100644 index 000000000..eab1c861a --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.nodebug.txt @@ -0,0 +1,13 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (no debug info available) advised by around advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:24(from AspectAdvice.aj)) [with runtime test] +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by before advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by after advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (no debug info available) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice_nodebug.jar!AspectAdvice.class:20(from AspectAdvice.aj)) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.jar.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.jar.txt new file mode 100644 index 000000000..1c9e788bb --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.jar.txt @@ -0,0 +1,4 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.jar!AspectInPackage.class:7(from AspectInPackage.aj)) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.txt new file mode 100644 index 000000000..d86780069 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.package.txt @@ -0,0 +1,4 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'pkg.AspectInPackage' (AspectInPackage.class:7(from AspectInPackage.aj)) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt new file mode 100644 index 000000000..9ed2ca073 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.binary.txt @@ -0,0 +1,13 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by after advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by after advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:20(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by around advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:24(from AspectAdvice.aj)) [with runtime test] +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:8(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by after advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:12(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:16(from AspectAdvice.aj)) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.jar!AspectAdvice.class:20(from AspectAdvice.aj)) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.txt new file mode 100644 index 000000000..03d6c4574 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/advice.txt @@ -0,0 +1,13 @@ +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) +Join point 'method-execution(void Simple.m1())' in Type 'Simple' (Simple.java:5) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) +Join point 'method-execution(java.lang.String Simple.m2())' in Type 'Simple' (Simple.java:9) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) +Join point 'method-execution(void Simple.main(java.lang.String[]))' in Type 'Simple' (Simple.java:13) advised by around advice from 'AspectAdvice' (AspectAdvice.aj:24) [with runtime test] +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by before advice from 'AspectAdvice' (AspectAdvice.aj:8) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by after advice from 'AspectAdvice' (AspectAdvice.aj:12) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterReturning advice from 'AspectAdvice' (AspectAdvice.aj:16) +Join point 'method-execution(void Simple.mSecret())' in Type 'Simple' (Simple.java:17) advised by afterThrowing advice from 'AspectAdvice' (AspectAdvice.aj:20) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.annotation.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.annotation.txt new file mode 100644 index 000000000..7daacb75d --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.annotation.txt @@ -0,0 +1,4 @@ +'Test' (AspectDeclareAnnotations.aj:14) is annotated with @anInterface type annotation from 'AspectDeclareAnnotations' (AspectDeclareAnnotations.aj:7) +'public void Test.new(String,int)' (AspectDeclareAnnotations.aj:16) is annotated with @anInterface constructor annotation from 'AspectDeclareAnnotations' (AspectDeclareAnnotations.aj:8) +'public int Test.fac(int)' (AspectDeclareAnnotations.aj:20) is annotated with @anInterface method annotation from 'AspectDeclareAnnotations' (AspectDeclareAnnotations.aj:9) +'public int a' of type 'Test' (AspectDeclareAnnotations.aj) is annotated with @anInterface field annotation from 'AspectDeclareAnnotations' (AspectDeclareAnnotations.aj:10) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.annotationNoWeaveInfo.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.annotationNoWeaveInfo.txt new file mode 100644 index 000000000..e69de29bb diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.extends.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.extends.txt new file mode 100644 index 000000000..29fb45592 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.extends.txt @@ -0,0 +1 @@ +Setting superclass of type 'Simple' (Simple.java) to 'InTheWay' (AspectDeclareExtends.aj) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.nodebug.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.nodebug.txt new file mode 100644 index 000000000..2a326c0e3 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.nodebug.txt @@ -0,0 +1,2 @@ +Softening exceptions in type 'Simple' (no debug info available) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft_nodebug.jar!AspectDeclareSoft.class:4(from AspectDeclareSoft.aj)) +Softening exceptions in type 'Simple' (no debug info available) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft_nodebug.jar!AspectDeclareSoft.class:6(from AspectDeclareSoft.aj)) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.txt new file mode 100644 index 000000000..e1f3522dc --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.binary.txt @@ -0,0 +1,2 @@ +Softening exceptions in type 'Simple' (Simple.java:13) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.jar!AspectDeclareSoft.class:4(from AspectDeclareSoft.aj)) +Softening exceptions in type 'Simple' (Simple.java:13) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.jar!AspectDeclareSoft.class:6(from AspectDeclareSoft.aj)) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.nodebug.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.nodebug.txt new file mode 100644 index 000000000..d64a942e3 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.nodebug.txt @@ -0,0 +1,2 @@ +Softening exceptions in type 'Simple' (no debug info available) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.aj:4) +Softening exceptions in type 'Simple' (no debug info available) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.aj:6) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.txt new file mode 100644 index 000000000..234d3228b --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare.soft.txt @@ -0,0 +1,2 @@ +Softening exceptions in type 'Simple' (Simple.java:13) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.aj:6) +Softening exceptions in type 'Simple' (Simple.java:13) as defined by aspect 'AspectDeclareSoft' (AspectDeclareSoft.aj:4) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare1.nodebug.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare1.nodebug.txt new file mode 100644 index 000000000..1da4b502c --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare1.nodebug.txt @@ -0,0 +1 @@ +Extending interface set for type 'Simple' (no debug info available) to include 'MarkerInterface' (AspectDeclare.aj) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare1.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare1.txt new file mode 100644 index 000000000..b05cdfb86 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/declare1.txt @@ -0,0 +1 @@ +Extending interface set for type 'Simple' (Simple.java) to include 'MarkerInterface' (AspectDeclare.aj) diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/itd.nodebug.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/itd.nodebug.txt new file mode 100644 index 000000000..0664ed4e0 --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/itd.nodebug.txt @@ -0,0 +1,4 @@ +Type 'Simple' (no debug info available) has intertyped field from 'AspectITD' (AspectITD.aj:'int Simple.fieldint') +Type 'Simple' (no debug info available) has intertyped field from 'AspectITD' (AspectITD.aj:'java.lang.String Simple.fieldstring') +Type 'Simple' (no debug info available) has intertyped method from 'AspectITD' (AspectITD.aj:'int Simple.returnint()') +Type 'Simple' (no debug info available) has intertyped method from 'AspectITD' (AspectITD.aj:'java.lang.String Simple.returnstring()') diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/expected/itd.txt b/ajde.core/testdata/WeaveInfoMessagesTest/expected/itd.txt new file mode 100644 index 000000000..eeb84247e --- /dev/null +++ b/ajde.core/testdata/WeaveInfoMessagesTest/expected/itd.txt @@ -0,0 +1,4 @@ +Type 'Simple' (Simple.java) has intertyped field from 'AspectITD' (AspectITD.aj:'int Simple.fieldint') +Type 'Simple' (Simple.java) has intertyped field from 'AspectITD' (AspectITD.aj:'java.lang.String Simple.fieldstring') +Type 'Simple' (Simple.java) has intertyped method from 'AspectITD' (AspectITD.aj:'int Simple.returnint()') +Type 'Simple' (Simple.java) has intertyped method from 'AspectITD' (AspectITD.aj:'java.lang.String Simple.returnstring()') diff --git a/ajde.core/testdata/WeaveInfoMessagesTest/pkg/AspectInPackage.class b/ajde.core/testdata/WeaveInfoMessagesTest/pkg/AspectInPackage.class new file mode 100644 index 000000000..cc11cd2ca Binary files /dev/null and b/ajde.core/testdata/WeaveInfoMessagesTest/pkg/AspectInPackage.class differ diff --git a/ajde.core/testdata/bug-36071a/config1.lst b/ajde.core/testdata/bug-36071a/config1.lst new file mode 100644 index 000000000..e1a10a7f6 --- /dev/null +++ b/ajde.core/testdata/bug-36071a/config1.lst @@ -0,0 +1,2 @@ +src/Main.java +src/testsrc/TestProperties.java diff --git a/ajde.core/testdata/bug-36071a/config2.lst b/ajde.core/testdata/bug-36071a/config2.lst new file mode 100644 index 000000000..5657df30e --- /dev/null +++ b/ajde.core/testdata/bug-36071a/config2.lst @@ -0,0 +1 @@ +src/aspects/Logging.java diff --git a/ajde.core/testdata/bug-36071a/input1 b/ajde.core/testdata/bug-36071a/input1 new file mode 100644 index 000000000..cc7183fdd Binary files /dev/null and b/ajde.core/testdata/bug-36071a/input1 differ diff --git a/ajde.core/testdata/bug-36071a/input1.jar b/ajde.core/testdata/bug-36071a/input1.jar new file mode 100644 index 000000000..cc7183fdd Binary files /dev/null and b/ajde.core/testdata/bug-36071a/input1.jar differ diff --git a/ajde.core/testdata/bug-36071a/input2.jar b/ajde.core/testdata/bug-36071a/input2.jar new file mode 100644 index 000000000..ff8b20a65 Binary files /dev/null and b/ajde.core/testdata/bug-36071a/input2.jar differ diff --git a/ajde.core/testdata/bug-36071a/src/Main.java b/ajde.core/testdata/bug-36071a/src/Main.java new file mode 100644 index 000000000..417fc6809 --- /dev/null +++ b/ajde.core/testdata/bug-36071a/src/Main.java @@ -0,0 +1,22 @@ +import java.io.IOException; + +/* + * Created on 30-Jul-03 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ + +/** + * @author websterm + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class Main { + + public static void main(String[] args) throws IOException { + String propsName = (args.length > 0)? args[0] : "test.props"; + new test.TestProperties().load(propsName); + } +} diff --git a/ajde.core/testdata/bug-36071a/src/aspects/Logging.java b/ajde.core/testdata/bug-36071a/src/aspects/Logging.java new file mode 100644 index 000000000..2e8ba485a --- /dev/null +++ b/ajde.core/testdata/bug-36071a/src/aspects/Logging.java @@ -0,0 +1,27 @@ +/* + * Created on 30-Jul-03 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package aspects; + +/** + * @author websterm + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public aspect Logging { + + pointcut methods () : + execution(* *..*(..)) && !within(Logging); + + before () : methods () { + System.err.println("> " + thisJoinPoint.getSignature().toLongString()); + } + + after () : methods () { + System.err.println("< " + thisJoinPoint.getSignature().toLongString()); + } +} diff --git a/ajde.core/testdata/bug-36071a/src/testsrc/TestProperties.java b/ajde.core/testdata/bug-36071a/src/testsrc/TestProperties.java new file mode 100644 index 000000000..18139e035 --- /dev/null +++ b/ajde.core/testdata/bug-36071a/src/testsrc/TestProperties.java @@ -0,0 +1,29 @@ +/* + * Created on 30-Jul-03 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * @author websterm + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class TestProperties { + + public void load (String name) throws IOException { + InputStream in = getClass().getResourceAsStream(name); +// System.out.println("? load() in=" + in); + Properties props = new Properties(); + props.load(in); + in.close(); + props.list(System.out); + } +} diff --git a/ajde.core/testdata/bug-36071a/src/testsrc/test.props b/ajde.core/testdata/bug-36071a/src/testsrc/test.props new file mode 100644 index 000000000..51e670ac7 --- /dev/null +++ b/ajde.core/testdata/bug-36071a/src/testsrc/test.props @@ -0,0 +1 @@ +test=test \ No newline at end of file diff --git a/ajde.core/testdata/coverage/.cvsignore b/ajde.core/testdata/coverage/.cvsignore new file mode 100644 index 000000000..17637b455 --- /dev/null +++ b/ajde.core/testdata/coverage/.cvsignore @@ -0,0 +1 @@ +*.ajsym diff --git a/ajde.core/testdata/coverage/ModelCoverage.java b/ajde.core/testdata/coverage/ModelCoverage.java new file mode 100644 index 000000000..a853ec83d --- /dev/null +++ b/ajde.core/testdata/coverage/ModelCoverage.java @@ -0,0 +1,161 @@ + +import java.io.*; +import java.util.List; + +interface I { } + +class Point { + int x; + static int sx; + + { + System.out.println(""); + } + + { x = 0; } + static { sx = 1; } + + public Point() { } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int changeX(int x) { + this.x = x; + return x; + } + + void doIt() { + try { + File f = new File("."); + f.getCanonicalPath(); + } catch (IOException ioe) { + System.err.println("!"); + } + setX(10); + new Point(); + } +} + +class SubPoint extends Point { } + +class Line { } + +aspect AdvisesRelationshipCoverage { + pointcut methodExecutionP(): execution(void Point.setX(int)); + before(): methodExecutionP() { } + + pointcut constructorExecutionP(): execution(Point.new()); + before(): constructorExecutionP() { } + + pointcut callMethodP(): call(* Point.setX(int)); + before(): callMethodP() { } + + pointcut callConstructorP(): call(Point.new()); + before(): callConstructorP() { } + + pointcut getP(): get(int *.*); + before(): getP() { } + + pointcut setP(): set(int *.*) && !set(int *.xxx); + before(): setP() { } + + pointcut initializationP(): initialization(Point.new(..)); + before(): initializationP() { } + + pointcut staticinitializationP(): staticinitialization(Point); + before(): staticinitializationP() { } + + pointcut handlerP(): handler(IOException); + before(): handlerP() { } + +// before(): within(*) && execution(* Point.setX(..)) { } +// before(): within(*) && execution(Point.new()) { } +} + +aspect AdviceNamingCoverage { + pointcut named(): call(* *.mumble()); + pointcut namedWithOneArg(int i): call(int Point.changeX(int)) && args(i); + pointcut namedWithArgs(int i, int j): set(int Point.x) && args(i, j); + + after(): named() { } + after(int i, int j) returning: namedWithArgs(i, j) { } + after() throwing: named() { } + after(): named() { } + + before(): named() { } + + int around(int i): namedWithOneArg(i) { return i;} + int around(int i) throws SizeException: namedWithOneArg(i) { return proceed(i); } + + before(): named() { } + before(int i): call(* *.mumble()) && named() && namedWithOneArg(i) { } + before(int i): named() && call(* *.mumble()) && namedWithOneArg(i) { } + + before(): call(* *.mumble()) { } +} + +abstract aspect AbstractAspect { + abstract pointcut abPtct(); +} + +aspect InterTypeDecCoverage { + public int Point.xxx = 0; + public int Point.check(int i, Line l) { return 1 + i; } +} + +aspect DeclareCoverage { + + pointcut illegalNewFigElt(): call(Point.new(..)) && !withincode(* *.doIt(..)); + + declare error: illegalNewFigElt(): "Illegal constructor call."; + declare warning: call(* Point.setX(..)): "Illegal call."; + + declare parents: Point extends java.io.Serializable; + declare parents: Point+ implements java.util.Observable; + declare parents: Point && Line implements java.util.Observable; + declare soft: SizeException : call(* Point.getX()); + declare precedence: AdviceCoverage, InterTypeDecCoverage, *; +// public Line.new(String s) { } +} + +class SizeException extends Exception { } + +aspect AdviceCoverage { + +} + +abstract class ModifiersCoverage { + private int a; + protected int b; + public int c; + int d; + + static int staticA; + final int finalA = 0; + + abstract void abstractM(); +} + +aspect Pointcuts { + pointcut a(): call(Point.new(..)); +} + +aspect PointcutUsage { + + pointcut usesA(): Pointcuts.a() && within(Point); + + pointcut usesUsesA(): usesA(); + + after(): usesUsesA() { } +} + + + + + diff --git a/ajde.core/testdata/coverage/coverage.lst b/ajde.core/testdata/coverage/coverage.lst new file mode 100644 index 000000000..9857809b9 --- /dev/null +++ b/ajde.core/testdata/coverage/coverage.lst @@ -0,0 +1,2 @@ +ModelCoverage.java +pkg/InPackage.java diff --git a/ajde.core/testdata/coverage/pkg/InPackage.java b/ajde.core/testdata/coverage/pkg/InPackage.java new file mode 100644 index 000000000..3e3bc8aa4 --- /dev/null +++ b/ajde.core/testdata/coverage/pkg/InPackage.java @@ -0,0 +1,4 @@ + +package pkg; + +public interface InPackage { } \ No newline at end of file diff --git a/ajde.core/testdata/declare-warning/apackage/InitCatcher.java b/ajde.core/testdata/declare-warning/apackage/InitCatcher.java new file mode 100644 index 000000000..efa19bba6 --- /dev/null +++ b/ajde.core/testdata/declare-warning/apackage/InitCatcher.java @@ -0,0 +1,11 @@ +package apackage; + +public aspect InitCatcher { + + declare warning: call(* *.init(..)) : + "Please don't call init methods"; + + declare warning: set(* SomeClass.*) : + "Please don't call setters"; + +} \ No newline at end of file diff --git a/ajde.core/testdata/declare-warning/apackage/SomeClass.java b/ajde.core/testdata/declare-warning/apackage/SomeClass.java new file mode 100644 index 000000000..bb34db820 --- /dev/null +++ b/ajde.core/testdata/declare-warning/apackage/SomeClass.java @@ -0,0 +1,15 @@ +package apackage; + +public class SomeClass { + + int x; + + public SomeClass() { + init(); // line 6 + x = 3; + } + + public void init() { + } + +} \ No newline at end of file diff --git a/ajde.core/testdata/figures-coverage/.cvsignore b/ajde.core/testdata/figures-coverage/.cvsignore new file mode 100644 index 000000000..c6495af69 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/.cvsignore @@ -0,0 +1 @@ +all.ajsym diff --git a/ajde.core/testdata/figures-coverage/all.lst b/ajde.core/testdata/figures-coverage/all.lst new file mode 100644 index 000000000..3879af0b1 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/all.lst @@ -0,0 +1,8 @@ +figures/Debug.java +figures/Figure.java +figures/FigureElement.java +figures/Main.java +figures/composites/Line.java +figures/composites/Square.java +figures/primitives/planar/Point.java +figures/primitives/solid/SolidPoint.java diff --git a/ajde.core/testdata/figures-coverage/editor/Editor.java b/ajde.core/testdata/figures-coverage/editor/Editor.java new file mode 100644 index 000000000..99e2b5d5b --- /dev/null +++ b/ajde.core/testdata/figures-coverage/editor/Editor.java @@ -0,0 +1,4 @@ + +package editor; + +class Editor { } diff --git a/ajde.core/testdata/figures-coverage/figures/.cvsignore b/ajde.core/testdata/figures-coverage/figures/.cvsignore new file mode 100644 index 000000000..9a2b438e3 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/.cvsignore @@ -0,0 +1,8 @@ +Checks.class +Debug.class +Element.class +Figure.class +FigureElement.class +Main.class +Main$TestGUI.class +Test.class diff --git a/ajde.core/testdata/figures-coverage/figures/Debug.java b/ajde.core/testdata/figures-coverage/figures/Debug.java new file mode 100644 index 000000000..01e895abc --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/Debug.java @@ -0,0 +1,7 @@ + +package figures; + +aspect Debug { + +} + diff --git a/ajde.core/testdata/figures-coverage/figures/Figure.java b/ajde.core/testdata/figures-coverage/figures/Figure.java new file mode 100644 index 000000000..b5e0e246a --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/Figure.java @@ -0,0 +1,92 @@ + +package figures; + +import figures.primitives.planar.Point; + +import java.awt.Canvas; + +aspect Figure { + //pointcut sendSuccess(): cflow(setX()) && !handler(Exception); + + public String Point.getName() { + return Point.name; + } + + public int figures.primitives.planar.Point.DEFAULT_X = 0; + + public pointcut constructions(): call(Point.new(int, int)) || call(SolidPoint.new(int, int, int)); + + public pointcut moves(FigureElement fe): target(fe) && + (call(String Point.getName()) || + call(void FigureElement.incrXY(int, int)) || + call(void Point.setX(int)) || + call(void Point.setY(int)) || + call(void SolidPoint.setZ(int))); + + pointcut mainExecution(): + execution(int main(*)); + + pointcut runtimeHandlers(): mainExecution() + || handler(RuntimeException); + + public pointcut mumble(): runtimeHandlers(); + + before(int newValue): set(int *.*) && args(newValue) { } + + before(): get(int *.*) { } + + before(): constructions() { + System.out.println("> before construction, jp: " + thisJoinPoint.getSignature()); + } + + before(FigureElement fe): moves(fe) { + System.out.println("> about to move FigureElement at X-coord: "); + } + + after(): initialization(Point.new(..)) || staticinitialization(Point) { + System.out.println("> Point initialized"); + } + + // should be around + after(): mumble() { + System.err.println(">> in after advice..."); + //proceed(); + } + + after(FigureElement fe): target(fe) && + (call(void FigureElement.incrXY(int, int)) || + call(void Point.setX(int)) || + call(void Point.setY(int)) || + call(void SolidPoint.setZ(int))) { + System.out.println("> yo."); + } + + after(FigureElement fe): + target(fe) && + (call(void FigureElement.incrXY(int, int)) || + call(void Line.setP1(Point)) || + call(void Line.setP2(Point)) || + call(void Point.setX(int)) || + call(void Point.setY(int))) { } + + declare parents: Point extends java.io.Serializable; + + declare parents: Point implements java.util.Observable; + + // AMC - this next line doesn't make sense!! Can these tests ever + // have been run??? + //declare soft: Point: call(* *(..)); +} + +aspect Checks { + pointcut illegalNewFigElt(): call(FigureElement+.new(..)) && + !withincode(* Main.main(..)); + +// pointcut illegalNewFigElt(): execution(FigureElement+.new(..)); + + declare error: illegalNewFigElt(): + "Illegal figure element constructor call."; + + declare warning: illegalNewFigElt(): + "Illegal figure element constructor call."; +} diff --git a/ajde.core/testdata/figures-coverage/figures/FigureElement.java b/ajde.core/testdata/figures-coverage/figures/FigureElement.java new file mode 100644 index 000000000..d2ce9eb82 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/FigureElement.java @@ -0,0 +1,9 @@ + +package figures; + +public interface FigureElement extends Element { + + public void incrXY(int dx, int dy); +} + +interface Element { } diff --git a/ajde.core/testdata/figures-coverage/figures/Main.java b/ajde.core/testdata/figures-coverage/figures/Main.java new file mode 100644 index 000000000..189f05cee --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/Main.java @@ -0,0 +1,56 @@ + +package figures; + +import figures.primitives.planar.Point; +import figures.primitives.solid.SolidPoint; + +class Main { + + private static Point startPoint; + + public static void main(String[] args) { + try { + System.out.println("> starting..."); + + startPoint = makeStartPoint(); + //startPoint.setX(3); new Point(0, 0); +// SolidPoint sp1 = new SolidPoint(1, 3, 3); + +// sp1.setZ(1); +// p1.incrXY(3, 3); + } catch (RuntimeException re) { + re.printStackTrace(); + } + System.out.println("> finished."); + } + + /** @deprecated use something else */ + public static Point makeStartPoint() { + //return new Point(1, 2); + return null; + } + + /** This should produce a deprecation warning with JDK > 1.2 */ + static class TestGUI extends javax.swing.JFrame { + TestGUI() { + this.disable(); + } + } + + /** This should produce a porting-deprecation warning. */ + //static pointcut mainExecution(): execution(void main(*)); +} + +privileged aspect Test { + pointcut testptct(): call(* *.*(..)); + + before(Point p, int newval): target(p) && set(int Point.xx) && args(newval) { + System.err.println("> new value of x is: " + p.x + ", setting to: " + newval); + } + + before(int newValue): set(int Point.*) && args(newValue) { + if (newValue < 0) { + throw new IllegalArgumentException("too small"); + } + } +} diff --git a/ajde.core/testdata/figures-coverage/figures/composites/.cvsignore b/ajde.core/testdata/figures-coverage/figures/composites/.cvsignore new file mode 100644 index 000000000..d9011a888 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/composites/.cvsignore @@ -0,0 +1,3 @@ +BoundedLine.class +Line.class +Square.class diff --git a/ajde.core/testdata/figures-coverage/figures/composites/Line.java b/ajde.core/testdata/figures-coverage/figures/composites/Line.java new file mode 100644 index 000000000..1f7ee5dc8 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/composites/Line.java @@ -0,0 +1,6 @@ + +package figures.composites; + +class Line { } + +class BoundedLine extends Line { } diff --git a/ajde.core/testdata/figures-coverage/figures/composites/Square.java b/ajde.core/testdata/figures-coverage/figures/composites/Square.java new file mode 100644 index 000000000..8ba3825d6 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/composites/Square.java @@ -0,0 +1,6 @@ + +package figures.composites; + +class Square { + private String name = "Square"; +} diff --git a/ajde.core/testdata/figures-coverage/figures/primitives/planar/.cvsignore b/ajde.core/testdata/figures-coverage/figures/primitives/planar/.cvsignore new file mode 100644 index 000000000..1dd78c3c0 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/primitives/planar/.cvsignore @@ -0,0 +1,4 @@ +StrictlyBoundedPoint.class +PointBoundsException.class +Point.class +BoundedPoint.class diff --git a/ajde.core/testdata/figures-coverage/figures/primitives/planar/Point.java b/ajde.core/testdata/figures-coverage/figures/primitives/planar/Point.java new file mode 100644 index 000000000..d389be386 --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/primitives/planar/Point.java @@ -0,0 +1,73 @@ + +package figures.primitives.planar; + +import figures.*; +import java.util.Collection; + +public class Point implements FigureElement { + + static int xx = -1; + private int x; + private int y; + transient int currVal = 0; + public static String name; + + { + y = -1; + } + + static { + xx = -10; + } + + int c; int b; int a; + { + x = 0; + y = 0; + } + + static { + Point.name = "2-Dimensional Point"; + } + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + + int getCurrVal() { + return currVal; + } + + /** + * @see Figure#moves + */ + public int getX() { return x; } + + public int getY() { return y; } + + public void setX(int x) { this.x = x; } + + public void setY(int x) { this.y = x; } + + public void incrXY(int dx, int dy) { + setX(getX() + dx); + setY(getY() + dy); + } + public void check(int dx, int dy) + throws ArithmeticException, PointBoundsException { + if (dx < 0 || dy < 0) throw new PointBoundsException(); + } +} + +class PointBoundsException extends Exception { } + +class BoundedPoint extends Point { + public BoundedPoint(int x, int y) { super(x, y); } +} + +class StrictlyBoundedPoint extends BoundedPoint { + public StrictlyBoundedPoint(int x, int y) { super(x, y); } +} + + diff --git a/ajde.core/testdata/figures-coverage/figures/primitives/solid/.cvsignore b/ajde.core/testdata/figures-coverage/figures/primitives/solid/.cvsignore new file mode 100644 index 000000000..fd0572c5e --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/primitives/solid/.cvsignore @@ -0,0 +1 @@ +SolidPoint.class diff --git a/ajde.core/testdata/figures-coverage/figures/primitives/solid/SolidPoint.java b/ajde.core/testdata/figures-coverage/figures/primitives/solid/SolidPoint.java new file mode 100644 index 000000000..80c1fc1ca --- /dev/null +++ b/ajde.core/testdata/figures-coverage/figures/primitives/solid/SolidPoint.java @@ -0,0 +1,24 @@ + +package figures.primitives.solid; + +import java.util.Collection; +import java.lang.String; +import figures.primitives.planar.*; + +public class SolidPoint extends Point { + private int z; + + public SolidPoint(int x, int y, int z) { + super(x, y); + this.z = z; + } + + public int getZ() { return z; } + + public void setZ(int z) { this.z = z; } + + public void incrXY(int dx, int dy) { + super.incrXY(dx, dy); + setZ(getZ() + dx + dy); + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreModuleTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreModuleTests.java new file mode 100644 index 000000000..0015e79ec --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreModuleTests.java @@ -0,0 +1,28 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class AjdeCoreModuleTests extends TestCase { + + public static TestSuite suite() { + TestSuite suite = new TestSuite(AjdeCoreModuleTests.class.getName()); + suite.addTest(org.aspectj.ajde.core.AjdeCoreTests.suite()); + return suite; + } + + public AjdeCoreModuleTests(String name) { + super(name); + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreTestCase.java b/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreTestCase.java new file mode 100644 index 000000000..08ee203ff --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreTestCase.java @@ -0,0 +1,158 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.aspectj.asm.AsmManager; +import org.aspectj.tools.ajc.Ajc; + +/** + * Testcase class to be used by all ajde.core tests. Provides + * helper methods to set up the environment in a sandbox + * as well as to drive a build. + */ +public class AjdeCoreTestCase extends TestCase { + + public final static String testdataSrcDir = "../ajde.core/testdata"; + protected static File sandboxDir; + + private String projectDir; + private AjCompiler compiler; + + + protected void setUp() throws Exception { + super.setUp(); + // Create a sandbox in which to work + sandboxDir = Ajc.createEmptySandbox(); + // AMC - added this next line as a temporary workaround for + // listener leakage in AsmManager induced by the Ajde test suite. + AsmManager.getDefault().removeAllListeners(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + compiler.clearLastState(); + compiler = null; + } + + /** + * Fill in the working directory with the project files and + * creates a compiler instance for this project + */ + public void initialiseProject(String projectName) { + File projectSrc=new File(testdataSrcDir + File.separatorChar + projectName); + File destination=new File(getWorkingDir(),projectName); + if (!destination.exists()) {destination.mkdir();} + copy(projectSrc,destination); + projectDir = destination.getAbsolutePath(); + + compiler = new AjCompiler( + projectDir, + new TestCompilerConfiguration(projectDir), + new TestBuildProgressMonitor(), + new TestMessageHandler()); + } + + /** + * @return the working directory + */ + protected File getWorkingDir() { + return sandboxDir; + } + + /** + * @return the absolute path of the project directory + * for example c:\temp\ajcSandbox\ajcTest15200.tmp\myProject + */ + protected String getAbsoluteProjectDir() { + return projectDir; + } + + /** + * Copy the contents of some directory to another location - the + * copy is recursive. + */ + private void copy(File from, File to) { + String contents[] = from.list(); + if (contents==null) return; + for (int i = 0; i < contents.length; i++) { + String string = contents[i]; + File f = new File(from,string); + File t = new File(to,string); + + if (f.isDirectory()) { + t.mkdir(); + copy(f,t); + } else if (f.isFile()) { + try { + org.aspectj.util.FileUtil.copyFile(f,t); + } catch (IOException e) { + throw new AssertionFailedError("Unable to copy " + f + " to " + t); + } + } + } + } + + protected File openFile(String path) { + return new File(projectDir + File.separatorChar + path); + } + + public void doBuild() { + doBuild(true); + } + + public void doBuild(boolean buildFresh) { + if (buildFresh) { + compiler.buildFresh(); + } else { + compiler.build(); + } + } + + public AjCompiler getCompiler() { + return compiler; + } + + public boolean checkFor(String what) { + List ll = ((TestMessageHandler)compiler.getMessageHandler()).getMessages(); + for (Iterator iter = ll.iterator(); iter.hasNext();) { + Object element = (Object) iter.next(); + if (element.toString().indexOf(what) != -1) + return true; + } + return false; + } + + public void dumpTaskData() { + List ll = ((TestMessageHandler)compiler.getMessageHandler()).getMessages(); + for (Iterator iter = ll.iterator(); iter.hasNext();) { + Object element = (Object) iter.next(); + System.out.println("RecordedMessage>"+element); + } + } + + public List getSourceFileList(String[] files) { + List sourceFiles = new ArrayList(); + for (int i = 0; i < files.length; i++) { + sourceFiles.add(getAbsoluteProjectDir() + File.separator + files[i]); + } + return sourceFiles; + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreTests.java new file mode 100644 index 000000000..7e45b4757 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/AjdeCoreTests.java @@ -0,0 +1,60 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.aspectj.ajde.core.tests.AjConfigTests; +import org.aspectj.ajde.core.tests.BuildCancellingTests; +import org.aspectj.ajde.core.tests.CompilerMessagesTests; +import org.aspectj.ajde.core.tests.DuplicateManifestTests; +import org.aspectj.ajde.core.tests.InpathTests; +import org.aspectj.ajde.core.tests.JarManifestTests; +import org.aspectj.ajde.core.tests.OutxmlTests; +import org.aspectj.ajde.core.tests.ResourceCopyTests; +import org.aspectj.ajde.core.tests.ReweavableTests; +import org.aspectj.ajde.core.tests.ShowWeaveMessagesTests; +import org.aspectj.ajde.core.tests.model.AsmDeclarationsTests; +import org.aspectj.ajde.core.tests.model.AsmRelationshipsTests; +import org.aspectj.ajde.core.tests.model.SavedModelConsistencyTests; +import org.aspectj.ajde.core.tests.model.StructureModelTests; + +public class AjdeCoreTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(AjdeCoreTests.class.getName()); + // $JUnit-BEGIN$ + suite.addTestSuite(ShowWeaveMessagesTests.class); + suite.addTestSuite(DuplicateManifestTests.class); + suite.addTestSuite(StructureModelTests.class); + suite.addTestSuite(CompilerMessagesTests.class); + suite.addTestSuite(AsmDeclarationsTests.class); + suite.addTestSuite(AsmRelationshipsTests.class); + suite.addTestSuite(InpathTests.class); + suite.addTestSuite(ReweavableTests.class); + suite.addTestSuite(ResourceCopyTests.class); + suite.addTestSuite(SavedModelConsistencyTests. class); + suite.addTestSuite(BuildCancellingTests.class); + suite.addTestSuite(JarManifestTests.class); + suite.addTestSuite(OutxmlTests.class); + suite.addTestSuite(AjConfigTests.class); + + // $JUnit-END$ + return suite; + } + + public AjdeCoreTests(String name) { + super(name); + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/TestBuildProgressMonitor.java b/ajde.core/testsrc/org/aspectj/ajde/core/TestBuildProgressMonitor.java new file mode 100644 index 000000000..8d9f4dcc1 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/TestBuildProgressMonitor.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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Test implementation of IBuildProgressMonitor which prints out + * progress to the console and enables users to cancel the build process + * after a specified string has been printed. + */ +public class TestBuildProgressMonitor implements IBuildProgressMonitor { + + private static boolean debugTests = false; + + public int numWovenClassMessages = 0; + public int numWovenAspectMessages = 0; + public int numCompiledMessages = 0; + + private String programmableString; + private int count; + private List messagesReceived = new ArrayList(); + private int currentVal; + private boolean isCancelRequested = false; + + public void finish(boolean wasFullBuild) { + System.out.println("build finished. Was full build: " + wasFullBuild); + } + + public boolean isCancelRequested() { + return isCancelRequested; + } + + public void setProgress(double percentDone) { + System.out.println("progress. Completed " + percentDone + " percent"); + } + + public void setProgressText(String text) { + System.out.println("progress text: " + text); + String newText = text+" [Percentage="+currentVal+"%]"; + messagesReceived.add(newText); + if (text.startsWith("woven aspect ")) numWovenAspectMessages++; + if (text.startsWith("woven class ")) numWovenClassMessages++; + if (text.startsWith("compiled:")) numCompiledMessages++; + if (programmableString != null + && text.indexOf(programmableString) != -1) { + count--; + if (count==0) { + if (debugTests) System.out.println("Just got message '"+newText+"' - asking build to cancel"); + isCancelRequested = true; + programmableString = null; + } + } + } + + public void begin() { + System.out.println("build started"); + currentVal = 0; + } + + // ------------- methods to help with testing ------------- + public void cancelOn(String string,int count) { + programmableString = string; + this.count = count; + } + + public boolean containsMessage(String prefix,String distinguishingMarks) { + for (Iterator iter = messagesReceived.iterator(); iter.hasNext();) { + String element = (String) iter.next(); + if (element.startsWith(prefix) && + element.indexOf(distinguishingMarks)!=-1) return true; + } + return false; + } + + public void dumpMessages() { + System.out.println("ProgressMonitorMessages"); + for (Iterator iter = messagesReceived.iterator(); iter.hasNext();) { + String element = (String) iter.next(); + System.out.println(element); + } + } + + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java b/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java new file mode 100644 index 000000000..6ce4aa92e --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java @@ -0,0 +1,160 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.aspectj.tools.ajc.AjcTests; +import org.aspectj.util.FileUtil; + +/** + * Test implementation of ICompilerConfiguration. Allows users to configure + * the settings via setter methods. By default returns null for all options + * except getClasspath(), getJavaOptionsMap() (by default returns that it's + * 1.3 compliant), getOutputLocationManager(), getSourcePathResources() (it + * recursively looks for them) and getProjectSourceFiles(). If no source + * files are specified by the user, then getProjectSourceFiles() returns + * an empty list. + */ +public class TestCompilerConfiguration implements ICompilerConfiguration { + + private String projectPath; + + private Set aspectpath; + private Set inpath; + private String outjar; + private Map javaOptions; + private String nonStandardOptions; + private List projectSourceFiles = new ArrayList(); + private Map sourcePathResources; + + private String srcDirName = "src"; + + private IOutputLocationManager outputLoc; + + public TestCompilerConfiguration(String projectPath) { + this.projectPath = projectPath; + } + + public Set getAspectPath() { + return aspectpath; + } + + public String getClasspath() { + return projectPath + + File.pathSeparator + + System.getProperty("sun.boot.class.path") + + File.pathSeparator + + AjcTests.aspectjrtClasspath(); + } + + public Set getInpath() { + return inpath; + } + + public Map getJavaOptionsMap() { + if (javaOptions == null) { + javaOptions = new Hashtable(); + javaOptions.put(JavaOptions.COMPLIANCE_LEVEL,JavaOptions.VERSION_13); + javaOptions.put(JavaOptions.SOURCE_COMPATIBILITY_LEVEL,JavaOptions.VERSION_13); + } + return javaOptions; + } + + public String getNonStandardOptions() { + return nonStandardOptions; + } + + public String getOutJar() { + return outjar; + } + + public IOutputLocationManager getOutputLocationManager() { + if (outputLoc == null) { + outputLoc = new TestOutputLocationManager(projectPath); + } + return outputLoc; + } + + public List getProjectSourceFiles() { + return projectSourceFiles; + } + + public Map getSourcePathResources() { + if (sourcePathResources == null) { + sourcePathResources = new HashMap(); + + /* Allow the user to override the testProjectPath by using sourceRoots */ + File[] srcBase = new File[] { new File(projectPath + File.separator + srcDirName) }; + + for (int j = 0; j < srcBase.length; j++) { + File[] fromResources = FileUtil.listFiles(srcBase[j], new FileFilter() { + public boolean accept(File pathname) { + String name = pathname.getName().toLowerCase(); + return !name.endsWith(".class") + && !name.endsWith(".java") + && !name.endsWith(".aj") + && !name.endsWith(".lst") + && !name.endsWith(".jar"); + } + }); + for (int i = 0; i < fromResources.length; i++) { + String normPath = FileUtil.normalizedPath(fromResources[i] ,srcBase[j]); + sourcePathResources.put(normPath, fromResources[i]); + + } + } + } + return sourcePathResources; + } + + + // -------------------- setter methods useful for testing --------------- + public void setAspectPath(Set aspectPath) { + this.aspectpath = aspectPath; + } + + public void setInpath(Set inpath) { + this.inpath = inpath; + } + + public void setOutjar(String outjar) { + this.outjar = outjar; + } + + public void setJavaOptions(Map javaOptions) { + this.javaOptions = javaOptions; + } + + public void setNonStandardOptions(String options) { + this.nonStandardOptions = options; + } + + public void setProjectSourceFiles(List projectSourceFiles) { + this.projectSourceFiles = projectSourceFiles; + } + + public void setSourcePathResources(Map sourcePathResources) { + this.sourcePathResources = sourcePathResources; + } + + public void setSourceDir(String srcDirName) { + this.srcDirName = srcDirName; + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/TestMessageHandler.java b/ajde.core/testsrc/org/aspectj/ajde/core/TestMessageHandler.java new file mode 100644 index 000000000..aab1e98e0 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/TestMessageHandler.java @@ -0,0 +1,105 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessage.Kind; + +/** + * Test implementation of IBuildMessageHandler. By default it + * ignores INFO and WEAVEINFO messages. Stores all messages it's + * not ignoring in an ArrayList and ERRORS and ABORTS also in + * a separate ArrayList enabling users to query whether anything + * went wrong with the build. + */ +public class TestMessageHandler implements IBuildMessageHandler { + + private List ignoring; + private List messages; + private List errors; + + public TestMessageHandler() { + ignoring = new ArrayList(); + messages = new ArrayList(); + errors = new ArrayList(); + ignore(IMessage.INFO); + ignore(IMessage.WEAVEINFO); + } + + public boolean handleMessage(IMessage message) throws AbortException { + IMessage.Kind kind = message.getKind(); + if (isIgnoring(kind)) { + return true; + } + TestMessage t = new TestMessage(message); + messages.add(t); + if (kind.equals(IMessage.ABORT) || message.getThrown() != null) { + System.err.println("> AjCompiler error: "+message.getMessage()); //$NON-NLS-1$ + message.getThrown().printStackTrace(); + errors.add(t); + } else if (kind.equals(IMessage.ERROR)) { + errors.add(t); + } + System.out.println("> "+message); //$NON-NLS-1$ + return true; + } + + public void dontIgnore(Kind kind) { + if (null != kind) { + ignoring.remove(kind); + } + } + + public boolean isIgnoring(Kind kind) { + return ((null != kind) && (ignoring.contains(kind))); + } + + public void ignore(Kind kind) { + if ((null != kind) && (!ignoring.contains(kind))) { + ignoring.add(kind); + } + } + + public List getMessages() { + return messages; + } + + public List getErrors() { + return errors; + } + + public static class TestMessage { + IMessage message; + + public TestMessage(IMessage m) { + message = m; + } + + public IMessage getContainedMessage() { + return message; + } + + public String toString() { + String loc = ""; + if (null != message.getSourceLocation()) { + loc = message.getSourceLocation().getSourceFile() + ":" + message.getSourceLocation().getLine(); + } + return "TestMessage [" + message.getMessage() + + ", " + loc + + ", " + message.getKind() + + "]"; + } + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/TestOutputLocationManager.java b/ajde.core/testsrc/org/aspectj/ajde/core/TestOutputLocationManager.java new file mode 100644 index 000000000..233c4239f --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/TestOutputLocationManager.java @@ -0,0 +1,81 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Test implementation of IOutputLocationManager. By default returns the + * same location for both resources and classes, however, setter methods + * enable the user to specify different location for these. Note that the + * user is unable to specify different output location for different class + * files. + */ +public class TestOutputLocationManager implements IOutputLocationManager { + + private String testProjectOutputPath; + private File classOutputLoc; + private File resourceOutputLoc; + private List allOutputLocations; + + public TestOutputLocationManager(String testProjectPath) { + this.testProjectOutputPath = testProjectPath + File.separator + "bin"; + } + + public File getOutputLocationForClass(File compilationUnit) { + initLocations(); + return classOutputLoc; + } + + public File getOutputLocationForResource(File resource) { + initLocations(); + return resourceOutputLoc; + } + + // -------------- setter methods useful for testing ------------- + public void setOutputLocForClass(File f) { + classOutputLoc = f; + } + + public void setOutputLocForResource(File f) { + resourceOutputLoc = f; + } + + public List getAllOutputLocations() { + if(allOutputLocations == null) { + allOutputLocations = new ArrayList(); + initLocations(); + allOutputLocations.add(classOutputLoc); + if (!classOutputLoc.equals(resourceOutputLoc)) { + allOutputLocations.add(resourceOutputLoc); + } + } + return allOutputLocations; + } + + public File getDefaultOutputLocation() { + initLocations(); + return classOutputLoc; + } + + private void initLocations() { + if (classOutputLoc == null) { + classOutputLoc = new File(testProjectOutputPath); + } + if (resourceOutputLoc == null) { + resourceOutputLoc = new File(testProjectOutputPath); + } + } + + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/AjConfigTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/AjConfigTests.java new file mode 100644 index 000000000..53dd64577 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/AjConfigTests.java @@ -0,0 +1,226 @@ +/******************************************************************** + * 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 + *******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.IOutputLocationManager; +import org.aspectj.ajde.core.JavaOptions; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.internal.AjdeCoreBuildManager; +import org.aspectj.ajdt.internal.core.builder.AjBuildConfig; + +/** + * Tests that the AjBuildConfig is populated correctly from the + * ICompilerConfiguration + */ +public class AjConfigTests extends AjdeCoreTestCase { + + private TestCompilerConfiguration compilerConfig; + private AjdeCoreBuildManager ajdeBuildManager; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("SimpleProject"); + ajdeBuildManager = new AjdeCoreBuildManager(getCompiler()); + compilerConfig = (TestCompilerConfiguration) getCompiler().getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + ajdeBuildManager = null; + compilerConfig = null; + } + + public void testJavaOptionsMap() { + Map options = JavaOptions.getDefaultJavaOptions(); + options.put(JavaOptions.WARN_DEPRECATION, JavaOptions.WARNING); + compilerConfig.setJavaOptions(options); + Map found = genAjBuildConfig().getOptions().getMap(); + String warning = (String) found.get(JavaOptions.WARN_DEPRECATION); + assertEquals("expected to be warning on deprecation but found setting " + + " was " + warning,JavaOptions.WARNING,warning); + } + + public void testAspectPath() { + Set aspects = new HashSet(); + compilerConfig.setAspectPath( aspects ); + AjBuildConfig buildConfig = genAjBuildConfig(); + List aPath = buildConfig.getAspectpath(); + assertTrue( "no aspect path", aPath.isEmpty() ); + + File f = new File( "jarone.jar" ); + aspects.add( f ); + buildConfig = genAjBuildConfig(); + List aPath2 = buildConfig.getAspectpath(); + assertEquals("expected one entry on the aspectpath but found " + + aPath2.size(), 1, aPath2.size()); + assertTrue( "expected to find file " + f.getName() + " on the aspectpath" + + " but didn't", aPath2.contains(f) ); + + File f2 = new File( "jartwo.jar" ); + aspects.add( f2 ); + buildConfig = genAjBuildConfig(); + List aPath3 = buildConfig.getAspectpath(); + assertEquals("expected two entries on the aspectpath but found " + + aPath3.size(), 2, aPath3.size()); + assertTrue( "expected to find file " + f.getName() + " on the aspectpath" + + " but didn't", aPath3.contains(f) ); + assertTrue( "expected to find file " + f2.getName() + " on the aspectpath" + + " but didn't", aPath3.contains(f2) ); + } + + public void testInpath() { + Set jars = new HashSet(); + compilerConfig.setInpath( jars ); + AjBuildConfig buildConfig = genAjBuildConfig(); + List inJars = buildConfig.getInpath(); + assertTrue( "expected to find nothing on the inpath but found " + + inJars, inJars.isEmpty() ); + + File f = new File( "jarone.jar" ); + jars.add( f ); + buildConfig = genAjBuildConfig(); + List inJars2 = buildConfig.getInpath(); + assertTrue("expected to find one file on the inpath but found " + + inJars2.size() + ": " + inJars2,inJars2.size() == 1); + assertTrue( "expected to find file " + f.getName() + " on the inpath" + + " but didn't", inJars2.contains(f) ); + + + File f2 = new File( "jartwo.jar" ); + jars.add( f2 ); + buildConfig = genAjBuildConfig(); + List inJars3 = buildConfig.getInpath(); + assertEquals("expected two entries on the inpath but found " + + inJars3.size(), 2, inJars3.size()); + assertTrue( "expected to find file " + f.getName() + " on the inpath" + + " but didn't", inJars3.contains(f) ); + assertTrue( "expected to find file " + f2.getName() + " on the inpath" + + " but didn't", inJars3.contains(f2) ); + } + + public void testOutJar() { + String outJar = "mybuild.jar"; + compilerConfig.setOutjar( outJar ); + AjBuildConfig buildConfig = genAjBuildConfig(); + assertNotNull("expected to find a non null output jar but " + + "didn't", buildConfig.getOutputJar()); + assertEquals( "expected to find outjar 'mybuild.jar' but instead " + + "found " + buildConfig.getOutputJar().toString(), + outJar, buildConfig.getOutputJar().toString() ); + } + + public void testXHasMember() { + compilerConfig.setNonStandardOptions("-XhasMember"); + AjBuildConfig buildConfig = genAjBuildConfig(); + assertTrue( "expected XhasMember to be enabled but wasn't ", + buildConfig.isXHasMemberEnabled() ); + } + + public void testOutputLocationManager() { + IOutputLocationManager mgr = compilerConfig.getOutputLocationManager(); + String expectedDefaultOutputDir = mgr.getDefaultOutputLocation().getAbsolutePath(); + AjBuildConfig buildConfig = genAjBuildConfig(); + String found = buildConfig.getCompilationResultDestinationManager(). + getDefaultOutputLocation().getAbsolutePath(); + assertEquals("expected to find default output location " + + expectedDefaultOutputDir + " but found " + found, + expectedDefaultOutputDir,found); + } + + public void testSourcePathResources() { + Map m = new HashMap(); + m.put("newFile.txt", getWorkingDir()); + compilerConfig.setSourcePathResources(m); + AjBuildConfig buildConfig = genAjBuildConfig(); + Map found = buildConfig.getSourcePathResources(); + for (Iterator i = found.keySet().iterator(); i.hasNext(); ) { + String resource = (String)i.next(); + assertEquals("expected to find resource with name newFile.txt but " + + "found " + resource,"newFile.txt",resource); + File from = (File)buildConfig.getSourcePathResources().get(resource); + assertEquals("expected to find resource with file " + getWorkingDir() + + "but found " + from,getWorkingDir(),from); + } + } + + public void testClasspath() { + String classpath = compilerConfig.getClasspath(); + List found = genAjBuildConfig().getClasspath(); + StringBuffer sb = new StringBuffer(); + for (Iterator iterator = found.iterator(); iterator.hasNext();) { + String name = (String) iterator.next(); + sb.append(name); + if (iterator.hasNext()) { + sb.append(File.pathSeparator); + } + } + assertEquals("expected to find classpath " + classpath + " but found " + + sb.toString(), classpath, sb.toString()); + } + + public void testNonStandardOptions() { + compilerConfig.setNonStandardOptions( "-XterminateAfterCompilation" ); + AjBuildConfig buildConfig = genAjBuildConfig(); + assertTrue( "XterminateAfterCompilation", buildConfig.isTerminateAfterCompilation() ); + compilerConfig.setNonStandardOptions( "-XserializableAspects" ); + buildConfig = genAjBuildConfig(); + assertTrue( "XserializableAspects", buildConfig.isXserializableAspects() ); + compilerConfig.setNonStandardOptions( "-XnoInline" ); + buildConfig = genAjBuildConfig(); + assertTrue( "XnoInline", buildConfig.isXnoInline()); + compilerConfig.setNonStandardOptions( "-Xlint" ); + buildConfig = genAjBuildConfig(); + assertEquals( "Xlint", AjBuildConfig.AJLINT_DEFAULT, + buildConfig.getLintMode()); + compilerConfig.setNonStandardOptions( "-Xlint:error" ); + buildConfig = genAjBuildConfig(); + assertEquals( "Xlint", AjBuildConfig.AJLINT_ERROR, + buildConfig.getLintMode()); + + // and a few options thrown in at once + compilerConfig.setNonStandardOptions( "-Xlint -XnoInline -XserializableAspects" ); + buildConfig = genAjBuildConfig(); + assertEquals( "Xlint", AjBuildConfig.AJLINT_DEFAULT, + buildConfig.getLintMode()); + assertTrue( "XnoInline", buildConfig.isXnoInline()); + assertTrue( "XserializableAspects", buildConfig.isXserializableAspects() ); + } + + public void testProjectSourceFiles() { + String f = getAbsoluteProjectDir() + File.separator + "C.java"; + List files = new ArrayList(); + files.add(f); + compilerConfig.setProjectSourceFiles(files); + AjBuildConfig buildConfig = genAjBuildConfig(); + String found = ((File)buildConfig.getFiles().get(0)).getAbsolutePath(); + assertEquals("expected source file " + f + ", but found " + + found, f, found); + } + + private AjBuildConfig genAjBuildConfig() { + AjBuildConfig buildConfig = ajdeBuildManager.genAjBuildConfig(); + assertNotNull("exepected to generate a non null AjBuildConfig but " + + "didn't", buildConfig); + return buildConfig; + } + + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/BuildCancellingTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/BuildCancellingTests.java new file mode 100644 index 000000000..2e0bffaa0 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/BuildCancellingTests.java @@ -0,0 +1,272 @@ +/******************************************************************** + * Copyright (c) 2004 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement Initial version + * Helen Hawkins Converted to new interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestBuildProgressMonitor; +import org.aspectj.ajde.core.TestCompilerConfiguration; + +/** + * It is now possible to cancel the compiler during either the compilation or + * weaving phases - this testcase verifies a few cases, making sure the process + * stops when expected. It can check the disk contents, but it doesn't right + * now. + * + * Two different .lst files are used during these tests: LoadsaCode.lst and + * EvenMoreCode.lst which contain mixes of aspects and classes + * + * Here are some things to think about that will help you understand what is on + * the disk when we cancel the compiler. + * + * There are 3 important phases worth remembering : - Compile all the types - + * Weave all the aspects - Weave all the classes + * + * Each of those steps goes through all the types. This means during the 'weave + * all the aspects' step we are jumping over classes and during the 'weave all + * the classes ' step we are jumping over aspects. Why is this important? + * + * + * We only write bytes out during the 'weave all the classes ' phase and it is + * even during that phase that we write out the bytes for aspects. This means if + * you cancel during compilation or during the weaving of aspects - there will + * be nothing on the disk. If you cancel whilst in the 'weave all the classes ' + * phase then the disk will contain anything finished with by the cancellation + * point. + */ +public class BuildCancellingTests extends AjdeCoreTestCase { + + private final boolean debugTests = false; + private TestBuildProgressMonitor programmableBPM; + private TestCompilerConfiguration compilerConfig; + + private String[] loadsaCode = { "A1.aj", "A2.aj", "HW.java", "A3.aj", + "A4.aj" }; + private String[] evenMoreCode = { "A1.aj", "Cl1.java", "A2.aj", "Cl2.java", + "HW.java", "A3.aj", "Cl3.java", "A4.aj" }; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("BuildCancelling"); + programmableBPM = (TestBuildProgressMonitor) getCompiler() + .getBuildProgressMonitor(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + programmableBPM = null; + compilerConfig = null; + } + + /** + * After first compilation message, get it to cancel, there should be one + * more warning message about cancelling the compile and their should be + * nothing on the disk. + */ + public void testCancelFirstCompile() { + if (debugTests) + System.out + .println("\n\n\ntestCancelFirstCompile: Building with LoadsaCode"); + + compilerConfig.setProjectSourceFiles(getSourceFileList(loadsaCode)); + programmableBPM.cancelOn("compiled:", 1); // Force a cancel after the + // first compile occurs + + doBuild(true); + + assertTrue("Should have cancelled after first compile?:" + + programmableBPM.numCompiledMessages, + programmableBPM.numCompiledMessages == 1); + // Comment out to check the disk contents + + // assertTrue("As weaving was cancelled, no files should have been + // written out, but I found:"+wovenClassesFound(), + // wovenClassesFound()==0); + + boolean expectedCancelMessageFound = checkFor("Compilation cancelled as requested"); + if (!expectedCancelMessageFound) + dumpTaskData(); // Useful for debugging + assertTrue( + "Failed to get warning message about compilation being cancelled!", + expectedCancelMessageFound); + } + + /** + * After third compilation message, get it to cancel, there should be one + * more warning message about cancelling the compile and their should be + * nothing on the disk. + */ + public void testCancelThirdCompile() { + if (debugTests) + System.out + .println("\n\n\ntestCancelThirdCompile: Building with LoadsaCode"); + + compilerConfig.setProjectSourceFiles(getSourceFileList(loadsaCode)); + programmableBPM.cancelOn("compiled:", 3); // Force a cancel after the + // third compile occurs + + doBuild(true); + + assertTrue("Should have cancelled after third compile?:" + + programmableBPM.numCompiledMessages, + programmableBPM.numCompiledMessages == 3); + // Comment out to check the disk contents + // assertTrue("As weaving was cancelled, no files should have been + // written out, but I found:"+wovenClassesFound(), + // wovenClassesFound()==0); + + boolean expectedCancelMessageFound = checkFor("Compilation cancelled as requested"); + if (!expectedCancelMessageFound) + dumpTaskData(); // Useful for debugging + assertTrue( + "Failed to get warning message about compilation being cancelled!", + expectedCancelMessageFound); + } + + /** + * After first weave aspect message, get it to cancel, there should be one + * more warning message about cancelling the weave and their should be + * nothing on the disk. + */ + public void testCancelFirstAspectWeave() { + if (debugTests) + System.out + .println("\n\n\ntestCancelFirstAspectWeave: Building with LoadsaCode"); + + compilerConfig.setProjectSourceFiles(getSourceFileList(loadsaCode)); + programmableBPM.cancelOn("woven aspect ", 1); // Force a cancel after + // the first weave + // aspect occurs + + doBuild(true); + + assertTrue("Should have cancelled after first aspect weave?:" + + programmableBPM.numWovenAspectMessages, + programmableBPM.numWovenAspectMessages == 1); + // Comment out to check the disk contents + // assertTrue("As weaving was cancelled, no files should have been + // written out?:"+wovenClassesFound(), + // wovenClassesFound()==0); + + boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested"); + if (!expectedCancelMessageFound) + dumpTaskData(); // Useful for debugging + assertTrue( + "Failed to get warning message about weaving being cancelled!", + expectedCancelMessageFound); + } + + /** + * After third weave aspect message, get it to cancel, there should be one + * more warning message about cancelling the weave and their should be + * nothing on the disk. + */ + public void testCancelThirdAspectWeave() { + if (debugTests) + System.out + .println("\n\n\ntestCancelThirdAspectWeave: Building with LoadsaCode"); + compilerConfig.setProjectSourceFiles(getSourceFileList(loadsaCode)); + // Force a cancel after the third weave occurs. + // This should leave two class files on disk - I think? + programmableBPM.cancelOn("woven aspect ", 3); + + doBuild(true); + assertTrue("Should have cancelled after third weave?:" + + programmableBPM.numWovenAspectMessages, + programmableBPM.numWovenAspectMessages == 3); + + // Comment out to check disk contents + // assertTrue("As weaving was cancelled, no files should have been + // written out?:"+wovenClassesFound(), + // wovenClassesFound()==0); + + boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested"); + if (!expectedCancelMessageFound) + dumpTaskData(); // Useful for debugging + assertTrue( + "Failed to get warning message about weaving being cancelled!", + expectedCancelMessageFound); + + } + + /** + * After first weave class message, get it to cancel, there should be one + * more warning message about cancelling the weave and their should be + * nothing on the disk. + * + * EvenMoreCode.lst contains: A1.aj Cl1.java A2.aj Cl2.java HW.java A3.aj + * Cl3.java A4.aj + * + */ + public void testCancelFirstClassWeave() { + if (debugTests) + System.out + .println("testCancelFirstClassWeave: Building with EvenMoreCode"); + compilerConfig.setProjectSourceFiles(getSourceFileList(evenMoreCode)); + programmableBPM.cancelOn("woven class", 1); + + doBuild(true); + + // Should just be A1 on the disk - uncomment this line to verify that! + // (and uncomment diskContents()) + // assertTrue("Incorrect disk contents found",diskContents("A1")); + + assertTrue("Should have cancelled after first class weave?:" + + programmableBPM.numWovenClassMessages, + programmableBPM.numWovenClassMessages == 1); + + boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested"); + if (!expectedCancelMessageFound) + dumpTaskData(); // Useful for debugging + assertTrue( + "Failed to get warning message about weaving being cancelled!", + expectedCancelMessageFound); + } + + /** + * After first weave aspect message, get it to cancel, there should be one + * more warning message about cancelling the weave and their should be + * nothing on the disk. + * + * EvenMoreCode.lst contains: A1.aj Cl1.java A2.aj Cl2.java HW.java A3.aj + * Cl3.java A4.aj + * + */ + public void testCancelSecondClassWeave() { + if (debugTests) + System.out + .println("testCancelSecondClassWeave: Building with EvenMoreCode"); + compilerConfig.setProjectSourceFiles(getSourceFileList(evenMoreCode)); + programmableBPM.cancelOn("woven class", 2); + + doBuild(true); + + // Uncomment this line to verify disk contents(and uncomment + // diskContents()) + // assertTrue("Incorrect disk contents found",diskContents("A1 Cl1 + // A2")); + + assertTrue("Should have cancelled after first class weave?:" + + programmableBPM.numWovenClassMessages, + programmableBPM.numWovenClassMessages == 2); + + boolean expectedCancelMessageFound = checkFor("Weaving cancelled as requested"); + if (!expectedCancelMessageFound) + dumpTaskData(); // Useful for debugging + assertTrue( + "Failed to get warning message about weaving being cancelled!", + expectedCancelMessageFound); + + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/CompilerMessagesTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/CompilerMessagesTests.java new file mode 100644 index 000000000..dda92a5b0 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/CompilerMessagesTests.java @@ -0,0 +1,77 @@ +/* ******************************************************************* + * Copyright (c) 2003 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * AMC 2003 initial version + * Helen Hawkins Converted to new interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.bridge.IMessage; + +public class CompilerMessagesTests extends AjdeCoreTestCase { + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + private String[] files = { "apackage" + File.separator + "InitCatcher.java", + "apackage" + File.separator + "SomeClass.java" }; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("declare-warning"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler().getCompilerConfiguration(); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + doBuild(true); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + public void testMessages() { + // bug 33474 + // The build has happened, what messages did the compiler give, and do they + // contain the information we expect? + List msgs = handler.getMessages(); + if (2 != msgs.size()) { + assertTrue("not two messages: " + msgs, false); + } + assertEquals("Two warning messages should be produced",2,msgs.size()); + TestMessageHandler.TestMessage msg = + (TestMessageHandler.TestMessage) msgs.get(0); + assertEquals( 8, msg.getContainedMessage().getSourceLocation().getLine()); + assertEquals( "Please don't call init methods", msg.getContainedMessage().getMessage()); + try { + String fullyQualifiedFile = msg.getContainedMessage().getSourceLocation().getSourceFile().getCanonicalPath(); + // this name has a tester specific prefix, followed by the location of the file. + // we can validate the ending. + fullyQualifiedFile = fullyQualifiedFile.replace('\\','/'); // ignore platform differences in slashes + assertTrue( "Fully-qualified source file location returned", + fullyQualifiedFile.endsWith("/declare-warning/apackage/SomeClass.java")); + } catch (IOException ex) { + assertTrue( "Unable to convert source file location: " + msg.getContainedMessage().getSourceLocation().getSourceFile(), false); + } + } + + public void testDeclareMessageContents() { + List msgs = handler.getMessages(); + IMessage msg = (IMessage)((TestMessageHandler.TestMessage)msgs.get(1)).getContainedMessage(); + assertEquals( "Please don't call setters" , msg.getMessage()); + assertEquals("field-set(int apackage.SomeClass.x)", msg.getDetails()); + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/DuplicateManifestTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/DuplicateManifestTests.java new file mode 100644 index 000000000..997c49d72 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/DuplicateManifestTests.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * 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 v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + * Helen Hawkins - Converted to new interface (bug 148190) + *******************************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; + +public class DuplicateManifestTests extends AjdeCoreTestCase { + + public static final String injarName = "injar.jar"; + public static final String aspectjarName = "aspectjar.jar"; + public static final String outjarName = "outjar.jar"; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("DuplicateManifestTest"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + public void testWeave() { + Set injars = new HashSet(); + injars.add(openFile(injarName)); + compilerConfig.setInpath(injars); + Set aspectpath = new HashSet(); + aspectpath.add(openFile(aspectjarName)); + compilerConfig.setAspectPath(aspectpath); + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + compareManifests(openFile(injarName), openFile(outjarName)); + } + + private void compareManifests(File inFile, File outFile) { + + try { + JarFile inJar = new JarFile(inFile); + Manifest inManifest = inJar.getManifest(); + inJar.close(); + JarFile outJar = new JarFile(outFile); + Manifest outManifest = outJar.getManifest(); + outJar.close(); + assertTrue("The manifests in '" + inFile.getCanonicalPath() + + "' and '" + outFile.getCanonicalPath() + + "' sould be the same", inManifest.equals(outManifest)); + } catch (IOException ex) { + fail(ex.toString()); + } + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/InpathTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/InpathTests.java new file mode 100644 index 000000000..4bcd6d1af --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/InpathTests.java @@ -0,0 +1,389 @@ +/* ******************************************************************* + * Copyright (c) 2003 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mik Kersten initial implementation + * Andy Clement Copied/changed for -inpath testing + * Helen Hawkins Changed to use new ajde interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.JarInputStream; +import java.util.zip.ZipEntry; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.util.FileUtil; + +public class InpathTests extends AjdeCoreTestCase { + + public static final FileFilter aspectjResourceFileFilter = + new FileFilter() { + public boolean accept(File pathname) { + String name = pathname.getName().toLowerCase(); + return ( + !name.endsWith(".class") + && !name.endsWith(".java") + && !name.endsWith(".aj")); + + } + }; + + public static final String indir1Name = "indir1"; + public static final String indir2Name = "indir2"; + public static final String injarName = "injar.jar"; + public static final String outjarName = "/bin/output.jar"; + + private String[] build1 = new String[]{"src1" + File.separator + "Main.java"}; + private String[] build2 = new String[]{"src2" + File.separator + "Aspect.java"}; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("InpathTest"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + /** + * Inputs to the compiler: + * inpath = 'indir1/' + * source = 'src' + * output = a jar file + * + * Expected result = output jar file contains contents of indir1 and + * class file for source that was in src + */ + public void testInpathToOutjar() { + Set inpath = new HashSet(); + File indir1 = openFile(indir1Name); + inpath.add(indir1); + compilerConfig.setInpath(inpath); + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + + compilerConfig.setProjectSourceFiles(getSourceFileList(build1)); + + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + Set expectedOutputJarContents = new HashSet(); + // From indir1 +// If we don't copy resources, these next three files won't make it. +// expectedOutputJarContents.add("META-INF/MANIFEST.MF"); +// expectedOutputJarContents.add("META-INF/test.xml"); +// expectedOutputJarContents.add("test/test.props"); + expectedOutputJarContents.add("test/TestProperties.class"); + // From src + expectedOutputJarContents.add("Main.class"); + compareJars(indir1, "src", outjar, expectedOutputJarContents); + } + + /** + * Similar to the first test but outputs to a directory rather than + * a jar. + * + */ + public void testInpathToBin() { + Set inpath = new HashSet(); + File indir1 = openFile(indir1Name); + inpath.add(indir1); + compilerConfig.setInpath(inpath); + compilerConfig.setProjectSourceFiles(getSourceFileList(build1)); + + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + Set expectedBindirContents = new HashSet(); + // From indir1 +// If we don't copy resources, these next three files won't make it +// expectedBindirContents.add("META-INF/MANIFEST.MF"); +// expectedBindirContents.add("META-INF/test.xml"); +// expectedBindirContents.add("test/test.props"); + expectedBindirContents.add("test/TestProperties.class"); + // From src + expectedBindirContents.add("Main.class"); + + compareIndirToBin(indir1, "src", "bin", expectedBindirContents); + + } + + + + /** + * Inputs to the compiler: + * inpath is 'indir2' that contains a helloworld source file and class file. + * source is 'src2' which contains Aspect.java which weaves before advice into the HelloWorld code from 'indir2' + * + * Expected result: HelloWorld copied through to output jar and 'weaved'. Compiled version of Aspect.java put into + * the output jar. The HelloWorld.java source file is also copied through to the output jar. + * + * An extra check is done at the end of this test to verify that HelloWorld has changed size (due to the weaving). + */ + public void testInpathToOutjar2() { + Set inpath = new HashSet(); + File indir2 = openFile(indir2Name); + inpath.add(indir2); + compilerConfig.setInpath(inpath); + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + + compilerConfig.setProjectSourceFiles(getSourceFileList(build2)); + + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + Set expectedOutputJarContents = new HashSet(); + // From indir1 + expectedOutputJarContents.add("example/HelloWorld.class"); + +// If we don't copy resources, this file won't make it +// expectedOutputJarContents.add("example/HelloWorld.java"); + // From src + expectedOutputJarContents.add("Aspect.class"); + + compareJars(indir2, "src", outjar, expectedOutputJarContents); + + // Extra test. The HelloWorld class from the input directory should have been woven + // by the aspect - verify that the size of the HelloWorld class in the output directory + // is a different size to the input version. + int outputsize = fetchFromJar(outjar, "example/HelloWorld.class"); + try { + FileInputStream fis = new FileInputStream(openFile(indir2Name+"/example/HelloWorld.class")); + byte[] filedata = FileUtil.readAsByteArray(fis); + int inputsize = filedata.length; + assertTrue("Weaving of Aspect should have occurred but the input and output size for HelloWorld.class are the same", + (inputsize!=outputsize)); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } + + + + /** + * More complex inpath - a jar and a directory + * + * Inputs: + * -inpath injar.jar;indir2 + * source is 'src2' which contains Aspect.java + * + * Expected result: Result should be a directory containing the contents of injar.jar and indir2 and the + * Aspect.class file. + * + */ + public void testInpathAndInjarToBin() { + Set inpath = new HashSet(); + File indir2 = openFile(indir2Name); + inpath.add(indir2); + inpath.add(openFile(injarName)); + compilerConfig.setInpath(inpath); + compilerConfig.setProjectSourceFiles(getSourceFileList(build2)); + + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + Set expectedBindirContents = new HashSet(); + + // From indir1 + expectedBindirContents.add("example/HelloWorld.class"); + +// If we don't copy resources, this file won't make it +// expectedBindirContents.add("example/HelloWorld.java"); + // From injar.jar + expectedBindirContents.add("props/resources.properties"); + // From src + expectedBindirContents.add("Aspect.class"); + + compareIndirToBin(indir2, "src", "bin", expectedBindirContents); + + // Check the input and output versions of HelloWorld.class are different sizes + try { + FileInputStream fis1 = new FileInputStream(openFile("indir2/example/HelloWorld.class")); + byte[] filedata1 = FileUtil.readAsByteArray(fis1); + int inputsize = filedata1.length; + FileInputStream fis2 = new FileInputStream(openFile("bin/example/HelloWorld.class")); + byte[] filedata2 = FileUtil.readAsByteArray(fis2); + int outputsize = filedata2.length; + assertTrue("Weaving of Aspect should have occurred but the input and output size for HelloWorld.class are the same", + (outputsize!=inputsize)); + + fis1.close(); + fis2.close(); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } + + /* + * Ensure -outjar contains all non-Java resouces from injars + */ + public void compareJars( + File dirFile, + String sourceDir, + File outjarFile, + Set expectedOutputJarContents) { + + try { + assertTrue( + "outjar older than injar", + (outjarFile.lastModified() > dirFile.lastModified())); + + // Go through the output jar file, for each element, remove it from + // the expectedOutputJarContents - when we finish, the expectedOutputJarContents + // set should be empty! + JarInputStream outjar = + new JarInputStream(new java.io.FileInputStream(outjarFile)); + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String fileName = entry.getName(); + fileName = fileName.replace('\\', '/'); + if (fileName.indexOf("CVS") == -1) { + boolean b = expectedOutputJarContents.remove(fileName); + assertTrue( + "Unexpectedly found : " + fileName + " in outjar", + b); + } + outjar.closeEntry(); + } + outjar.close(); + + assertTrue( + "Didnt make it into the output jar: " + + expectedOutputJarContents.toString(), + expectedOutputJarContents.isEmpty()); + } catch (IOException ex) { + fail(ex.toString()); + } + } + + /* + * Ensure -outjar contains all non-Java resouces from source and injars + */ + public void compareSourceToOutjar(String indirName, File outjarFile) { + HashSet resources = new HashSet(); + listSourceResources(indirName, resources); + + try { + + JarInputStream outjar = + new JarInputStream(new java.io.FileInputStream(outjarFile)); + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String fileName = entry.getName(); + + if (!fileName.endsWith(".class")) { + boolean b = resources.remove(fileName); + assertTrue(fileName, b); + } + outjar.closeEntry(); + } + outjar.close(); + + assertTrue( + "Missing resources: " + resources.toString(), + resources.isEmpty()); + } catch (IOException ex) { + fail(ex.toString()); + } + } + + /* + * Ensure bin contains all non-Java resouces from source and injars + */ + public void compareIndirToBin( + File indirFile, + String sourceDir, + String outdirName, + Set expectedOutdirContents) { + +// byte[] inManifest = null; + + File binBase = openFile(outdirName); + String[] toResources = FileUtil.listFiles(binBase); + for (int i = 0; i < toResources.length; i++) { + String fileName = toResources[i]; + if (fileName.indexOf("CVS") == -1) { + boolean b = expectedOutdirContents.remove(fileName); + assertTrue("Extraneous resources: " + fileName, b); + } + } + + assertTrue( + "Missing resources: " + expectedOutdirContents.toString(), + expectedOutdirContents.isEmpty()); + } + + private void listSourceResources(String indirName, Set resources) { + File srcBase = openFile(indirName); + File[] fromResources = + FileUtil.listFiles(srcBase, aspectjResourceFileFilter); + for (int i = 0; i < fromResources.length; i++) { + String name = FileUtil.normalizedPath(fromResources[i], srcBase); + //System.err.println("Checking "+name); + if (!name.startsWith("CVS/") + && (-1 == name.indexOf("/CVS/")) + && !name.endsWith("/CVS")) { + resources.add(name); + } + } + } + + // Return the size of specified entry from the output jar file + public int fetchFromJar(File outjarFile, String filename) { + int ret = -1; + try { + JarInputStream outjar; + + outjar = + new JarInputStream(new java.io.FileInputStream(outjarFile)); + + ZipEntry entry; + while (null != (entry = (ZipEntry)outjar.getNextEntry())) { + String zipentryname = entry.getName(); + if (zipentryname.equals(filename)) { + byte[] filedata = FileUtil.readAsByteArray(outjar); + ret = filedata.length; + outjar.closeEntry(); + break; + } + outjar.closeEntry(); + } + outjar.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return ret; + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/JarManifestTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/JarManifestTests.java new file mode 100644 index 000000000..ec3a6c32c --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/JarManifestTests.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * 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 v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Helen Hawkins - Converted to new interface (bug 148190) + *******************************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.jar.JarInputStream; +import java.util.jar.Manifest; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; + +public class JarManifestTests extends AjdeCoreTestCase { + + public static final String outjarName = "/bin/output.jar"; + + private String[] weave = { "src" + File.separator + "Main.java", + "src" + File.separator + "Logging.aj" }; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("JarManifestTest"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + public void testWeave () { + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(weave)); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + checkManifest(outjar); + } + + public void testNoWeave () { + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(weave)); + compilerConfig.setNonStandardOptions("-XterminateAfterCompilation"); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + checkManifest(outjar); + } + + private void checkManifest (File outjarFile) { + Manifest manifest = null; + + try { + JarInputStream outjar = new JarInputStream(new FileInputStream(outjarFile)); + manifest = outjar.getManifest(); + outjar.close(); + assertNotNull("'" + outjarFile.getCanonicalPath() + "' should contain a manifest",manifest); + } + catch (IOException ex) { + fail(ex.toString()); + } + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/OutxmlTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/OutxmlTests.java new file mode 100644 index 000000000..28768722d --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/OutxmlTests.java @@ -0,0 +1,165 @@ +/******************************************************************** + * Copyright (c) 2003 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster initial implementation + * Helen Hawkins Converted to new interface (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.bridge.Constants; + +public class OutxmlTests extends AjdeCoreTestCase { + + public static final String PROJECT_DIR = "OutxmlTest"; + public static final String BIN_DIR = "bin"; + public static final String OUTJAR_NAME = "/bin/test.jar"; + public static final String DEFAULT_AOPXML_NAME = Constants.AOP_AJC_XML; + public static final String CUSTOM_AOPXML_NAME = "custom/aop.xml"; + + private String[] files = new String[]{ + "src" + File.separator + "TestAbstractAspect.aj", + "src" + File.separator + "TestClass.java", + "src" + File.separator + "TestConcreteAspect.aj", + "src" + File.separator + "TestInterface.java" + }; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject(PROJECT_DIR); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + /** + * Aim: Test "-outxml" option produces the correct xml file + */ + public void testOutxmlToFile () { + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-outxml"); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + File aopxml = openFile(BIN_DIR + "/" + DEFAULT_AOPXML_NAME); + assertTrue(DEFAULT_AOPXML_NAME + " missing",aopxml.exists()); + } + + /** + * Aim: Test "-outxmlfile filename" option produces the correct + * xml file + * + */ + public void testOutxmlfileToFile () { + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-outxmlfile custom/aop.xml"); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + File aopxml = openFile(BIN_DIR + "/" + CUSTOM_AOPXML_NAME); + assertTrue(CUSTOM_AOPXML_NAME + " missing",aopxml.exists()); + } + + /** + * Aim: Test "-outxml" option produces the correct + * xml entry in outjar file + * + */ + public void testOutxmlToOutjar () { + File outjar = openFile(OUTJAR_NAME); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-outxml"); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + File aopxml = openFile(BIN_DIR + "/" + DEFAULT_AOPXML_NAME); + assertFalse(DEFAULT_AOPXML_NAME + " should not exisit",aopxml.exists()); + assertJarContainsEntry(outjar,DEFAULT_AOPXML_NAME); + } + + /** + * Aim: Test "-outxml" option produces a warning if "META-INF/aop.xml + * already exists in source + * + */ + public void testOutxmlToOutjarWithAop_xml () { + File f = new File( getAbsoluteProjectDir() + File.separator + "src-resources" + File.separator + "testjar.jar"); + Set roots = new HashSet(); + roots.add(f); + compilerConfig.setInpath(roots); + + File outjar = openFile(OUTJAR_NAME); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setNonStandardOptions("-outxml"); + doBuild(true); + assertFalse("Expected compiler errors or warnings but didn't find any " + + handler.getMessages(), handler.getMessages().isEmpty()); + + List msgs = handler.getMessages(); + String msg = ((TestMessageHandler.TestMessage)msgs.get(0)).getContainedMessage().getMessage(); + String exp = "-outxml/-outxmlfile option ignored because resource already exists:"; + assertTrue("Expected message to start with : " + exp + " but found message " + msg,msg.startsWith(exp)); + + File aopxml = openFile(BIN_DIR + "/" + DEFAULT_AOPXML_NAME); + assertFalse(DEFAULT_AOPXML_NAME + " should not exisit",aopxml.exists()); + assertJarContainsEntry(outjar,DEFAULT_AOPXML_NAME); + } + + + /** + * Aim: Test "-outxmlfile filename" option produces the correct + * xml entry in outjar file + */ + public void testOutxmlfileToOutjar () { + File outjar = openFile(OUTJAR_NAME); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-outxmlfile custom/aop.xml"); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + + File aopxml = openFile(BIN_DIR + "/" + CUSTOM_AOPXML_NAME); + assertFalse(CUSTOM_AOPXML_NAME + " should not exisit",aopxml.exists()); + assertJarContainsEntry(outjar,CUSTOM_AOPXML_NAME); + } + + private void assertJarContainsEntry (File file, String entryName) { + + try { + JarFile jarFile = new JarFile(file); + JarEntry jarEntry = jarFile.getJarEntry(entryName); + assertNotNull(entryName + " missing",jarEntry); + } + catch (IOException ex) { + fail(ex.toString()); + } + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/ResourceCopyTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/ResourceCopyTests.java new file mode 100644 index 000000000..84f21a405 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/ResourceCopyTests.java @@ -0,0 +1,318 @@ +/******************************************************************** + * Copyright (c) 2003 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Mik Kersten initial implementation + * Helen Hawkins Converted to new interface (bug 148190) + *******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.JarInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.util.FileUtil; + +public class ResourceCopyTests extends AjdeCoreTestCase { + + public static final String PROJECT_DIR = "bug-36071a"; + public static final String srcDir = PROJECT_DIR + "/src"; + public static final String binDir = "bin"; + + public static final String injar1Name = "input1.jar"; + public static final String injar2Name = "input2.jar"; + public static final String outjarName = "/bin/output.jar"; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + private String testProps; + + private String[] config1 = new String[] { + "src" + File.separator + "Main.java", + "src" + File.separator + "testsrc" + File.separator + "TestProperties.java" + }; + + private String[] config2 = new String[] { + "src" + File.separator + "aspects" + File.separator + "Logging.java" + }; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject(PROJECT_DIR); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + testProps = getAbsoluteProjectDir() + File.separator + "src" + File.separator + "testsrc" + File.separator + "test.props"; + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + public void testSrcToBin () { + assertTrue("Expected there to be no compiler messages but found " + handler.getMessages(), handler.getMessages().isEmpty()); + compilerConfig.setProjectSourceFiles(getSourceFileList(config1)); + doBuild(true); + compareDirs("src","bin"); + } + + public void testInjarsToOutjar () { + Set injars = new HashSet(); + File injar1 = openFile(injar1Name); + injars.add(injar1); + compilerConfig.setInpath(injars); + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(config2)); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + compareJars(injar1,"src",outjar); + } + + public void testDuplicateResources () { + Set injars = new HashSet(); + File injar1 = openFile(injar1Name); + File injar2 = openFile(injar2Name); + injars.add(injar1); + injars.add(injar2); + compilerConfig.setInpath(injars); + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(config2)); + doBuild(true); + assertFalse("Expected compiler errors or warnings but didn't find any" + , handler.getMessages().isEmpty()); + + List msgs = handler.getMessages(); + String exp = "duplicate resource: "; + String found = ((TestMessageHandler.TestMessage)msgs.get(0)).getContainedMessage().getMessage(); + assertTrue("Expected message to start with 'duplicate resource:' but found" + + " message " + found, found.startsWith(exp)); + compareJars(injar1,"src",outjar); + } + + public void testSrcToOutjar () { + File outjar = openFile(outjarName); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(config1)); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + compareSourceToOutjar("src",outjar); + } + + public void testInjarsToBin () { + Set injars = new HashSet(); + File injar1 = openFile(injar1Name); + injars.add(injar1); + compilerConfig.setInpath(injars); + compilerConfig.setProjectSourceFiles(getSourceFileList(config2)); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + compareInjarsToBin(injar1,"src","bin"); + } + + // BAH! keeps whinging about CVS extraneous resources +// public void testInjarsToOddBin () { +// Set injars = new HashSet(); +// File injar1 = openFile(injar1Name); +// injars.add(injar1); +// ideManager.getProjectProperties().setOutputPath("crazy.jar"); +// ideManager.getProjectProperties().setInJars(injars); +// assertTrue("Build failed",doSynchronousBuild("config2.lst")); +// assertTrue("Build warnings",ideManager.getCompilationSourceLineTasks().isEmpty()); +// compareInjarsToBin(injar1,"src","crazy.jar"); +// } + + public void testInjarsToOutjarOddNames () { + Set injars = new HashSet(); + File injar1 = openFile("input1"); + File outjar = openFile(outjarName+".fozout"); + injars.add(injar1); + compilerConfig.setInpath(injars); + compilerConfig.setOutjar(outjar.getAbsolutePath()); + compilerConfig.setProjectSourceFiles(getSourceFileList(config2)); + doBuild(true); + assertTrue("Expected no compiler errors or warnings but found " + + handler.getMessages(), handler.getMessages().isEmpty()); + compareJars(injar1,"src",outjar); + } + + /* + * Ensure bin contains all non-Java resouces from source and injars + */ + public void compareDirs (String indirName, String outdirName) { + File binBase = openFile(outdirName); + File[] toResources = FileUtil.listFiles(binBase,aspectjResourceFileFilter); + + HashSet resources = new HashSet(); + listSourceResources(indirName,resources); + + for (int i = 0; i < toResources.length; i++) { + String fileName = FileUtil.normalizedPath(toResources[i],binBase); + boolean b = resources.remove(fileName); + assertTrue("Extraneous resources: " + fileName,b); + } + + assertTrue("Missing resources: " + resources.toString(), resources.isEmpty()); + } + + private void listSourceResources (String indirName, Set resources) { + File srcBase = openFile(indirName); + File[] fromResources = FileUtil.listFiles(srcBase,aspectjResourceFileFilter); + for (int i = 0; i < fromResources.length; i++) { + String name = FileUtil.normalizedPath(fromResources[i],srcBase); + if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && !name.endsWith("/CVS")) { + resources.add(name); + } + } + } + public static final FileFilter aspectjResourceFileFilter = new FileFilter() { + public boolean accept(File pathname) { + String name = pathname.getName().toLowerCase(); + boolean isCVSRelated = name.indexOf("/cvs/")!=-1; + return (!isCVSRelated && !name.endsWith(".class") && !name.endsWith(".java") && !name.endsWith(".aj")); + } + }; + + /* + * Ensure -outjar contains all non-Java resouces from injars + */ + public void compareJars (File injarFile, String indirName, File outjarFile) { + + HashSet resources = new HashSet(); + + try { + assertTrue("outjar older than injar",(outjarFile.lastModified() > injarFile.lastModified())); + byte[] inManifest = listJarResources(injarFile,resources); + listSourceResources(indirName,resources); + + ZipInputStream outjar = new ZipInputStream(new java.io.FileInputStream(outjarFile)); + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String fileName = entry.getName(); + if (!fileName.endsWith(".class")) { + + /* Ensure we copied right JAR manifest */ + if (fileName.equalsIgnoreCase("meta-inf/Manifest.mf")) { + byte[] outManifest = FileUtil.readAsByteArray(outjar); + assertTrue("Wrong manifest has been copied",Arrays.equals(inManifest,outManifest)); + } + + boolean b = resources.remove(fileName); + assertTrue(fileName,b); + } + outjar.closeEntry(); + } + outjar.close(); + + assertTrue(resources.toString(),resources.isEmpty()); + } + catch (IOException ex) { + fail(ex.toString()); + } + } + + /* + * Ensure -outjar conatins all non-Java resouces from source and injars + */ + public void compareSourceToOutjar (String indirName, File outjarFile) { + HashSet resources = new HashSet(); + listSourceResources(indirName,resources); + + try { + + ZipInputStream outjar = new JarInputStream(new java.io.FileInputStream(outjarFile)); + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String fileName = entry.getName(); + if (!fileName.endsWith(".class")) { + boolean b = resources.remove(fileName); + assertTrue(fileName,b); + } + outjar.closeEntry(); + } + outjar.close(); + + assertTrue("Missing resources: " + resources.toString(), resources.isEmpty()); + } + catch (IOException ex) { + fail(ex.toString()); + } + } + /* + * Ensure bin contains all non-Java resouces from source and injars + */ + public void compareInjarsToBin(File injarFile, String indirName, String outdirName) { + + HashSet resources = new HashSet(); + + try { + byte[] inManifest = listJarResources(injarFile,resources); + listSourceResources(indirName,resources); + + File binBase = openFile(outdirName); + File[] toResources = FileUtil.listFiles(binBase,aspectjResourceFileFilter); + for (int i = 0; i < toResources.length; i++) { + String fileName = FileUtil.normalizedPath(toResources[i],binBase); + + /* Ensure we copied the right JAR manifest */ + if (fileName.equalsIgnoreCase("meta-inf/Manifest.mf")) { + byte[] outManifest = FileUtil.readAsByteArray(toResources[i]); + assertTrue("Wrong manifest has been copied",Arrays.equals(inManifest,outManifest)); + } + boolean b = resources.remove(fileName); + assertTrue("Extraneous resources: " + fileName,b); + } + + assertTrue("Missing resources: " + resources.toString(), resources.isEmpty()); + } + catch (IOException ex) { + fail(ex.toString()); + } + } + private byte[] listJarResources (File injarFile, Set resources) { + byte[] manifest = null; + + try { + ZipInputStream injar = new ZipInputStream(new java.io.FileInputStream(injarFile)); + ZipEntry entry; + while (null != (entry = injar.getNextEntry())) { + String fileName = entry.getName(); + if (!entry.isDirectory() && !fileName.endsWith(".class")) { + + /* JAR manifests shouldn't be copied */ + if (fileName.equalsIgnoreCase("meta-inf/Manifest.mf")) { + manifest = FileUtil.readAsByteArray(injar); + } + resources.add(fileName); + } + injar.closeEntry(); + } + injar.close(); + } + catch (IOException ex) { + fail(ex.toString()); + } + + return manifest; + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/ReweavableTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/ReweavableTests.java new file mode 100644 index 000000000..4443268e6 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/ReweavableTests.java @@ -0,0 +1,410 @@ +/* ******************************************************************* + * Copyright (c) 2004 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement Initial version + * Helen Hawkins Converted to new interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.bridge.IMessage; + +public class ReweavableTests extends AjdeCoreTestCase { + + private static final boolean debugTests = false; + + public static final String binDir = "bin"; + + public static final String indir1Name = "indir1"; + public static final String indir2Name = "indir2"; + public static final String injarName = "injar.jar"; + public static final String outjarName = "/bin/output.jar"; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("ReweavableTest"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + handler.dontIgnore(IMessage.INFO); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + /** + * Aim: Check we haven't damaged 'normal compilation' when not supplying + * -Xreweavable. Also determines baseline sizes for the compiled class files + * for later comparison. + * + * Inputs to the compiler: NonReweavable1.lst -> CalculatePI.java -> + * Logger.aj -> -verbose -> -noExit + * + * Expected result = Compile successful, the types will not be reweavable + * and the weaver should not report it is running in reweavable mode. + */ + public void testNonReweavableCompile() { + if (debugTests)System.out.println("testNonReweavableCompile: Building with NonReweavable1.lst"); + String[] files = new String[] { "CalculatePI.java", "Logger.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-verbose -noExit -XnotReweavable"); + + doBuild(true); + + assertFalse("Did not expect to find a message about the weaver operating " + + "in reweavable mode",checkFor("weaver operating in reweavable mode")); + + File fCalc = openFile("bin/CalculatePI.class"); + File fLog = openFile("bin/Logger.class"); + assertTrue("bin/CalculatePI.class should exist?!?", fCalc.exists()); + assertTrue("bin/Logger.class should exist?!?", fLog.exists()); + if (debugTests) + System.out.println("CalculatePI.class is of size: " + + fCalc.length()); + if (debugTests) + System.out.println("Logger.class is of size: " + fLog.length()); + if (debugTests) + System.out.println("\n\n\n"); + /* nonreweavesize_CalculatePI = (int) */fCalc.length(); + /* nonreweavesize_Logger = (int) */fLog.length(); + } + + /** + * Aim: Basic call to -Xreweavable. Weaver should report it is in reweavable + * mode and the classes produced should be much larger than normal classes + * (those produced in the first test). + * + * Inputs to the compiler: Reweavable1.lst -> CalculatePI.java -> Logger.aj -> + * -Xreweavable -> -verbose -> -noExit + * + * Expected result = Compile successful, the types will be reweavable and + * the weaver should report it is running in reweavable mode. The files + * produced should be larger than those created during the last test. + */ + public void testReweavableCompile() { + if (debugTests) + System.out + .println("testReweavableCompile: Building with Reweavable1.lst"); + String[] files = new String[] { "CalculatePI.java", "Logger.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-verbose -noExit"); + + doBuild(true); + + assertTrue("Expected a message about operating in reweavable mode, but " + + "didn't get one",checkFor("weaver operating in reweavable mode")); + + File fCalc = openFile("bin/CalculatePI.class"); + File fLog = openFile("bin/Logger.class"); + assertTrue("bin/CalculatePI.class should exist?!?", fCalc.exists()); + assertTrue("bin/Logger.class should exist?!?", fLog.exists()); + if (debugTests) + System.out.println("CalculatePI.class is of size: " + + fCalc.length()); + if (debugTests) + System.out.println("Logger.class is of size: " + fLog.length()); + // Temporarily remove these tests - it seems the order in which the + // testXXX methods are run cannot be relied upon + // so reweavablesize_XXX fields might not have been set yet. + // assertTrue("Reweavable version should be larger than non-reweavable + // version of CalculatePI", + // fCalc.length()>nonreweavesize_CalculatePI); + // assertTrue("Reweavable version should be larger than non-reweavable + // version of Logger", + // fLog.length()>nonreweavesize_Logger); + + /* reweavablesize_CalculatePI = (int) */fCalc.length(); + /* reweavablesize_Logger = (int) */fLog.length(); + + if (debugTests) + System.out.println("\n\n\n"); + } + + /** + * Aim: Use the optional ':compress' modifier on -Xreweavable. This causes + * some of the meta-data for use in reweaving to be compressed. It should + * succeed and produce class files smaller than straight -Xreweavable but + * larger than without specifying -Xreweavable. + * + * Inputs to the compiler: ReweavableCompress1.lst -> CalculatePI.java -> + * Logger.aj -> -Xreweavable:compress -> -verbose -> -noExit + * + * Expected result = Compile successful, the types will be reweavable and + * the weaver should report it is running in reweavable mode. The files + * created should have a size between the non-reweavable versions and the + * reweavable (without compression) versions. + */ + public void testReweavableCompressCompile() { + if (debugTests) + System.out + .println("testReweavableCompressCompile: Building with ReweavableCompress1.lst"); + + String[] files = new String[] { "CalculatePI.java", "Logger.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig + .setNonStandardOptions("-Xreweavable:compress -verbose -noExit"); + + doBuild(true); + + assertTrue( + "Expected a message about operating in reweavable mode, but didn't get one", + checkFor("weaver operating in reweavable mode")); + + File fCalc = openFile("bin/CalculatePI.class"); + File fLog = openFile("bin/Logger.class"); + assertTrue("bin/CalculatePI.class should exist?!?", fCalc.exists()); + assertTrue("bin/Logger.class should exist?!?", fLog.exists()); + int calclen = (int) fCalc.length(); + int loglen = (int) fLog.length(); + if (debugTests) + System.out.println("CalculatePI.class is of size: " + calclen); + if (debugTests) + System.out.println("Logger.class is of size: " + loglen); + // Temporarily remove these tests - it seems the order in which the + // testXXX methods are run cannot be relied upon + // so reweavablesize_XXX fields might not have been set yet. + // assertTrue("Reweavable version should be larger than non-reweavable + // version of CalculatePI", + // calclen>nonreweavesize_CalculatePI); + // assertTrue("Reweavable version should be larger than non-reweavable + // version of Logger", + // loglen>nonreweavesize_Logger); + + // Temporarily remove these tests - it seems the order in which the + // testXXX methods are run cannot be relied upon + // so reweavablesize_XXX fields might not have been set yet. + // assertTrue("Reweavable (with compression) version should be smaller + // than reweavable (without compression) version of CalculatePI:" + + // " Compressed version:"+calclen+"bytes Non-compressed + // version:"+reweavablesize_CalculatePI+"bytes", + // calclen CalculatePI.java -> + * Logger.aj -> -Xreweavable -> -verbose -> -noExit + * + * Input to the second compile: Reweavable2.lst -> SecondAspect.aj -> + * -Xreweavable -> -verbose -> -noExit -inpath bin\. + * + * Expected result = Both compiles will succeed. + */ + public void testReweavableSimpleCompile() { + if (debugTests) + System.out + .println("testReweavableSimpleCompile: Building with Reweavable1.lst"); + + String[] files = new String[] { "CalculatePI.java", "Logger.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-verbose -noExit"); + + doBuild(true); + + assertTrue( + "Expected a message about operating in reweavable mode, but didn't get one", + checkFor("weaver operating in reweavable mode")); + + if (debugTests) + System.out + .println("\ntestReweavableSimpleCompile: Building with Reweavable2.lst"); + Set paths = new HashSet(); + paths.add(openFile(binDir)); + compilerConfig.setInpath(paths); + String[] newFiles = new String[] { "SecondAspect.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(newFiles)); + + doBuild(true); + + String expMessage = "successfully verified type Logger exists"; + assertTrue("Expected message '" + expMessage + "' but did not find it", + checkFor(expMessage)); + + File fCalc = openFile("bin/CalculatePI.class"); + File fLog = openFile("bin/Logger.class"); + File fSec = openFile("bin/SecondAspect.class"); + assertTrue("bin/CalculatePI.class should exist?!?", fCalc.exists()); + assertTrue("bin/Logger.class should exist?!?", fLog.exists()); + assertTrue("bin/SecondAspect.class should exist?!?", fSec.exists()); + + if (debugTests) + System.out.println("\n\n\n"); + } + + /** + * Aim: Based on the test above, if we delete Logger.class between the first + * and second compiles the second compile should fail because there is not + * enough information to reweave CalculatePI + * + * Inputs to the first compile: Reweavable1.lst -> CalculatePI.java -> + * Logger.aj -> -Xreweavable -> -verbose -> -noExit + * + * Input to the second compile: Reweavable2.lst -> SecondAspect.aj -> + * -Xreweavable -> -verbose -> -noExit -inpath bin\. + * + * Expected result = Second compile will fail - reporting that Logger is + * missing (it 'touched' in the first compile CalculatePI) + */ + public void testForReweavableSimpleErrorCompile() { + if (debugTests) + System.out + .println("testForReweavableSimpleErrorCompile: Building with Reweavable2.lst"); + + String[] files = new String[] { "CalculatePI.java", "Logger.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-verbose -noExit"); + + doBuild(true); + + assertTrue( + "Expected a message about operating in reweavable mode, but didn't get one", + checkFor("weaver operating in reweavable mode")); + + assertTrue("Could not delete bin/Logger.class??", openFile( + "bin/Logger.class").delete()); + + if (debugTests) + System.out + .println("\ntestForReweavableSimpleErrorCompile: Building with Reweavable2.lst"); + Set paths = new HashSet(); + paths.add(openFile(binDir)); + compilerConfig.setInpath(paths); + String[] newFiles = new String[] { "SecondAspect.aj" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(newFiles)); + + doBuild(true); + + String expMessage = "type Logger is needed by reweavable type CalculatePI"; + assertTrue("Expected message '" + expMessage + "' but did not find it", + checkFor(expMessage)); + + File fCalc = openFile("bin/CalculatePI.class"); + File fLog = openFile("bin/Logger.class"); + File fSec = openFile("bin/SecondAspect.class"); + assertTrue("bin/CalculatePI.class should exist!", fCalc.exists()); + assertTrue("bin/Logger.class should not exist!", !fLog.exists()); + assertTrue("bin/SecondAspect.class should not exist!", fSec.exists()); + + if (debugTests) + System.out.println("\n\n\n"); + } + + /** + * Aim: Based on the test above, if we delete Logger.class between the first + * and second compiles the second compile should fail because there is not + * enough information to reweave CalculatePI + * + * Inputs to the first compile: TJP1.lst -> tjp/Demo.java -> + * tjp/GetInfo.java -> -Xreweavable -> -verbose -> -noExit + * + * Now, delete bin\tjp\GetInfo.class and do a compile with: TJP2.lst -> + * -Xreweavable -> -verbose -> -noExit -inpath bin\. + * + * Expected result = Second compile will fail - reporting that tjp.GetInfo + * is missing (it 'touched' in the first compile tjp.Demo) + */ + public void testErrorScenario2Compile() { + if (debugTests) + System.out.println("testErrorScenario2: Building with TJP1.lst"); + + String[] files = new String[] { "tjp" + File.separator + "Demo.java", + "tjp" + File.separator + "GetInfo.java" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig.setNonStandardOptions("-verbose -noExit"); + + doBuild(true); + + assertTrue( + "Expected a message about operating in reweavable mode, but didn't get one", + checkFor("weaver operating in reweavable mode")); + + assertTrue("Could not delete bin/tjp/GetInfo.class??", openFile( + "bin/tjp/GetInfo.class").delete()); + + if (debugTests) + System.out.println("\ntestErrorScenario2: Building with TJP2.lst"); + Set paths = new HashSet(); + paths.add(openFile(binDir)); + compilerConfig.setInpath(paths); + compilerConfig.setProjectSourceFiles(new ArrayList()); + doBuild(true); + + String expMessage = "type tjp.GetInfo is needed by reweavable type tjp.Demo"; + assertTrue("Expected message '" + expMessage + "' but did not find it", + checkFor(expMessage)); + + File fDemo = openFile("bin/tjp/Demo.class"); + File fGetInfo = openFile("bin/tjp/GetInfo.class"); + assertTrue("bin/tjp/Demo.class should exist!", fDemo.exists()); + assertTrue("bin/tjp/GetInfo.class should not exist!", !fGetInfo.exists()); + + if (debugTests)System.out.println("\n\n\n"); + } + + public void testWorkingScenario2Compile() { + if (debugTests) + System.out.println("testWorkingScenario2: Building with TJP1.lst"); + String[] files = new String[] { "tjp" + File.separator + "Demo.java", + "tjp" + File.separator + "GetInfo.java" }; + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + compilerConfig + .setNonStandardOptions("-Xreweavable:compress -verbose -noExit"); + + doBuild(true); + + assertTrue( + "Expected a message about operating in reweavable mode, but didn't get one", + checkFor("weaver operating in reweavable mode")); + + if (debugTests)System.out.println("\ntestWorkingScenario2: Building with TJP2.lst"); + Set paths = new HashSet(); + paths.add(openFile(binDir)); + compilerConfig.setInpath(paths); + compilerConfig.setProjectSourceFiles(new ArrayList()); + doBuild(true); + + String expMessage = "successfully verified type tjp.GetInfo exists"; + assertTrue("Expected message '" + expMessage + "' but did not find it", + checkFor(expMessage)); + + File fGetInfo = openFile("bin/tjp/GetInfo.class"); + File fDemo = openFile("bin/tjp/Demo.class"); + assertTrue("bin/tjp/GetInfo.class should exist!", fGetInfo.exists()); + assertTrue("bin/tjp/Demo.class should not exist!", fDemo.exists()); + + if (debugTests) + System.out.println("\n\n\n"); + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/ShowWeaveMessagesTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/ShowWeaveMessagesTests.java new file mode 100644 index 000000000..7d4b578a0 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/ShowWeaveMessagesTests.java @@ -0,0 +1,446 @@ +/* ******************************************************************* + * Copyright (c) 2004 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement Initial version + * Helen Hawkins Converted to new interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.JavaOptions; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.bridge.IMessage; +import org.aspectj.util.LangUtil; + +/** + * Weaving messages are complicated things. There are multiple places where weaving + * takes place and the places vary depending on whether we are doing a binary weave or + * going from source. All places that output weaving messages are tagged: + * // TAG: WeavingMessage + * so you can easily find them! + * + * Advice is the simplest to deal with as that is advice weaving is always done in the weaver. + * + * Next is intertype declarations. These are also always done in the weaver but in the case + * of a binary weave we don't know the originating source line for the ITD. + * + * Finally, declares. + * Declare Parents: extends Can only be done when going from source, if attempted by a + * binary weave then an error message (compiler limitation) is + * produced. + * Declare Parents: implements Is (currently!) done at both compile time and weave time. + * If going from source then the message is produced by the + * code in the compiler. if going from binary then the message + * is produced by the weaver. + * Declare Soft: Comes out with 'advice' as a special kind of advice: softener advice + * + * + * Q: Where are the messages turned on/off? + * A: It is a bit messy. See BuildArgParser.genBuildConfig(). Basically that method is the first time + * we parse the option set. Whether weaving messages are on or off is stored in the build config. + * As soon as we have parser the options and determined that weave messages are on, we grab the + * top level message handler and tell it not to ignore WeaveInfo messages. + * + * + * TODO - Other forms of declare? Do they need messages? e.g. declare precedence * + */ +public class ShowWeaveMessagesTests extends AjdeCoreTestCase { + + private static boolean regenerate; + private static boolean debugTests = false; + + static { + // Switch this to true for a single iteration if you want to reconstruct the + // 'expected weaving messages' files. + regenerate = false; + } + + public static final String PROJECT_DIR = "WeaveInfoMessagesTest"; + + public static final String binDir = "bin"; + public static final String expectedResultsDir = "expected"; + + public String[] one = new String[] {"AspectAdvice.aj","Simple.java"}; + public String[] two = new String[] {"AspectITD.aj","Simple.java"}; + public String[] three = new String[] {"AspectDeclare.aj","Simple.java"}; + public String[] four = new String[] {"AspectDeclareExtends.aj","Simple.java"}; + public String[] five = new String[] {"Simple.java","AspectDeclareSoft.aj"}; + public String[] six = new String[] {"AspectDeclareAnnotations.aj"}; + public String[] seven = new String[] {"AspectDeclareAnnotations.aj"}; + public String[] empty = new String[] {}; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject(PROJECT_DIR); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + handler.dontIgnore(IMessage.WEAVEINFO); + compilerConfig = (TestCompilerConfiguration) getCompiler().getCompilerConfiguration(); + compilerConfig.setNonStandardOptions("-showWeaveInfo"); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + /** + * Weave all the possible kinds of advice and verify the messages that come out. + */ + public void testWeaveMessagesAdvice() { + if (debugTests) System.out.println("testWeaveMessagesAdvice: Building with One.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(one)); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("advice",true); + } + + + /** + * Weave field and method ITDs and check the weave messages that come out. + */ + public void testWeaveMessagesITD() { + if (debugTests) System.out.println("\ntestWeaveMessagesITD: Building with Two.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(two)); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("itd",true); + } + + + /** + * Weave "declare parents: implements" and check the weave messages that come out. + */ + public void testWeaveMessagesDeclare() { + if (debugTests) System.out.println("\ntestWeaveMessagesDeclare: Building with Three.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(three)); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare1",true); + } + + /** + * Weave "declare parents: extends" and check the weave messages that come out. + * Can't do equivalent binary test - as can't do extends in binary. + */ + public void testWeaveMessagesDeclareExtends() { + if (debugTests) System.out.println("\ntestWeaveMessagesDeclareExtends: Building with Four.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(four)); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare.extends",true); + } + + /** + * Weave "declare soft: type: pointcut" and check the weave messages that come out. + */ + public void testWeaveMessagesDeclareSoft() { + if (debugTests) System.out.println("\ntestWeaveMessagesDeclareSoft: Building with Five.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(five)); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare.soft",true); + } + + /** + * Weave 'declare @type, @constructor, @method and @field' and check the weave messages that come out. + */ + public void testWeaveMessagesDeclareAnnotation() { + if (!LangUtil.is15VMOrGreater()) return; // annotation classes won't be about pre 15 + if (debugTests) System.out.println("\ntestWeaveMessagesDeclareAnnotation: Building with Six.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(six)); + setRunIn15Mode(); + compilerConfig.setNonStandardOptions("-showWeaveInfo -1.5"); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare.annotation",true); + } + + /** + * Weave 'declare @type, @constructor, @method and @field' and check the weave messages don't come out without the -showWeaveInfo arg. + */ + public void testWeaveMessagesDeclareAnnotationWeaveInfoOff() { + if (debugTests) System.out.println("\ntestWeaveMessagesDeclareAnnotation: Building with Seven.lst"); + compilerConfig.setProjectSourceFiles(getSourceFileList(seven)); + compilerConfig.setNonStandardOptions(""); + setRunIn15Mode(); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare.annotationNoWeaveInfo",true); + } + + + // BINARY WEAVING TESTS + + /** + * Binary weave variant of the advice weaving test above - to check messages are ok for + * binary weave. Unlike the source level weave, in this test we are using an aspect on + * the aspectpath - which means it has already had its necessary parts woven - so the list + * of weaving messages we expect is less. + */ + public void testWeaveMessagesBinaryAdvice() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryAdvice: Simple.jar + AspectAdvice.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectAdvice.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("advice.binary",true); + } + + public void testWeaveMessagesBinaryITD() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryITD: Simple.jar + AspectITD.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectITD.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("itd",false); + } + + + public void testWeaveMessagesBinaryDeclare() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryDeclare: Simple.jar + AspectDeclare.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectDeclare.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare1",false); + } + + /** + * Weave "declare soft: type: pointcut" and check the weave messages that come out. + */ + public void testWeaveMessagesBinaryDeclareSoft() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryDeclareSoft: Simple.jar + AspectDeclareSoft.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectDeclareSoft.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare.soft.binary",true); + } + + public void testWeaveMessagesBinaryAdviceInPackageFromJar() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryAdviceInPackageFromJar: Simple.jar + AspectInPackage.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectInPackage.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("advice.binary.package.jar",true); + } + + public void testWeaveMessagesBinaryAdviceInPackage() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryAdviceInPackage: Simple.jar + AspectInPackage.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("pkg")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("advice.binary.package",true); + } + + // BINARY WEAVING WHEN WE'VE LOST THE SOURCE POINTERS + + public void testWeaveMessagesBinaryAdviceNoDebugInfo() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryAdvice: Simple.jar + AspectAdvice.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple_nodebug.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectAdvice_nodebug.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("advice.binary.nodebug",true); + } + + public void testWeaveMessagesBinaryITDNoDebugInfo() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryITD: Simple.jar + AspectITD.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple_nodebug.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectITD_nodebug.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("itd.nodebug",true); + } + + public void testWeaveMessagesBinaryDeclareNoDebugInfo() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryDeclareNoDebugInfo: Simple.jar + AspectDeclare.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple_nodebug.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectDeclare_nodebug.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare1.nodebug",true); + } + + /** + * Weave "declare soft: type: pointcut" and check the weave messages that come out. + */ + public void testWeaveMessagesBinaryDeclareSoftNoDebugInfo() { + if (debugTests) System.out.println("\ntestWeaveMessagesBinaryDeclareSoftNoDebugInfo: Simple.jar + AspectDeclareSoft.jar"); + Set inpath = new HashSet(); + inpath.add(openFile("Simple_nodebug.jar")); + compilerConfig.setInpath(inpath); + Set aspectpath = new HashSet(); + aspectpath.add(openFile("AspectDeclareSoft_nodebug.jar")); + compilerConfig.setAspectPath(aspectpath); + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + verifyWeavingMessages("declare.soft.binary.nodebug",true); + } + + + public void verifyWeavingMessages(String testid,boolean source) { + File expectedF = openFile(expectedResultsDir+File.separator+testid+".txt"); + if (regenerate && source) { + // Create the file + saveWeaveMessages(expectedF); + } else { + // Verify the file matches what we have + compareWeaveMessages(expectedF); + } + } + + /** + * Compare weaving messages with what is in the file + */ + private void compareWeaveMessages(File f) { + List fileContents = new ArrayList(); + BufferedReader fr; + try { + // Load the file in + fr = new BufferedReader(new FileReader(f)); + String line = null; + while ((line=fr.readLine())!=null) fileContents.add(line); + List originalFileContents = new ArrayList(); + originalFileContents.addAll(fileContents); + + // See if the messages match + int msgCount = 0; + List l = handler.getMessages(); + for (Iterator iter = l.iterator(); iter.hasNext();) { + IMessage msg = ((TestMessageHandler.TestMessage) iter.next()).getContainedMessage(); + if (debugTests) System.out.println("Looking at ["+msg+"]"); + if (msg.getKind().equals(IMessage.WEAVEINFO)) { + if (!fileContents.contains(msg.getMessage())) { + fail("Could not find message '"+msg.getMessage()+"' in the expected results. Expected results are:\n"+ + stringify(originalFileContents)); + } else { + fileContents.remove(msg.getMessage()); + } + msgCount++; + } + } + assertTrue("Didn't get these expected messages: "+fileContents,fileContents.size()==0); + if (debugTests) System.out.println("Successfully verified "+msgCount+" weaving messages"); + } catch (Exception e) { + fail("Unexpected exception saving weaving messages:"+e); + } + } + + private String stringify(List l) { + StringBuffer result = new StringBuffer(); + for (Iterator iter = l.iterator(); iter.hasNext();) { + String str = (String) iter.next(); + result.append(str);result.append("\n"); + } + return result.toString(); + } + + /** + * Store the weaving messages in the specified file. + */ + private void saveWeaveMessages(File f) { + System.out.println("Saving weave messages into "+f.getName()); + FileWriter fw; + try { + fw = new FileWriter(f); + List l = handler.getMessages(); + for (Iterator iter = l.iterator(); iter.hasNext();) { + IMessage msg = ((TestMessageHandler.TestMessage) iter.next()).getContainedMessage(); + if (msg.getKind().equals(IMessage.WEAVEINFO)) { + fw.write(msg.getMessage()+"\n"); + } + } + fw.close(); + } catch (Exception e) { + fail("Unexpected exception saving weaving messages:"+e); + } + } + + private void setRunIn15Mode() { + Map m = new Hashtable(); + m.put(JavaOptions.COMPLIANCE_LEVEL,JavaOptions.VERSION_15); + m.put(JavaOptions.SOURCE_COMPATIBILITY_LEVEL,JavaOptions.VERSION_15); + m.put(JavaOptions.TARGET_COMPATIBILITY_LEVEL,JavaOptions.VERSION_15); + compilerConfig.setJavaOptions(m); + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/AsmDeclarationsTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/AsmDeclarationsTests.java new file mode 100644 index 000000000..3da3f0fea --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/AsmDeclarationsTests.java @@ -0,0 +1,224 @@ +/* ******************************************************************* + * 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 + * + * ******************************************************************/ +package org.aspectj.ajde.core.tests.model; + +import java.io.File; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.asm.AsmManager; +import org.aspectj.asm.IHierarchy; +import org.aspectj.asm.IProgramElement; + +public class AsmDeclarationsTests extends AjdeCoreTestCase { + + private IHierarchy model = null; + + private String[] files = new String[]{ + "ModelCoverage.java", + "pkg" + File.separator + "InPackage.java" + }; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("coverage"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + doBuild(); + model = AsmManager.getDefault().getHierarchy(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + model = null; + } + + public void testRoot() { + IProgramElement root = (IProgramElement)model.getRoot(); + assertNotNull(root); + assertEquals("Expected root to be named 'coverage' but found " + + root.toLabelString(), root.toLabelString(), "coverage"); + } + + public void testAspectAccessibility() { + IProgramElement packageAspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "AdviceNamingCoverage"); + assertNotNull(packageAspect); + assertEquals(IProgramElement.Accessibility.PACKAGE, packageAspect.getAccessibility()); + assertEquals("aspect should not have public in it's signature","aspect AdviceNamingCoverage",packageAspect.getSourceSignature()); + } + + public void testStaticModifiers() { + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "ModifiersCoverage"); + assertNotNull(aspect); + + IProgramElement staticA = model.findElementForSignature(aspect, IProgramElement.Kind.FIELD, "staticA"); + assertTrue(staticA.getModifiers().contains(IProgramElement.Modifiers.STATIC)); + + IProgramElement finalA = model.findElementForSignature(aspect, IProgramElement.Kind.FIELD, "finalA"); + assertTrue(!finalA.getModifiers().contains(IProgramElement.Modifiers.STATIC)); + assertTrue(finalA.getModifiers().contains(IProgramElement.Modifiers.FINAL)); + + } + + public void testFileInPackageAndDefaultPackage() { + IProgramElement root = model.getRoot(); + assertEquals(root.toLabelString(), "coverage"); + IProgramElement pkg = (IProgramElement)root.getChildren().get(1); + assertEquals(pkg.toLabelString(), "pkg"); + assertEquals(((IProgramElement)pkg.getChildren().get(0)).toLabelString(), "InPackage.java"); + assertEquals(((IProgramElement)root.getChildren().get(0)).toLabelString(), "ModelCoverage.java"); + } + + public void testDeclares() { + IProgramElement node = (IProgramElement)model.getRoot(); + assertNotNull(node); + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "DeclareCoverage"); + assertNotNull(aspect); + + String label = "declare error: \"Illegal construct..\""; + IProgramElement decErrNode = model.findElementForSignature(aspect, IProgramElement.Kind.DECLARE_ERROR, "declare error"); + assertNotNull(decErrNode); + assertEquals(decErrNode.toLabelString(), label); + + String decWarnMessage = "declare warning: \"Illegal call.\""; + IProgramElement decWarnNode = model.findElementForSignature(aspect, IProgramElement.Kind.DECLARE_WARNING, "declare warning"); + assertNotNull(decWarnNode); + assertEquals(decWarnNode.toLabelString(), decWarnMessage); + + String decParentsMessage = "declare parents: implements Serializable"; + IProgramElement decParentsNode = model.findElementForSignature(aspect, IProgramElement.Kind.DECLARE_PARENTS, "declare parents"); + assertNotNull(decParentsNode); + assertEquals(decParentsNode.toLabelString(), decParentsMessage); + // check the next two relative to this one + int declareIndex = decParentsNode.getParent().getChildren().indexOf(decParentsNode); + String decParentsPtnMessage = "declare parents: extends Observable"; + assertEquals(decParentsPtnMessage,((IProgramElement)aspect.getChildren().get(declareIndex+1)).toLabelString()); + String decParentsTPMessage = "declare parents: extends Observable"; + assertEquals(decParentsTPMessage,((IProgramElement)aspect.getChildren().get(declareIndex+2)).toLabelString()); + + String decSoftMessage = "declare soft: SizeException"; + IProgramElement decSoftNode = model.findElementForSignature(aspect, IProgramElement.Kind.DECLARE_SOFT, "declare soft"); + assertNotNull(decSoftNode); + assertEquals(decSoftNode.toLabelString(), decSoftMessage); + + String decPrecMessage = "declare precedence: AdviceCoverage, InterTypeDecCoverage, "; + IProgramElement decPrecNode = model.findElementForSignature(aspect, IProgramElement.Kind.DECLARE_PRECEDENCE, "declare precedence"); + assertNotNull(decPrecNode); + assertEquals(decPrecNode.toLabelString(), decPrecMessage); + } + + public void testInterTypeMemberDeclares() { + IProgramElement node = (IProgramElement)model.getRoot(); + assertNotNull(node); + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "InterTypeDecCoverage"); + assertNotNull(aspect); + + String fieldMsg = "Point.xxx"; + IProgramElement fieldNode = model.findElementForLabel(aspect, IProgramElement.Kind.INTER_TYPE_FIELD, fieldMsg); + assertNotNull(fieldNode); + assertEquals(fieldNode.toLabelString(), fieldMsg); + + String methodMsg = "Point.check(int,Line)"; + IProgramElement methodNode = model.findElementForLabel(aspect, IProgramElement.Kind.INTER_TYPE_METHOD, methodMsg); + assertNotNull(methodNode); + assertEquals(methodNode.toLabelString(), methodMsg); + + // TODO: enable +// String constructorMsg = "Point.new(int, int, int)"; +// ProgramElementNode constructorNode = model.findNode(aspect, ProgramElementNode.Kind.INTER_TYPE_CONSTRUCTOR, constructorMsg); +// assertNotNull(constructorNode); +// assertEquals(constructorNode.toLabelString(), constructorMsg); + } + + public void testPointcuts() { + IProgramElement node = (IProgramElement)model.getRoot(); + assertNotNull(node); + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "AdviceNamingCoverage"); + assertNotNull(aspect); + + String ptct = "named()"; + IProgramElement ptctNode = model.findElementForSignature(aspect, IProgramElement.Kind.POINTCUT, ptct); + assertNotNull(ptctNode); + assertEquals(ptctNode.toLabelString(), ptct); + + String params = "namedWithArgs(int,int)"; + IProgramElement paramsNode = model.findElementForSignature(aspect, IProgramElement.Kind.POINTCUT, params); + assertNotNull(paramsNode); + assertEquals(paramsNode.toLabelString(), params); + } + + public void testAbstract() { + IProgramElement node = (IProgramElement)model.getRoot(); + assertNotNull(node); + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "AbstractAspect"); + assertNotNull(aspect); + + String abst = "abPtct()"; + IProgramElement abstNode = model.findElementForSignature(aspect, IProgramElement.Kind.POINTCUT, abst); + assertNotNull(abstNode); + assertEquals(abstNode.toLabelString(), abst); + } + + public void testAdvice() { + IProgramElement node = (IProgramElement)model.getRoot(); + assertNotNull(node); + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "AdviceNamingCoverage"); + assertNotNull(aspect); + + String anon = "before(): "; + IProgramElement anonNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, anon); + assertNotNull(anonNode); + assertEquals(anonNode.toLabelString(), anon); + + String named = "before(): named.."; + IProgramElement namedNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, named); + assertNotNull(namedNode); + assertEquals(namedNode.toLabelString(), named); + + String namedWithOneArg = "around(int): namedWithOneArg.."; + IProgramElement namedWithOneArgNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, namedWithOneArg); + assertNotNull(namedWithOneArgNode); + assertEquals(namedWithOneArgNode.toLabelString(), namedWithOneArg); + + String afterReturning = "afterReturning(int,int): namedWithArgs.."; + IProgramElement afterReturningNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, afterReturning); + assertNotNull(afterReturningNode); + assertEquals(afterReturningNode.toLabelString(), afterReturning); + + String around = "around(int): namedWithOneArg.."; + IProgramElement aroundNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, around); + assertNotNull(aroundNode); + assertEquals(aroundNode.toLabelString(), around); + + String compAnon = "before(int): .."; + IProgramElement compAnonNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, compAnon); + assertNotNull(compAnonNode); + assertEquals(compAnonNode.toLabelString(), compAnon); + + String compNamed = "before(int): named().."; + IProgramElement compNamedNode = model.findElementForLabel(aspect, IProgramElement.Kind.ADVICE, compNamed); + assertNotNull(compNamedNode); + assertEquals(compNamedNode.toLabelString(), compNamed); + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/AsmRelationshipsTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/AsmRelationshipsTests.java new file mode 100644 index 000000000..fca358138 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/AsmRelationshipsTests.java @@ -0,0 +1,206 @@ +/* ******************************************************************* + * 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 + * + * ******************************************************************/ + +package org.aspectj.ajde.core.tests.model; + +import java.io.File; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.ajdt.internal.core.builder.AsmHierarchyBuilder; +import org.aspectj.asm.AsmManager; +import org.aspectj.asm.IProgramElement; +import org.aspectj.asm.IRelationship; + +public class AsmRelationshipsTests extends AjdeCoreTestCase { + + private AsmManager manager = null; + + private String[] files = new String[]{ + "ModelCoverage.java", + "pkg" + File.separator + "InPackage.java" + }; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("coverage"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + doBuild(); + manager = AsmManager.getDefault(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + manager = null; + } + + // see pr148027 + public void testUsesPointcut() { + if (!AsmHierarchyBuilder.shouldAddUsesPointcut) return; + + IProgramElement ptUsage = AsmManager.getDefault().getHierarchy().findElementForType(null, "PointcutUsage"); + assertNotNull(ptUsage); + IProgramElement pts = AsmManager.getDefault().getHierarchy().findElementForType(null, "Pointcuts"); + assertNotNull(pts); + + IProgramElement pUsesA = manager.getHierarchy().findElementForLabel( + ptUsage, + IProgramElement.Kind.POINTCUT, + "usesA()"/*Point"*/); + assertNotNull(pUsesA); + + IProgramElement ptsA = manager.getHierarchy().findElementForLabel( + pts, + IProgramElement.Kind.POINTCUT, + "a()"/*Point"*/); + assertNotNull(ptsA); + + assertTrue(AsmManager.getDefault().getRelationshipMap().get(pUsesA).size()>0); + assertTrue(AsmManager.getDefault().getRelationshipMap().get(ptsA).size()>0); + } + + public void testDeclareParents() { + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, "DeclareCoverage"); + + IProgramElement dp = manager.getHierarchy().findElementForLabel( + aspect, + IProgramElement.Kind.DECLARE_PARENTS, + "declare parents: implements Serializable"/*Point"*/); + + assertNotNull(dp); + /*List relations = */manager.getRelationshipMap().get(dp); + + List rels = AsmManager.getDefault().getRelationshipMap().get(dp); + assertTrue(rels.size()>0); + +// assertTrue(rel.getTargets().size() > 0); +// +// checkDeclareMapping("DeclareCoverage", "Point", , +// "Point", "matched by", "matches declare", +// IProgramElement.Kind.DECLARE_PARENTS); + } + + public void testDeclareWarningAndError() { + checkDeclareMapping("DeclareCoverage", "Point", "declare warning: \"Illegal call.\"", + "method-call(void Point.setX(int))", "matched by", "matches declare", IProgramElement.Kind.DECLARE_WARNING); + } + + public void testInterTypeDeclarations() { + checkInterTypeMapping("InterTypeDecCoverage", "Point", "Point.xxx", "Point", + "declared on", "aspect declarations", IProgramElement.Kind.INTER_TYPE_FIELD); + checkInterTypeMapping("InterTypeDecCoverage", "Point", "Point.check(int,Line)", + "Point", "declared on", "aspect declarations", IProgramElement.Kind.INTER_TYPE_METHOD); + } + + public void testAdvice() { + checkMapping("AdvisesRelationshipCoverage", "Point", "before(): methodExecutionP..", + "setX(int)", "advises", "advised by"); + checkUniDirectionalMapping("AdvisesRelationshipCoverage", "Point", "before(): getP..", + "field-get(int Point.x)", "advises"); + checkUniDirectionalMapping("AdvisesRelationshipCoverage", "Point", "before(): setP..", + "field-set(int Point.x)", "advises"); + } + + private void checkDeclareMapping(String fromType, String toType, String from, String to, + String forwardRelName, String backRelName, IProgramElement.Kind kind) { + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, fromType); + assertNotNull(aspect); + String beforeExec = from; + IProgramElement beforeExecNode = manager.getHierarchy().findElementForLabel(aspect, kind, beforeExec); + assertNotNull(beforeExecNode); + IRelationship rel = manager.getRelationshipMap().get(beforeExecNode, IRelationship.Kind.DECLARE, forwardRelName); + assertTrue(rel.getTargets().size() > 0); + String handle = (String)rel.getTargets().get(0); + assertEquals(manager.getHierarchy().findElementForHandle(handle).toString(), to); + + IProgramElement clazz = AsmManager.getDefault().getHierarchy().findElementForType(null, toType); + assertNotNull(clazz); + String set = to; + IProgramElement setNode = manager.getHierarchy().findElementForLabel(clazz, IProgramElement.Kind.CODE, set); + assertNotNull(setNode); + IRelationship rel2 = manager.getRelationshipMap().get(setNode, IRelationship.Kind.DECLARE, backRelName); + String handle2 = (String)rel2.getTargets().get(0); + assertEquals(manager.getHierarchy().findElementForHandle(handle2).toString(), from); + } + + private void checkUniDirectionalMapping(String fromType, String toType, String from, + String to, String relName) { + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, fromType); + assertNotNull(aspect); + String beforeExec = from; + IProgramElement beforeExecNode = manager.getHierarchy().findElementForLabel(aspect, IProgramElement.Kind.ADVICE, beforeExec); + assertNotNull(beforeExecNode); + IRelationship rel = manager.getRelationshipMap().get(beforeExecNode, IRelationship.Kind.ADVICE, relName); + for (Iterator it = rel.getTargets().iterator(); it.hasNext(); ) { + String currHandle = (String)it.next(); + if (manager.getHierarchy().findElementForHandle(currHandle).toLabelString().equals(to)) return; + } + fail(); // didn't find it + } + + private void checkMapping(String fromType, String toType, String from, String to, + String forwardRelName, String backRelName) { + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, fromType); + assertNotNull(aspect); + String beforeExec = from; + IProgramElement beforeExecNode = manager.getHierarchy().findElementForLabel(aspect, IProgramElement.Kind.ADVICE, beforeExec); + assertNotNull(beforeExecNode); + IRelationship rel = manager.getRelationshipMap().get(beforeExecNode, IRelationship.Kind.ADVICE, forwardRelName); + String handle = (String)rel.getTargets().get(0); + assertEquals(manager.getHierarchy().findElementForHandle(handle).toString(), to); + + IProgramElement clazz = AsmManager.getDefault().getHierarchy().findElementForType(null, toType); + assertNotNull(clazz); + String set = to; + IProgramElement setNode = manager.getHierarchy().findElementForLabel(clazz, IProgramElement.Kind.METHOD, set); + assertNotNull(setNode); + IRelationship rel2 = manager.getRelationshipMap().get(setNode, IRelationship.Kind.ADVICE, backRelName); + String handle2 = (String)rel2.getTargets().get(0); + assertEquals(manager.getHierarchy().findElementForHandle(handle2).toString(), from); + } + + private void checkInterTypeMapping(String fromType, String toType, String from, + String to, String forwardRelName, String backRelName, IProgramElement.Kind declareKind) { + + IProgramElement aspect = AsmManager.getDefault().getHierarchy().findElementForType(null, fromType); + assertNotNull(aspect); + String beforeExec = from; + IProgramElement fromNode = manager.getHierarchy().findElementForLabel(aspect, declareKind, beforeExec); + assertNotNull(fromNode); + IRelationship rel = manager.getRelationshipMap().get(fromNode, IRelationship.Kind.DECLARE_INTER_TYPE, forwardRelName); + String handle = (String)rel.getTargets().get(0); + assertEquals(manager.getHierarchy().findElementForHandle(handle).toString(), to); + + IProgramElement clazz = AsmManager.getDefault().getHierarchy().findElementForType(null, toType); + assertNotNull(clazz); +// String set = to; + IRelationship rel2 = manager.getRelationshipMap().get(clazz, IRelationship.Kind.DECLARE_INTER_TYPE, backRelName); +// String handle2 = (String)rel2.getTargets().get(0); + for (Iterator it = rel2.getTargets().iterator(); it.hasNext(); ) { + String currHandle = (String)it.next(); + if (manager.getHierarchy().findElementForHandle(currHandle).toLabelString().equals(from)) return; + } + fail(); // didn't find it + } +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/SavedModelConsistencyTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/SavedModelConsistencyTests.java new file mode 100644 index 000000000..99f6e354f --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/SavedModelConsistencyTests.java @@ -0,0 +1,119 @@ +/* ******************************************************************* + * 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: + * Mik Kersten initial implementation + * Helen Hawkins Converted to new interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests.model; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.asm.AsmManager; +import org.aspectj.asm.HierarchyWalker; +import org.aspectj.asm.IHierarchy; +import org.aspectj.asm.IProgramElement; + +public class SavedModelConsistencyTests extends AjdeCoreTestCase { + + private String[] files = new String[]{ + "ModelCoverage.java", + "pkg" + File.separator + "InPackage.java" + }; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("coverage"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + // In order to get a model on the disk to read in, do a build with the right flag set ! + try { + AsmManager.dumpModelPostBuild=true; + doBuild(); + } finally { + AsmManager.dumpModelPostBuild=false; + } + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + } + + public void testInterfaceIsSameInBoth() { + AsmManager.getDefault().readStructureModel(getAbsoluteProjectDir()); + + IHierarchy model = AsmManager.getDefault().getHierarchy(); + assertTrue("model exists", model != null); + + assertTrue("root exists", model.getRoot() != null); // TODO-path + File testFile = openFile("ModelCoverage.java"); + assertTrue("Expected " + testFile.getAbsolutePath() + " to exist, but it did not", testFile.exists()); + + IProgramElement nodePreBuild = model.findElementForSourceLine(testFile.getAbsolutePath(), 5); + + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + + IProgramElement nodePostBuild = model.findElementForSourceLine(testFile.getAbsolutePath(), 5); + + assertTrue("Nodes should be identical: Prebuild kind = "+nodePreBuild.getKind()+ + " Postbuild kind = "+nodePostBuild.getKind(), + nodePreBuild.getKind().equals(nodePostBuild.getKind())); + + } + + public void testModelIsSamePreAndPostBuild() { + AsmManager.getDefault().readStructureModel(getAbsoluteProjectDir()); + IHierarchy model = AsmManager.getDefault().getHierarchy(); + assertTrue("model exists", model != null); + + final List preBuildKinds = new ArrayList(); + HierarchyWalker walker = new HierarchyWalker() { + public void preProcess(IProgramElement node) { + preBuildKinds.add(node.getKind()); + } + }; + AsmManager.getDefault().getHierarchy().getRoot().walk(walker); + assertFalse("Expected there to be build kinds but didn't " + + "find any", preBuildKinds.isEmpty()); + + doBuild(); + assertTrue("Expected no compiler errors but found " + + handler.getErrors(), handler.getErrors().isEmpty()); + + final List postBuildKinds = new ArrayList(); + HierarchyWalker walker2 = new HierarchyWalker() { + public void preProcess(IProgramElement node) { + postBuildKinds.add(node.getKind()); + } + }; + AsmManager.getDefault().getHierarchy().getRoot().walk(walker2); + assertFalse("Expected there to be build kinds but didn't " + + "find any", preBuildKinds.isEmpty()); + + assertTrue("Lists should be the same: PRE"+preBuildKinds.toString() + +" POST"+postBuildKinds.toString(),preBuildKinds.equals(postBuildKinds)); + + } + +} diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/StructureModelTests.java b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/StructureModelTests.java new file mode 100644 index 000000000..8d9a7f836 --- /dev/null +++ b/ajde.core/testsrc/org/aspectj/ajde/core/tests/model/StructureModelTests.java @@ -0,0 +1,152 @@ +/* ******************************************************************* + * 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 + * AMC 21.01.2003 fixed for new source location in eclipse.org + * Helen Hawkins Converted to new interface (bug 148190) + * ******************************************************************/ +package org.aspectj.ajde.core.tests.model; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.aspectj.ajde.core.AjdeCoreTestCase; +import org.aspectj.ajde.core.TestCompilerConfiguration; +import org.aspectj.ajde.core.TestMessageHandler; +import org.aspectj.asm.AsmManager; +import org.aspectj.asm.HierarchyWalker; +import org.aspectj.asm.IHierarchy; +import org.aspectj.asm.IProgramElement; + +public class StructureModelTests extends AjdeCoreTestCase { + + private AsmManager manager = null; + + private String[] files = new String[]{ + "figures" + File.separator + "Debug.java", + "figures" + File.separator + "Figure.java", + "figures" + File.separator + "FigureElement.java", + "figures" + File.separator + "Main.java", + "figures" + File.separator + "composites" + File.separator + "Line.java", + "figures" + File.separator + "composites" + File.separator + "Square.java", + "figures" + File.separator + "primitives" + File.separator + "planar" + File.separator + "Point.java", + "figures" + File.separator + "primitives" + File.separator + "solid" + File.separator + "SolidPoint.java" + }; + + private TestMessageHandler handler; + private TestCompilerConfiguration compilerConfig; + + protected void setUp() throws Exception { + super.setUp(); + initialiseProject("figures-coverage"); + handler = (TestMessageHandler) getCompiler().getMessageHandler(); + compilerConfig = (TestCompilerConfiguration) getCompiler() + .getCompilerConfiguration(); + compilerConfig.setProjectSourceFiles(getSourceFileList(files)); + doBuild(); + manager = AsmManager.getDefault(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + handler = null; + compilerConfig = null; + manager = null; + } + + public void testRootForSourceFile() throws IOException { + File testFile = openFile("figures" + File.separator + "Figure.java"); + IProgramElement node = manager.getHierarchy().findElementForSourceFile( + testFile.getAbsolutePath()); + assertTrue("find result", node != null) ; + IProgramElement pNode = (IProgramElement)node; + String child = ((IProgramElement)pNode.getChildren().get(1)).getName(); + assertTrue("expected Figure got child " + child, child.equals("Figure")); + } + + public void testPointcutName() throws IOException { + File testFile = openFile("figures" + File.separator + "Main.java"); + IProgramElement node = manager.getHierarchy().findElementForSourceFile( + testFile.getAbsolutePath()); + assertTrue("find result", node != null) ; + IProgramElement pNode = (IProgramElement)((IProgramElement)node).getChildren().get(2); + IProgramElement pointcut = (IProgramElement)pNode.getChildren().get(0); + assertTrue("kind", pointcut.getKind().equals(IProgramElement.Kind.POINTCUT)); + assertTrue("found node: " + pointcut.getName(), pointcut.toLabelString().equals("testptct()")); + } + + public void testFileNodeFind() throws IOException { + File testFile = openFile("figures" + File.separator + "Main.java"); + +// System.err.println(((IProgramElement)((IProgramElement)Ajde.getDefault().getStructureModelManager().getHierarchy().getRoot().getChildren().get(0)).getChildren().get(3)).getSourceLocation().getSourceFile().getAbsolutePath()); +// System.err.println(testFile.getAbsolutePath()); + + IProgramElement node = manager.getHierarchy().findElementForSourceLine( + testFile.getAbsolutePath(), 1); + assertTrue("find result", node != null) ; + assertEquals("find result has children", 3, node.getChildren().size()) ; + IProgramElement pNode = (IProgramElement)node; + assertTrue("found node: " + pNode.getName(), pNode.getKind().equals(IProgramElement.Kind.FILE_JAVA)); + } + + /** + * @todo add negative test to make sure things that aren't runnable aren't annotated + */ + public void testMainClassNodeInfo() throws IOException { + IHierarchy model = manager.getHierarchy(); + assertTrue("model exists", model != null); + assertTrue("root exists", model.getRoot() != null); + File testFile = openFile("figures" + File.separator + "Main.java"); + IProgramElement node = model.findElementForSourceLine(testFile.getAbsolutePath(), 11); + assertTrue("find result", node != null); + IProgramElement pNode = (IProgramElement)((IProgramElement)node).getParent(); + if (null == pNode) { + assertTrue("null parent of " + node, false); + } + assertTrue("found node: " + pNode.getName(), pNode.isRunnable()); + } + + /** + * Integrity could be checked somewhere in the API. + */ + public void testModelIntegrity() { + IProgramElement modelRoot = manager.getHierarchy().getRoot(); + assertTrue("root exists", modelRoot != null); + + try { + testModelIntegrityHelper(modelRoot); + } catch (Exception e) { + assertTrue(e.toString(), false); + } + } + + private void testModelIntegrityHelper(IProgramElement node) throws Exception { + for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { + IProgramElement child = (IProgramElement)it.next(); + if (node == child.getParent()) { + testModelIntegrityHelper(child); + } else { + throw new Exception("parent-child check failed for child: " + child.toString()); + } + } + } + + public void testNoChildIsNull() { + HierarchyWalker walker = new HierarchyWalker() { + public void preProcess(IProgramElement node) { + if (node.getChildren() == null) return; + for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { + if (it.next() == null) throw new NullPointerException("null child on node: " + node.getName()); + } + } + }; + manager.getHierarchy().getRoot().walk(walker); + } +}