diff options
author | Till Brychcy | 2018-02-12 22:43:44 +0000 |
---|---|---|
committer | Till Brychcy | 2018-02-19 21:43:59 +0000 |
commit | 86b105d1761e70cf1cca4f74c60ede1ff3f77520 (patch) | |
tree | fb39f9a1d3a763b9a70d044cb351e44b837b2504 /org.eclipse.jdt.apt.core/src/org | |
parent | e603dedfdfd718d3d302f1cd90c78085d81e98f0 (diff) | |
download | eclipse.jdt.core-86b105d1761e70cf1cca4f74c60ede1ff3f77520.tar.gz eclipse.jdt.core-86b105d1761e70cf1cca4f74c60ede1ff3f77520.tar.xz eclipse.jdt.core-86b105d1761e70cf1cca4f74c60ede1ff3f77520.zip |
Bug 531072 - [testsources][apt] classes generated for test sources need
to be put in a test source folder
Change-Id: Ieb06760c55d8fe3bd04954ca13d1b9fb4f67d846
Diffstat (limited to 'org.eclipse.jdt.apt.core/src/org')
21 files changed, 324 insertions, 127 deletions
diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/env/EnvironmentFactory.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/env/EnvironmentFactory.java index f2e7417bf6..a8480307c9 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/env/EnvironmentFactory.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/env/EnvironmentFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -14,6 +14,7 @@ package org.eclipse.jdt.apt.core.env; import org.eclipse.core.resources.IFile; import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv; +import org.eclipse.jdt.apt.core.internal.util.TestCodeUtil; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.dom.CompilationUnit; @@ -41,7 +42,8 @@ public class EnvironmentFactory { node, (IFile)compilationUnit.getResource(), javaProject, - Phase.OTHER + Phase.OTHER, + TestCodeUtil.isTestCode(compilationUnit) ); return env; } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/APTDispatchRunnable.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/APTDispatchRunnable.java index e6378ef273..ee17cbae8f 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/APTDispatchRunnable.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/APTDispatchRunnable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. and others + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -119,6 +119,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable private final boolean _isFullBuild; private static final boolean SPLIT_FILES; private static final String SPLIT_FILES_PROPERTY = "org.eclipse.jdt.apt.core.split_files"; //$NON-NLS-1$ + private final boolean _isTestCode; static { String setting = System.getProperty(SPLIT_FILES_PROPERTY); @@ -132,7 +133,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable AptProject aptProject, Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories, Set<AnnotationProcessorFactory> dispatchedBatchFactories, - boolean isFullBuild){ + boolean isFullBuild, boolean isTestCode){ if( filesWithAnnotations == null ){ filesWithAnnotations = NO_FILES_TO_PROCESS; @@ -145,7 +146,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable filesWithoutAnnotations, problemRecorder, aptProject, factories, - dispatchedBatchFactories, isFullBuild ); + dispatchedBatchFactories, isFullBuild, isTestCode ); IWorkspace workspace = ResourcesPlugin.getWorkspace(); try { workspace.run(runnable, aptProject.getJavaProject().getResource(), IWorkspace.AVOID_UPDATE, null); @@ -159,13 +160,14 @@ public class APTDispatchRunnable implements IWorkspaceRunnable public static void runAPTDuringReconcile( ReconcileContext reconcileContext, AptProject aptProject, - Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories) + Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories, + boolean test) { // Reconciling, so we do not want to run this as an atomic workspace // operation. If we do, it is easy to have locking issues when someone // calls a reconcile from within a workspace lock - APTDispatchRunnable runnable = new APTDispatchRunnable( aptProject, factories ); - runnable.reconcile(reconcileContext, aptProject.getJavaProject()); + APTDispatchRunnable runnable = new APTDispatchRunnable( aptProject, factories, test); + runnable.reconcile(reconcileContext, aptProject.getJavaProject(), test); } /** create a runnable used during build */ @@ -176,7 +178,8 @@ public class APTDispatchRunnable implements IWorkspaceRunnable AptProject aptProject, Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories, Set<AnnotationProcessorFactory> dispatchedBatchFactories, - boolean isFullBuild) + boolean isFullBuild, + boolean isTestCode) { assert filesWithAnnotation != null : "missing files"; //$NON-NLS-1$ _filesWithAnnotation = filesWithAnnotation; @@ -186,14 +189,17 @@ public class APTDispatchRunnable implements IWorkspaceRunnable _factories = factories; _dispatchedBatchFactories = dispatchedBatchFactories; _isFullBuild = isFullBuild; + _isTestCode = isTestCode; } /** create a runnable used during reconcile */ private APTDispatchRunnable( AptProject aptProject, - Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories) + Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories, + boolean test) { _aptProject = aptProject; _factories = factories; + _isTestCode = test; _isFullBuild = false; // does not apply in reconcile case. we don't generate file during // reconcile and no apt rounding ever occur as a result. @@ -201,7 +207,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable } private void reconcile(final ReconcileContext reconcileContext, - IJavaProject javaProject) + IJavaProject javaProject, boolean test) { if (_factories.size() == 0) { if (AptPlugin.DEBUG) @@ -214,7 +220,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable // Construct a reconcile time environment. This will invoke // dispatch from inside the callback. - GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); + GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(test); gfm.reconcileStarted(); EnvCallback callback = new ReconcileEnvCallback(reconcileContext, gfm); AbstractCompilationEnv.newReconcileEnv(reconcileContext, callback); @@ -308,7 +314,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable // We need to save the file dependency state regardless of whether any Java 5 processing // was performed, because it may also contain Java 6 information. - _aptProject.getGeneratedFileManager().writeState(); + _aptProject.getGeneratedFileManager(_isTestCode).writeState(); } /** @@ -341,7 +347,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable private void runAPTInFileBasedMode(final BuildEnv processorEnv) { final BuildContext[] cpResults = processorEnv.getFilesWithAnnotation(); - final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); + final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(_isTestCode); boolean projectEnablesReconcile = AptConfig.shouldProcessDuringReconcile(_aptProject.getJavaProject()); for (BuildContext curResult : cpResults ) { processorEnv.beginFileProcessing(curResult); @@ -566,7 +572,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable // If there are no files to be built, apt will not be involved. assert firstResult != null : "don't know where to report results"; //$NON-NLS-1$ if(firstResult != null ){ - final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); + final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(_isTestCode); reportResult( firstResult, // just put it all in processorEnv.getAllGeneratedFiles(), @@ -608,7 +614,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable } } - final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); + final GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(_isTestCode); reportResult( curResult, processorEnv.getAllGeneratedFiles(), @@ -749,7 +755,7 @@ public class APTDispatchRunnable implements IWorkspaceRunnable return; } final Set<IFile> deleted = new HashSet<>(); - GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(); + GeneratedFileManager gfm = _aptProject.getGeneratedFileManager(_isTestCode); Set<IFile> java6GeneratedFiles = AptCompilationParticipant.getInstance().getJava6GeneratedFiles(); for( BuildContext cpResult : cpResults){ final IFile parentFile = cpResult.getFile(); diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptCompilationParticipant.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptCompilationParticipant.java index 3a0a7e7d87..b78916bd8f 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptCompilationParticipant.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptCompilationParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -25,6 +25,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.apt.core.internal.util.FactoryPath; +import org.eclipse.jdt.apt.core.internal.util.TestCodeUtil; import org.eclipse.jdt.apt.core.util.AptConfig; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; @@ -135,8 +136,12 @@ public class AptCompilationParticipant extends CompilationParticipant // also exclude files that has already been processed. int annoFileCount = 0; int noAnnoFileCount = 0; + boolean test = false; for( int i=0; i<total; i++ ){ BuildContext bc = allfiles[i]; + if(bc.isTestCode()) { + test = true; + } if( _buildRound > 0 && _processedFiles.containsKey( bc.getFile() )){ // We've already processed this file; we'll skip reprocessing it, on // the assumption that nothing would change, but we need to re-report @@ -191,7 +196,8 @@ public class AptCompilationParticipant extends CompilationParticipant aptProject, factories, _previousRoundsBatchFactories, - _isBatch); + _isBatch, + test); _previousRoundsBatchFactories.addAll(dispatchedBatchFactories); } finally { @@ -215,14 +221,14 @@ public class AptCompilationParticipant extends CompilationParticipant Map<AnnotationProcessorFactory, FactoryPath.Attributes> factories = AnnotationProcessorFactoryLoader.getLoader().getJava5FactoriesAndAttributesForProject( javaProject ); - APTDispatchRunnable.runAPTDuringReconcile(context, aptProject, factories); + APTDispatchRunnable.runAPTDuringReconcile(context, aptProject, factories, TestCodeUtil.isTestCode(workingCopy)); } @Override public void cleanStarting(IJavaProject javaProject){ IProject p = javaProject.getProject(); - AptPlugin.getAptProject(javaProject).projectClean( true ); + AptPlugin.getAptProject(javaProject).projectClean( true, true, true ); try{ // clear out all markers during a clean. IMarker[] markers = p.findMarkers(AptPlugin.APT_BATCH_PROCESSOR_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java index 8b28ab7d56..53a266c078 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/AptProject.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -28,26 +28,32 @@ public class AptProject { private final IJavaProject _javaProject; - private final GeneratedFileManager _gfm; + private final GeneratedFileManager _main_gfm; - private final GeneratedSourceFolderManager _gsfm; + private final GeneratedSourceFolderManager _main_gsfm; + + private final GeneratedFileManager _test_gfm; + private final GeneratedSourceFolderManager _test_gsfm; + public AptProject(final IJavaProject javaProject) { _javaProject = javaProject; - _gsfm = new GeneratedSourceFolderManager(this); - _gfm = new GeneratedFileManager(this, _gsfm); + _main_gsfm = new GeneratedSourceFolderManager(this, false); + _main_gfm = new GeneratedFileManager(this, _main_gsfm); + _test_gsfm = new GeneratedSourceFolderManager(this, true); + _test_gfm = new GeneratedFileManager(this, _test_gsfm); } public IJavaProject getJavaProject() { return _javaProject; } - public GeneratedFileManager getGeneratedFileManager() { - return _gfm; + public GeneratedFileManager getGeneratedFileManager(boolean isTestCode) { + return isTestCode ? _test_gfm : _main_gfm; } - public GeneratedSourceFolderManager getGeneratedSourceFolderManager() { - return _gsfm; + public GeneratedSourceFolderManager getGeneratedSourceFolderManager(boolean isTestCode) { + return isTestCode ? _test_gsfm : _main_gsfm; } /** @@ -55,7 +61,8 @@ public class AptProject { * initialization and verify configuration. */ public void compilationStarted() { - _gfm.compilationStarted(); + getGeneratedFileManager(false).compilationStarted(); + getGeneratedFileManager(true).compilationStarted(); } /** @@ -68,10 +75,12 @@ public class AptProject { */ public void preferenceChanged(String key) { if (AptPreferenceConstants.APT_GENSRCDIR.equals(key)) { - _gsfm.folderNamePreferenceChanged(); - } - else if(AptPreferenceConstants.APT_ENABLED.equals(key) ){ - _gsfm.enabledPreferenceChanged(); + _main_gsfm.folderNamePreferenceChanged(); + } else if (AptPreferenceConstants.APT_GENTESTSRCDIR.equals(key)) { + _test_gsfm.folderNamePreferenceChanged(); + } else if(AptPreferenceConstants.APT_ENABLED.equals(key) ){ + _main_gsfm.enabledPreferenceChanged(); + _test_gsfm.enabledPreferenceChanged(); } } @@ -84,28 +93,42 @@ public class AptProject { * deleted, false otherwise. */ - public void projectClean( boolean deleteFiles ) + public void projectClean( boolean deleteFiles, boolean cleanMain, boolean cleanTest ) { - _gfm.projectCleaned(); + if(cleanMain) + _main_gfm.projectCleaned(); + if(cleanTest) + _test_gfm.projectCleaned(); // delete the contents of the generated source folder, but don't delete // the generated source folder because that will cause a classpath change, // which will force the next build to be a full build. if ( deleteFiles ) { - IFolder f = _gsfm.getFolder(); - if ( f != null && f.exists() ) - { - try - { - IResource[] members = f.members(); - for ( int i = 0; i<members.length; i++ ){ - FileSystemUtil.deleteDerivedResources(members[i]); + if (cleanMain) { + IFolder f = _main_gsfm.getFolder(); + if (f != null && f.exists()) { + try { + IResource[] members = f.members(); + for (int i = 0; i < members.length; i++) { + FileSystemUtil.deleteDerivedResources(members[i]); + } + } catch (CoreException ce) { + AptPlugin.log(ce, "Could not delete generated files"); //$NON-NLS-1$ } } - catch ( CoreException ce ) - { - AptPlugin.log(ce, "Could not delete generated files"); //$NON-NLS-1$ + } + if (cleanMain) { + IFolder f = _test_gsfm.getFolder(); + if (f != null && f.exists()) { + try { + IResource[] members = f.members(); + for (int i = 0; i < members.length; i++) { + FileSystemUtil.deleteDerivedResources(members[i]); + } + } catch (CoreException ce) { + AptPlugin.log(ce, "Could not delete generated files"); //$NON-NLS-1$ + } } } } @@ -116,7 +139,8 @@ public class AptProject { */ public void projectClosed() { - _gfm.projectClosed(); + _main_gfm.projectClosed(); + _test_gfm.projectClosed(); } /** @@ -130,7 +154,8 @@ public class AptProject { { if (AptPlugin.DEBUG) AptPlugin.trace("AptProject.projectDeleted cleaning state for project " + _javaProject.getElementName()); //$NON-NLS-1$ - _gfm.projectDeleted(); + _main_gfm.projectDeleted(); + _test_gfm.projectDeleted(); } } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/AbstractCompilationEnv.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/AbstractCompilationEnv.java index 60d6bea5bb..1f124d156e 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/AbstractCompilationEnv.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/AbstractCompilationEnv.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -104,9 +104,16 @@ public abstract class AbstractCompilationEnv EnvCallback callback) { assert filesWithAnnotations != null : "missing files"; //$NON-NLS-1$ - + boolean isTestCode; + if (filesWithAnnotations != null && filesWithAnnotations.length > 0) { + isTestCode = filesWithAnnotations[0].isTestCode(); + } else if (additionalFiles != null && additionalFiles.length > 0) { + isTestCode = additionalFiles[0].isTestCode(); + } else { + isTestCode = false; + } // note, we are not reading any files. - BuildEnv env = new BuildEnv(filesWithAnnotations, additionalFiles, javaProj); + BuildEnv env = new BuildEnv(filesWithAnnotations, additionalFiles, javaProj, isTestCode); env._callback = callback; env.createASTs(filesWithAnnotations); } @@ -131,9 +138,9 @@ public abstract class AbstractCompilationEnv CompilationUnit compilationUnit, IFile file, IJavaProject javaProj, - Phase phase) + Phase phase, boolean isTestCode) { - super(compilationUnit, file, javaProj, phase); + super(compilationUnit, file, javaProj, phase, isTestCode); } @Override @@ -361,5 +368,4 @@ public abstract class AbstractCompilationEnv return options.contains(AptPreferenceConstants.RTTG_ENABLED_OPTION) || options.contains(RTTG_ENABLED_DASH_A_OPTION); } - } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java index b98ca43c22..53ae29196c 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BaseProcessorEnv.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2017 BEA Systems Inc. and others + * Copyright (c) 2005, 2018 BEA Systems Inc. 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 @@ -107,6 +107,7 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment protected IFile _file; protected final IJavaProject _javaProject; protected final AptProject _aptProject; + private final boolean _isTestCode; /** * Unmodifiable map of processor options, including -A options. @@ -139,7 +140,7 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment public BaseProcessorEnv(CompilationUnit astCompilationUnit, IFile file, IJavaProject javaProj, - Phase phase ) + Phase phase, boolean isTestCode ) { _astRoot = astCompilationUnit; _file = file; @@ -149,6 +150,7 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment _modelCompUnit2astCompUnit = new HashMap<>(); _typeBinding2ModelCompUnit = new HashMap<>(); _aptProject = AptPlugin.getAptProject(javaProj); + _isTestCode = isTestCode; } /** @@ -168,7 +170,7 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment * so this will always be up to date with the latest settings. */ private Map<String, String> initOptions(IJavaProject jproj) { - Map<String, String> procOptions = AptConfig.getProcessorOptions(jproj); + Map<String, String> procOptions = AptConfig.getProcessorOptions(jproj, isTestCode()); // options is large enough to include the translated -A options Map<String, String> options = new HashMap<>(procOptions.size() * 2); @@ -1009,4 +1011,5 @@ public class BaseProcessorEnv implements AnnotationProcessorEnvironment public IProject getProject(){ return _javaProject.getProject(); } public IJavaProject getJavaProject(){ return _javaProject; } public AptProject getAptProject(){ return _aptProject; } + public boolean isTestCode() { return _isTestCode; } } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java index e6c5cca85b..a0b687b187 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -81,7 +81,7 @@ public class BinaryFileOutputStream extends ByteArrayOutputStream { IFile parentFile = _env.getFile(); if (parentFile != null) { - _env.getAptProject().getGeneratedFileManager().addGeneratedFileDependency(Collections.singleton(parentFile), _file); + _env.getAptProject().getGeneratedFileManager(_env.isTestCode()).addGeneratedFileDependency(Collections.singleton(parentFile), _file); _env.addGeneratedNonSourceFile(_file); } } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildEnv.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildEnv.java index 91510b9292..6a306b9b89 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildEnv.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildEnv.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -89,14 +89,15 @@ public class BuildEnv extends AbstractCompilationEnv * @param additionalFiles * @param units * @param javaProj + * @param isTestCode * @param phase */ BuildEnv( final BuildContext[] filesWithAnnotations, final BuildContext[] additionalFiles, - final IJavaProject javaProj) { + final IJavaProject javaProj, boolean isTestCode) { - super(null, null, javaProj, Phase.BUILD); + super(null, null, javaProj, Phase.BUILD, isTestCode); _filer = new BuildFilerImpl(this); _filesWithAnnotation = filesWithAnnotations; _additionFiles = additionalFiles; diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildFilerImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildFilerImpl.java index 0ce8dd685b..f35c671dcf 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildFilerImpl.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BuildFilerImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 BEA Systems, Inc. + * Copyright (c) 2006, 2018 BEA Systems, Inc. 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 @@ -61,7 +61,7 @@ public class BuildFilerImpl extends FilerImpl { return new NoOpOutputStream(); } - GeneratedSourceFolderManager gsfm = _env.getAptProject().getGeneratedSourceFolderManager(); + GeneratedSourceFolderManager gsfm = _env.getAptProject().getGeneratedSourceFolderManager(_env.isTestCode()); IPath path; try { diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/FilerImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/FilerImpl.java index e46500f09c..b188f5970b 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/FilerImpl.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/FilerImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -67,7 +67,7 @@ public abstract class FilerImpl implements Filer { protected IPath getOutputFileForLocation( Filer.Location loc, String pkg, File relPath ) throws IOException { - GeneratedSourceFolderManager gsfm = getEnv().getAptProject().getGeneratedSourceFolderManager(); + GeneratedSourceFolderManager gsfm = getEnv().getAptProject().getGeneratedSourceFolderManager(getEnv().isTestCode()); IPath path = null; if ( loc == Filer.Location.CLASS_TREE ) { diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/JavaSourceFilePrintWriter.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/JavaSourceFilePrintWriter.java index fe4d15eed7..012d0f2652 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/JavaSourceFilePrintWriter.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/JavaSourceFilePrintWriter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -47,7 +47,7 @@ public class JavaSourceFilePrintWriter extends PrintWriter { try { String contents = _sw.toString(); super.close(); - GeneratedFileManager gfm = _env.getAptProject().getGeneratedFileManager(); + GeneratedFileManager gfm = _env.getAptProject().getGeneratedFileManager(_env.isTestCode()); Phase phase = _env.getPhase(); FileGenerationResult result = null; diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ReconcileEnv.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ReconcileEnv.java index 1422214990..078ebf053d 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ReconcileEnv.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/ReconcileEnv.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -16,6 +16,7 @@ import org.eclipse.jdt.apt.core.env.EclipseAnnotationProcessorEnvironment; import org.eclipse.jdt.apt.core.env.Phase; import org.eclipse.jdt.apt.core.internal.AptPlugin; import org.eclipse.jdt.apt.core.internal.env.MessagerImpl.Severity; +import org.eclipse.jdt.apt.core.internal.util.TestCodeUtil; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.compiler.ReconcileContext; @@ -42,21 +43,21 @@ public class ReconcileEnv extends AbstractCompilationEnv implements EclipseAnnot final ICompilationUnit workingCopy = context.getWorkingCopy(); IJavaProject javaProject = workingCopy.getJavaProject(); final IFile file = (IFile)workingCopy.getResource(); - return new ReconcileEnv(context, workingCopy, file, javaProject); + return new ReconcileEnv(context, workingCopy, file, javaProject, TestCodeUtil.isTestCode(workingCopy)); } private ReconcileEnv( ReconcileContext context, ICompilationUnit workingCopy, IFile file, - IJavaProject javaProj) + IJavaProject javaProj, boolean isTestCode) { // See bug 133744: calling ReconcileContext.getAST3() here would result in // a typesystem whose types are not comparable with the types we get after // openPipeline(). Instead, we start the env with an EMPTY_AST_UNIT, and // replace it with the real thing inside the openPipeline() ASTRequestor's // acceptAST() callback. - super(EMPTY_AST_UNIT, file, javaProj, Phase.RECONCILE); + super(EMPTY_AST_UNIT, file, javaProj, Phase.RECONCILE, isTestCode); _context = context; _workingCopy = workingCopy; if (AptPlugin.DEBUG_COMPILATION_ENV) AptPlugin.trace( diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java index b46c8abdb7..56bc9659f4 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/ClasspathUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -145,8 +145,10 @@ public class ClasspathUtil { /** * returns true if we updated the classpath, false otherwise + * @param specificOutputLocation + * @param */ - public static boolean updateProjectClasspath( IJavaProject jp, IFolder folder, IProgressMonitor progressMonitor ) + public static boolean updateProjectClasspath( IJavaProject jp, IFolder folder, IProgressMonitor progressMonitor, boolean isTestCode, IPath specificOutputLocation ) throws JavaModelException { IClasspathEntry[] cp = jp.getRawClasspath(); @@ -196,10 +198,13 @@ public class ClasspathUtil { } IPath[] exclusionPatterns = exclusions.toArray( new IPath[exclusions.size()] ); - final IClasspathAttribute[] attrs = new IClasspathAttribute[1]; + final IClasspathAttribute[] attrs = new IClasspathAttribute[isTestCode ? 2 : 1]; attrs[0] = JavaCore.newClasspathAttribute(IClasspathAttribute.OPTIONAL, Boolean.toString(true)); + if(isTestCode) { + attrs[1] = JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, Boolean.toString(true)); + } IClasspathEntry generatedSourceClasspathEntry = - JavaCore.newSourceEntry(folder.getFullPath(), new IPath[] {}, exclusionPatterns, null, attrs ); + JavaCore.newSourceEntry(folder.getFullPath(), new IPath[] {}, exclusionPatterns, specificOutputLocation, attrs ); IClasspathEntry[] newCp = new IClasspathEntry[cp.length + 1]; System.arraycopy(cp, 0, newCp, 0, cp.length); @@ -212,6 +217,18 @@ public class ClasspathUtil { return !found; } + public static IPath findTestOutputLocation(IClasspathEntry[] cp) { + for (IClasspathEntry entry : cp) { + if(entry.getEntryKind()==IClasspathEntry.CPE_SOURCE && entry.isTest()) { + IPath outputLocation = entry.getOutputLocation(); + if(outputLocation != null) { + return outputLocation; + } + } + } + return null; + } + /** * All methods static. Clients should not instantiate this class. */ diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java index 47690dc743..48671c290a 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. and others + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -317,7 +317,7 @@ public class GeneratedFileManager public GeneratedFileManager(final AptProject aptProject, final GeneratedSourceFolderManager gsfm) { _jProject = aptProject.getJavaProject(); _gsfm = gsfm; - _buildDeps = new GeneratedFileMap(_jProject.getProject()); + _buildDeps = new GeneratedFileMap(_jProject.getProject(), gsfm.isTestCode()); _clearDuringReconcile = new HashSet<>(); _reconcileDeps = new ManyToMany<>(); _reconcileNonDeps = new ManyToMany<>(); @@ -346,11 +346,13 @@ public class GeneratedFileManager { try { // clear out any generated source folder config markers - IMarker[] markers = _jProject.getProject().findMarkers(AptPlugin.APT_CONFIG_PROBLEM_MARKER, true, - IResource.DEPTH_INFINITE); - if (markers != null) { - for (IMarker marker : markers) - marker.delete(); + if(!_gsfm.isTestCode()) { + IMarker[] markers = _jProject.getProject().findMarkers(AptPlugin.APT_CONFIG_PROBLEM_MARKER, true, + IResource.DEPTH_INFINITE); + if (markers != null) { + for (IMarker marker : markers) + marker.delete(); + } } } catch (CoreException e) { AptPlugin.log(e, "Unable to delete configuration marker."); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileMap.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileMap.java index 49d5fb1f3f..aa7d456f0d 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileMap.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedFileMap.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2015 BEA Systems, Inc. + * Copyright (c) 2006, 2018 BEA Systems, Inc. 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 @@ -50,9 +50,12 @@ public class GeneratedFileMap extends ManyToMany<IFile, IFile> { private final IProject _proj; private final Map<IFile, Set<Flags>> _flags = new HashMap<>(); + + private final boolean _isTestCode; - public GeneratedFileMap(IProject proj) { + public GeneratedFileMap(IProject proj, boolean isTestCode) { _proj = proj; + _isTestCode = isTestCode; readState(); } @@ -114,7 +117,7 @@ public class GeneratedFileMap extends ManyToMany<IFile, IFile> { */ public synchronized void clearState() { clear(); - File state = getStateFile(_proj); + File state = getStateFile(_proj, _isTestCode); if (state != null) { boolean successfullyDeleted = state.delete(); if (!successfullyDeleted && state.exists()) { @@ -188,11 +191,12 @@ public class GeneratedFileMap extends ManyToMany<IFile, IFile> { /** * Returns the File to use for saving and restoring the last built state for the given project. * Returns null if the project does not exists (e.g. has been deleted) + * @param isTestCode */ - private File getStateFile(IProject project) { + private File getStateFile(IProject project, boolean isTestCode) { if (!project.exists()) return null; IPath workingLocation = project.getWorkingLocation(AptPlugin.PLUGIN_ID); - return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$ + return workingLocation.append(isTestCode ? "teststate.dat" : "state.dat").toFile(); //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -211,7 +215,7 @@ public class GeneratedFileMap extends ManyToMany<IFile, IFile> { * This method is not synchronized because it is called only from this object's constructor. */ private void readState() { - File file = getStateFile(_proj); + File file = getStateFile(_proj, _isTestCode); if (file == null || !file.exists()) { // We'll just start with no dependencies return; @@ -288,7 +292,7 @@ public class GeneratedFileMap extends ManyToMany<IFile, IFile> { if (!isDirty()) { return; } - File file = getStateFile(_proj); + File file = getStateFile(_proj, _isTestCode); if (file == null) { // Cannot write state, as project has been deleted return; diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java index 31e3aba84c..788fb0f734 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedResourceChangeListener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -90,7 +90,8 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener } event.getDelta().accept( pbv ); - addGeneratedSrcFolderTo(pbv.getProjectsThatNeedGenSrcFolder()); + addGeneratedSrcFolderTo(pbv.getProjectsThatNeedGenSrcFolder(), false); + addGeneratedSrcFolderTo(pbv.getProjectsThatNeedGenTestSrcFolder(), true); // Now clear the set of deleted resources, // as we don't want to re-handle them @@ -115,12 +116,12 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener } } - private void addGeneratedSrcFolderTo(final Set<IProject> projs ){ + private void addGeneratedSrcFolderTo(final Set<IProject> projs, boolean isTestCode){ for(IProject proj : projs ){ final IJavaProject javaProj = JavaCore.create(proj); if(javaProj.getProject().isOpen() && AptConfig.isEnabled(javaProj)){ - final GeneratedSourceFolderManager gsfm = AptPlugin.getAptProject(javaProj).getGeneratedSourceFolderManager(); + final GeneratedSourceFolderManager gsfm = AptPlugin.getAptProject(javaProj).getGeneratedSourceFolderManager(isTestCode); gsfm.ensureFolderExists(); } } @@ -153,6 +154,8 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener { // projects that we need to add the generated source folder to. private final Set<IProject> _addGenFolderTo = new HashSet<>(); + // projects that we need to add the generated test source folder to. + private final Set<IProject> _addGenTestFolderTo = new HashSet<>(); // any projects that is closed or about to be deleted private final Set<IProject> _removedProjects = new HashSet<>(); @Override @@ -173,6 +176,7 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener final IProject proj = (IProject)delta.getResource(); if( canUpdate(proj) ){ _addGenFolderTo.add(proj); + _addGenTestFolderTo.add(proj); } else _removedProjects.add(proj); @@ -189,13 +193,14 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener final IJavaProject javaProj = JavaCore.create(project); final AptProject aptProj = AptPlugin.getAptProject(javaProj); if( resource instanceof IFile ){ - final GeneratedFileManager gfm = aptProj.getGeneratedFileManager(); + final GeneratedFileManager gfm = aptProj.getGeneratedFileManager(false); IFile f = (IFile)resource; gfm.fileDeleted(f); + aptProj.getGeneratedFileManager(true).fileDeleted(f); } else if( resource instanceof IFolder ){ - final GeneratedSourceFolderManager gsfm = aptProj.getGeneratedSourceFolderManager(); IFolder f = (IFolder) resource; + final GeneratedSourceFolderManager gsfm = aptProj.getGeneratedSourceFolderManager(false); if ( gsfm.isGeneratedSourceFolder( f ) ){ gsfm.folderDeleted(); // all deletion occurs before any add (adding the generated source directory) @@ -206,6 +211,17 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener // deleted, will ignore this deletion since we cannot correct // the classpath anyways. } + final GeneratedSourceFolderManager testgsfm = aptProj.getGeneratedSourceFolderManager(true); + if ( testgsfm.isGeneratedSourceFolder( f ) ){ + testgsfm.folderDeleted(); + // all deletion occurs before any add (adding the generated source directory) + if( !_removedProjects.contains(project) ){ + _addGenTestFolderTo.add(project); + } + // if the project is already closed or in the process of being + // deleted, will ignore this deletion since we cannot correct + // the classpath anyways. + } } else if( resource instanceof IProject ){ _removedProjects.add((IProject)resource); @@ -216,7 +232,12 @@ public class GeneratedResourceChangeListener implements IResourceChangeListener _addGenFolderTo.removeAll(_removedProjects); return _addGenFolderTo; } - + + Set<IProject> getProjectsThatNeedGenTestSrcFolder(){ + _addGenTestFolderTo.removeAll(_removedProjects); + return _addGenTestFolderTo; + } + private boolean canUpdate(IProject proj) throws CoreException { diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java index b18c776bf6..718b6e4b83 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/GeneratedSourceFolderManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 BEA Systems, Inc. and others + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -84,13 +84,17 @@ public class GeneratedSourceFolderManager { */ private IFolder _generatedSourceFolder = null; + private final boolean _isTestCode; + + /** * Should be constructed only by AptProject. Other clients should call - * @see AptProject#getGeneratedSourceFolderManager() to get this object. + * @see AptProject#getGeneratedSourceFolderManager(boolean) to get this object. */ - public GeneratedSourceFolderManager(AptProject aptProject) + public GeneratedSourceFolderManager(AptProject aptProject, boolean isTestCode) { _aptProject = aptProject; + _isTestCode = isTestCode; final IJavaProject javaProject = aptProject.getJavaProject(); // Set _generatedSourceFolder only if APT is enabled, the folder exists, @@ -109,12 +113,13 @@ public class GeneratedSourceFolderManager { /** * Add the folder to the classpath, unless it's already there. * @param srcFolder the folder to add to the classpath. Must not be null. + * @param specificOutputLocation * @return true if, at the end of the routine, the folder is on the classpath. */ - private boolean addToClasspath(IFolder srcFolder) { + private boolean addToClasspath(IFolder srcFolder, IPath specificOutputLocation) { boolean onClasspath = false; try { - ClasspathUtil.updateProjectClasspath( _aptProject.getJavaProject(), srcFolder, null ); + ClasspathUtil.updateProjectClasspath( _aptProject.getJavaProject(), srcFolder, null, _isTestCode, specificOutputLocation ); if(AptPlugin.DEBUG) AptPlugin.trace("Ensured classpath has an entry for " + srcFolder); //$NON-NLS-1$ onClasspath = true; @@ -150,10 +155,30 @@ public class GeneratedSourceFolderManager { return; } + ensureFolderExists(srcFolder); + } + + public void ensureFolderExists(IFolder srcFolder) { + IPath specificOutputLocation; + if (_isTestCode) { + IClasspathEntry[] cp; + try { + cp = _aptProject.getJavaProject().getRawClasspath(); + } catch (JavaModelException e) { + return; + } + specificOutputLocation = ClasspathUtil.findTestOutputLocation(cp); + if (specificOutputLocation == null) { + // not test source folder present + return; + } + } else { + specificOutputLocation = null; + } // Ensure that the new folder exists on disk. if (createOnDisk(srcFolder)) { // Add it to the classpath. - if (addToClasspath(srcFolder)) { + if (addToClasspath(srcFolder, specificOutputLocation)) { // Only if we get this far do we actually set _generatedSourceFolder. synchronized ( this ) { _generatedSourceFolder = srcFolder; @@ -187,15 +212,7 @@ public class GeneratedSourceFolderManager { AptPlugin.log(status); return; } - - if (createOnDisk(srcFolder)) { - if (addToClasspath(srcFolder)) { - synchronized (this) { - // Only set _generatedSourceFolder if folder is on disk and on classpath. - _generatedSourceFolder = srcFolder; - } - } - } + ensureFolderExists(srcFolder); } /** @@ -298,7 +315,7 @@ public class GeneratedSourceFolderManager { */ public void folderDeleted() { - _aptProject.projectClean( false ); + _aptProject.projectClean( false, !_isTestCode, _isTestCode); IFolder srcFolder; synchronized(this){ @@ -371,7 +388,7 @@ public class GeneratedSourceFolderManager { * means that the name is something illegal like "..". */ private IFolder getFolderPreference() { - final String folderName = AptConfig.getGenSrcDir(_aptProject.getJavaProject()); + final String folderName = _isTestCode ? AptConfig.getGenTestSrcDir(_aptProject.getJavaProject()) : AptConfig.getGenSrcDir(_aptProject.getJavaProject()); IFolder folder = null; try { folder = _aptProject.getJavaProject().getProject().getFolder( folderName ); @@ -425,7 +442,7 @@ public class GeneratedSourceFolderManager { } // Clear out the generated file maps - _aptProject.projectClean(false); + _aptProject.projectClean(false, !_isTestCode, _isTestCode); // clean up the classpath first so that when we actually delete the // generated source folder we won't cause a classpath error. @@ -512,4 +529,7 @@ public class GeneratedSourceFolderManager { return succeeded; } + public boolean isTestCode() { + return _isTestCode; + } } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/WorkingCopyCleanupListener.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/WorkingCopyCleanupListener.java index 71f83fb9ef..053cd013c7 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/WorkingCopyCleanupListener.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/generatedfile/WorkingCopyCleanupListener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -14,6 +14,7 @@ package org.eclipse.jdt.apt.core.internal.generatedfile; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.apt.core.internal.AptPlugin; +import org.eclipse.jdt.apt.core.internal.util.TestCodeUtil; import org.eclipse.jdt.core.ElementChangedEvent; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IElementChangedListener; @@ -60,7 +61,7 @@ public class WorkingCopyCleanupListener implements IElementChangedListener if ( workingCopyDiscarded ) { IJavaProject jp = cu.getJavaProject(); - GeneratedFileManager gfm = AptPlugin.getAptProject(jp).getGeneratedFileManager(); + GeneratedFileManager gfm = AptPlugin.getAptProject(jp).getGeneratedFileManager(TestCodeUtil.isTestCode(cu)); try { gfm.workingCopyDiscarded( cu ); } catch (CoreException e) { diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java new file mode 100644 index 0000000000..4f44e64e4b --- /dev/null +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2018 Till Brychcy 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: + * Till Brychcy - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.apt.core.internal.util; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaModelException; + +public class TestCodeUtil { + + private TestCodeUtil() { + } + + public static boolean isTestCode(ICompilationUnit cu) { + IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) ((IJavaElement) cu) + .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); + if (packageFragmentRoot != null) { + try { + return packageFragmentRoot.getResolvedClasspathEntry().isTest(); + } catch (JavaModelException e) { + // ignore + } + } + return false; + } +} diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java index 7729a4384a..9615a792ac 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptConfig.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2016 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -40,6 +40,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jdt.apt.core.internal.AnnotationProcessorFactoryLoader; import org.eclipse.jdt.apt.core.internal.AptPlugin; import org.eclipse.jdt.apt.core.internal.AptProject; +import org.eclipse.jdt.apt.core.internal.generatedfile.ClasspathUtil; import org.eclipse.jdt.apt.core.internal.generatedfile.GeneratedSourceFolderManager; import org.eclipse.jdt.apt.core.internal.util.FactoryPath; import org.eclipse.jdt.apt.core.internal.util.FactoryPathUtil; @@ -58,6 +59,7 @@ import org.osgi.service.prefs.BackingStoreException; * * Helpful information about the Eclipse preferences mechanism can be found at: * http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-core-home/documents/user_settings/faq.html + * @since 3.5 */ public class AptConfig { @@ -121,6 +123,15 @@ public class AptConfig { } /** + * @deprecated Use {@link #getProcessorOptions(IJavaProject, boolean)} or + * {@link #getRawProcessorOptions(IJavaProject)} + */ + @Deprecated + public static Map<String, String> getProcessorOptions(IJavaProject jproj) { + return getProcessorOptions(jproj, false); + } + + /** * Get the options that are presented to annotation processors by the * AnnotationProcessorEnvironment. Options are key/value pairs which * are set in the project properties. @@ -160,12 +171,14 @@ public class AptConfig { * above. * * @param jproj a project, or null to query the workspace-wide setting. + * @param isTestCode if true, the programmatically set options are computed for test code compilation * @return a mutable, possibly empty, map of (key, value) pairs. * The value part of a pair may be null (equivalent to "-Akey" on the Sun apt * command line). * The value part may contain spaces. + * @since 3.6 */ - public static Map<String, String> getProcessorOptions(IJavaProject jproj) { + public static Map<String, String> getProcessorOptions(IJavaProject jproj, boolean isTestCode) { Map<String,String> rawOptions = getRawProcessorOptions(jproj); // map is large enough to also include the programmatically generated options Map<String, String> options = new HashMap<>(rawOptions.size() + 6); @@ -195,6 +208,9 @@ public class AptConfig { Set<IJavaProject> projectsProcessed = new HashSet<>(); projectsProcessed.add(jproj); for (IClasspathEntry entry : classpathEntries) { + if (!isTestCode && entry.isTest()) { + continue; + } int kind = entry.getEntryKind(); if (kind == IClasspathEntry.CPE_LIBRARY) { IPath cpPath = entry.getPath(); @@ -233,7 +249,7 @@ public class AptConfig { // If it doesn't exist, ignore it if (otherJavaProject != null && otherJavaProject.getProject().isOpen()) { - addProjectClasspath(root, otherJavaProject, projectsProcessed, classpath); + addProjectClasspath(root, otherJavaProject, projectsProcessed, classpath, isTestCode); } } } @@ -245,12 +261,12 @@ public class AptConfig { options.put("-sourcepath", convertPathCollectionToString(sourcepath)); //$NON-NLS-1$ // Get absolute path for generated source dir - IFolder genSrcDir = jproj.getProject().getFolder(getGenSrcDir(jproj)); + IFolder genSrcDir = jproj.getProject().getFolder(isTestCode ? getGenTestSrcDir(jproj) : getGenSrcDir(jproj)); String genSrcDirString = genSrcDir.getRawLocation().toOSString(); options.put("-s", genSrcDirString); //$NON-NLS-1$ // Absolute path for bin dir as well - IPath binPath = jproj.getOutputLocation(); + IPath binPath = isTestCode ? ClasspathUtil.findTestOutputLocation(jproj.getRawClasspath()) : jproj.getOutputLocation(); IResource binPathResource = root.findMember(binPath); String binDirString; if (binPathResource != null) { @@ -330,7 +346,8 @@ public class AptConfig { IWorkspaceRoot root, IJavaProject otherJavaProject, Set<IJavaProject> projectsProcessed, - Set<String> classpath) { + Set<String> classpath, + boolean isTestCode) { // Check for cycles. If we've already seen this project, // no need to go any further. @@ -355,6 +372,9 @@ public class AptConfig { // Now the rest of the classpath IClasspathEntry[] classpathEntries = otherJavaProject.getResolvedClasspath(true); for (IClasspathEntry entry : classpathEntries) { + if (!isTestCode && entry.isTest()) { + continue; + } if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IPath cpPath = entry.getPath(); @@ -374,7 +394,7 @@ public class AptConfig { IProject otherProject = root.getProject(otherProjectPath.segment(0)); IJavaProject yetAnotherJavaProject = JavaCore.create(otherProject); if (yetAnotherJavaProject != null) { - addProjectClasspath(root, yetAnotherJavaProject, projectsProcessed, classpath); + addProjectClasspath(root, yetAnotherJavaProject, projectsProcessed, classpath, isTestCode); } } // Ignore source types @@ -888,7 +908,24 @@ public class AptConfig { } setString(jproject, AptPreferenceConstants.APT_GENSRCDIR, dirString); } + + /** + * @since 3.6 + */ + public static String getGenTestSrcDir(IJavaProject jproject) { + return getString(jproject, AptPreferenceConstants.APT_GENTESTSRCDIR); + } + /** + * @since 3.6 + */ + public static void setGenTestSrcDir(IJavaProject jproject, String dirString) { + if (!GeneratedSourceFolderManager.validate(jproject, dirString)) { + throw new IllegalArgumentException("Illegal name for generated test source folder: " + dirString); //$NON-NLS-1$ + } + setString(jproject, AptPreferenceConstants.APT_GENTESTSRCDIR, dirString); + } + public static boolean validateGenSrcDir(IJavaProject jproject, String dirName) { return GeneratedSourceFolderManager.validate(jproject, dirName); } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptPreferenceConstants.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptPreferenceConstants.java index ab18c4ce32..afcdc751de 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptPreferenceConstants.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/util/AptPreferenceConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2015 BEA Systems, Inc. + * Copyright (c) 2005, 2018 BEA Systems, Inc. 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 @@ -23,6 +23,10 @@ import java.util.Map; public class AptPreferenceConstants { public static final String APT_STRING_BASE = "org.eclipse.jdt.apt"; //$NON-NLS-1$ public static final String APT_GENSRCDIR = APT_STRING_BASE + ".genSrcDir"; //$NON-NLS-1$ + /** + * @since 3.6 + */ + public static final String APT_GENTESTSRCDIR = APT_STRING_BASE + ".genTestSrcDir"; //$NON-NLS-1$ public static final String APT_PROCESSOROPTIONS = APT_STRING_BASE + ".processorOptions"; //$NON-NLS-1$ public static final String APT_RECONCILEENABLED = APT_STRING_BASE + ".reconcileEnabled"; //$NON-NLS-1$ public static final String APT_PROCESSANNOTATIONS = "org.eclipse.jdt.core.compiler.processAnnotations"; //$NON-NLS-1$ @@ -37,6 +41,10 @@ public class AptPreferenceConstants { public static final String APT_NULLVALUE = APT_STRING_BASE + ".NULLVALUE"; //$NON-NLS-1$ public static final String DEFAULT_GENERATED_SOURCE_FOLDER_NAME = ".apt_generated"; //$NON-NLS-1$ + /** + * @since 3.6 + */ + public static final String DEFAULT_GENERATED_TEST_SOURCE_FOLDER_NAME = ".apt_generated_tests"; //$NON-NLS-1$ /** * Processors should report this option in {@link com.sun.mirror.apt.AnnotationProcessorFactory#supportedOptions()} @@ -61,6 +69,7 @@ public class AptPreferenceConstants { Map<String,String> options = new HashMap<>(); options.put(AptPreferenceConstants.APT_ENABLED, "false"); //$NON-NLS-1$ options.put(AptPreferenceConstants.APT_GENSRCDIR, DEFAULT_GENERATED_SOURCE_FOLDER_NAME); + options.put(AptPreferenceConstants.APT_GENTESTSRCDIR, DEFAULT_GENERATED_TEST_SOURCE_FOLDER_NAME); options.put(AptPreferenceConstants.APT_PROCESSOROPTIONS, ""); //$NON-NLS-1$ options.put(AptPreferenceConstants.APT_RECONCILEENABLED, "true"); //$NON-NLS-1$ DEFAULT_OPTIONS_MAP = Collections.unmodifiableMap(options); @@ -76,6 +85,7 @@ public class AptPreferenceConstants { public static final String[] OPTION_NAMES = { APT_ENABLED, APT_GENSRCDIR, + APT_GENTESTSRCDIR, APT_PROCESSOROPTIONS, APT_RECONCILEENABLED, }; |