Add support for packaging Module Sources to Artifacts. (IDEA-110964)

This commit is contained in:
Ilya Ryzhenkov
2018-06-01 18:25:56 +03:00
parent 80321951e8
commit fe756f3317
36 changed files with 614 additions and 254 deletions
@@ -25,14 +25,11 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.artifacts.ArtifactManager;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
@@ -437,9 +437,9 @@ public class ArtifactUtil {
ContainerUtil.addIfNotNull(result, sourceRoot.findFileByRelativePath(path));
}
}
else if (element instanceof ModuleOutputPackagingElement) {
else if (element instanceof ModulePackagingElement) {
final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(context.getProject());
for (VirtualFile sourceRoot : ((ModuleOutputPackagingElement)element).getSourceRoots(context)) {
for (VirtualFile sourceRoot : ((ModulePackagingElement)element).getSourceRoots(context)) {
final VirtualFile sourceFile = sourceRoot.findFileByRelativePath(path);
if (sourceFile != null && compilerConfiguration.isResourceFile(sourceFile)) {
result.add(sourceFile);
@@ -0,0 +1,91 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.packaging.impl.elements;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.elements.CompositePackagingElement;
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.elements.PackagingElementType;
import com.intellij.packaging.ui.ArtifactEditorContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
*/
public abstract class ModuleElementTypeBase<E extends ModulePackagingElementBase> extends PackagingElementType<E> {
public ModuleElementTypeBase(String id, String presentableName) {
super(id, presentableName);
}
@Override
public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
return !getSuitableModules(context).isEmpty();
}
@NotNull
public List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
@NotNull CompositePackagingElement<?> parent) {
List<Module> suitableModules = getSuitableModules(context);
List<Module> selected = context.chooseModules(suitableModules, ProjectBundle.message("dialog.title.packaging.choose.module"));
final List<PackagingElement<?>> elements = new ArrayList<>();
final ModulePointerManager pointerManager = ModulePointerManager.getInstance(context.getProject());
for (Module module : selected) {
elements.add(createElement(context.getProject(), pointerManager.create(module)));
}
return elements;
}
protected abstract ModulePackagingElementBase createElement(@NotNull Project project, @NotNull ModulePointer pointer);
private List<Module> getSuitableModules(ArtifactEditorContext context) {
ModulesProvider modulesProvider = context.getModulesProvider();
ArrayList<Module> modules = new ArrayList<>();
for (Module module : modulesProvider.getModules()) {
if (isSuitableModule(modulesProvider, module)) {
modules.add(module);
}
}
return modules;
}
public abstract boolean isSuitableModule(@NotNull ModulesProvider modulesProvider, @NotNull Module module);
/**
* Provides element presentation text.
* @param moduleName name of the module for which this presentation is requested.
* @return text to display.
*/
@NotNull
public abstract String getElementText(@NotNull String moduleName);
public Icon getElementIcon(@Nullable Module module) {
return module != null ? ModuleType.get(module).getIcon() : AllIcons.Modules.Output;
}
}
@@ -1,75 +1,17 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.packaging.impl.elements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.elements.CompositePackagingElement;
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.elements.PackagingElementType;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.openapi.compiler.CompilerBundle;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
*/
public abstract class ModuleOutputElementTypeBase<E extends ModuleOutputPackagingElementBase> extends PackagingElementType<E> {
public abstract class ModuleOutputElementTypeBase<E extends ModulePackagingElementBase> extends ModuleElementTypeBase<E> {
public ModuleOutputElementTypeBase(String id, String presentableName) {
super(id, presentableName);
}
@Override
public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
return !getSuitableModules(context).isEmpty();
}
@NotNull
public List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
@NotNull CompositePackagingElement<?> parent) {
List<Module> suitableModules = getSuitableModules(context);
List<Module> selected = context.chooseModules(suitableModules, ProjectBundle.message("dialog.title.packaging.choose.module"));
final List<PackagingElement<?>> elements = new ArrayList<>();
final ModulePointerManager pointerManager = ModulePointerManager.getInstance(context.getProject());
for (Module module : selected) {
elements.add(createElement(context.getProject(), pointerManager.create(module)));
}
return elements;
@Override
public String getElementText(@NotNull String moduleName) {
return CompilerBundle.message("node.text.0.compile.output", moduleName);
}
protected abstract ModuleOutputPackagingElementBase createElement(@NotNull Project project, @NotNull ModulePointer pointer);
private List<Module> getSuitableModules(ArtifactEditorContext context) {
ModulesProvider modulesProvider = context.getModulesProvider();
ArrayList<Module> modules = new ArrayList<>();
for (Module module : modulesProvider.getModules()) {
if (isSuitableModule(modulesProvider, module)) {
modules.add(module);
}
}
return modules;
}
public abstract boolean isSuitableModule(ModulesProvider modulesProvider, Module module);
}
@@ -1,38 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.packaging.impl.elements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* @author nik
*/
public interface ModuleOutputPackagingElement {
@Nullable
String getModuleName();
@Nullable
Module findModule(PackagingElementResolvingContext context);
@NotNull
Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context);
public interface ModuleOutputPackagingElement extends ModulePackagingElement{
}
@@ -3,119 +3,47 @@ package com.intellij.packaging.impl.elements;
import com.intellij.compiler.ant.BuildProperties;
import com.intellij.compiler.ant.Generator;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.packaging.elements.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
/**
* @author nik
*/
public abstract class ModuleOutputPackagingElementBase extends PackagingElement<ModuleOutputPackagingElementBase.ModuleOutputPackagingElementState> implements ModuleOutputPackagingElement {
@NonNls public static final String MODULE_NAME_ATTRIBUTE = "name";
protected ModulePointer myModulePointer;
protected final Project myProject;
public ModuleOutputPackagingElementBase(PackagingElementType type, Project project, ModulePointer modulePointer) {
super(type);
myProject = project;
myModulePointer = modulePointer;
public abstract class ModuleOutputPackagingElementBase extends ModulePackagingElementBase implements ModuleOutputPackagingElement {
public ModuleOutputPackagingElementBase(PackagingElementType type,
Project project,
ModulePointer modulePointer) {
super(type, project, modulePointer);
}
public ModuleOutputPackagingElementBase(PackagingElementType type, Project project) {
super(type);
myProject = project;
}
@Nullable
protected abstract String getDirectoryAntProperty(ArtifactAntGenerationContext generationContext);
@NotNull
@Override
public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext,
@NotNull AntCopyInstructionCreator creator,
@NotNull ArtifactAntGenerationContext generationContext,
@NotNull ArtifactType artifactType) {
if (myModulePointer != null) {
final String moduleOutput = BuildProperties.propertyRef(getModuleOutputAntProperty(generationContext));
String property = getDirectoryAntProperty(generationContext);
if (myModulePointer != null && property != null) {
final String moduleOutput = BuildProperties.propertyRef(property);
return Collections.singletonList(creator.createDirectoryContentCopyInstruction(moduleOutput));
}
return Collections.emptyList();
}
protected abstract String getModuleOutputAntProperty(ArtifactAntGenerationContext generationContext);
@Nullable
protected abstract VirtualFile getModuleOutputPath(CompilerModuleExtension extension);
@NotNull
@Override
public PackagingElementOutputKind getFilesKind(PackagingElementResolvingContext context) {
return PackagingElementOutputKind.DIRECTORIES_WITH_CLASSES;
}
@Override
public boolean isEqualTo(@NotNull PackagingElement<?> element) {
return element.getClass() == getClass() && myModulePointer != null
&& myModulePointer.equals(((ModuleOutputPackagingElementBase)element).myModulePointer);
}
public ModuleOutputPackagingElementState getState() {
final ModuleOutputPackagingElementState state = new ModuleOutputPackagingElementState();
if (myModulePointer != null) {
state.setModuleName(myModulePointer.getModuleName());
}
return state;
}
public void loadState(@NotNull ModuleOutputPackagingElementState state) {
final String moduleName = state.getModuleName();
myModulePointer = moduleName != null ? ModulePointerManager.getInstance(myProject).create(moduleName) : null;
}
@Override
@Nullable
public String getModuleName() {
return myModulePointer != null ? myModulePointer.getModuleName() : null;
}
@Override
@Nullable
public Module findModule(PackagingElementResolvingContext context) {
if (myModulePointer != null) {
final Module module = myModulePointer.getModule();
final ModulesProvider modulesProvider = context.getModulesProvider();
if (module != null) {
if (modulesProvider instanceof DefaultModulesProvider//optimization
|| ArrayUtil.contains(module, modulesProvider.getModules())) {
return module;
}
}
return modulesProvider.getModule(myModulePointer.getModuleName());
}
return null;
}
public static class ModuleOutputPackagingElementState {
private String myModuleName;
@Attribute(MODULE_NAME_ATTRIBUTE)
public String getModuleName() {
return myModuleName;
}
public void setModuleName(String moduleName) {
myModuleName = moduleName;
}
public ModuleOutputPackagingElementBase(PackagingElementType type, Project project) {
super(type, project);
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.packaging.impl.elements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* @author nik
*/
public interface ModulePackagingElement {
@Nullable
String getModuleName();
@Nullable
Module findModule(PackagingElementResolvingContext context);
@NotNull
Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context);
}
@@ -0,0 +1,76 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.packaging.impl.elements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
import com.intellij.packaging.elements.PackagingElementType;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public abstract class ModulePackagingElementBase extends PackagingElement<ModulePackagingElementState> implements ModulePackagingElement {
protected final Project myProject;
protected ModulePointer myModulePointer;
public ModulePackagingElementBase(PackagingElementType type, Project project, ModulePointer modulePointer) {
super(type);
myProject = project;
myModulePointer = modulePointer;
}
public ModulePackagingElementBase(PackagingElementType type, Project project) {
super(type);
myProject = project;
}
@Override
public boolean isEqualTo(@NotNull PackagingElement<?> element) {
return element.getClass() == getClass() && myModulePointer != null
&& myModulePointer.equals(((ModulePackagingElementBase)element).myModulePointer);
}
public ModulePackagingElementState getState() {
final ModulePackagingElementState state = new ModulePackagingElementState();
if (myModulePointer != null) {
state.setModuleName(myModulePointer.getModuleName());
}
return state;
}
public void loadState(@NotNull ModulePackagingElementState state) {
final String moduleName = state.getModuleName();
myModulePointer = moduleName != null ? ModulePointerManager.getInstance(myProject).create(moduleName) : null;
}
@Override
@Nullable
public String getModuleName() {
return myModulePointer != null ? myModulePointer.getModuleName() : null;
}
@Override
@Nullable
public Module findModule(PackagingElementResolvingContext context) {
if (myModulePointer != null) {
final Module module = myModulePointer.getModule();
final ModulesProvider modulesProvider = context.getModulesProvider();
if (module != null) {
if (modulesProvider instanceof DefaultModulesProvider//optimization
|| ArrayUtil.contains(module, modulesProvider.getModules())) {
return module;
}
}
return modulesProvider.getModule(myModulePointer.getModuleName());
}
return null;
}
}
@@ -0,0 +1,20 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.packaging.impl.elements;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NonNls;
public class ModulePackagingElementState {
@NonNls public static final String MODULE_NAME_ATTRIBUTE = "name";
private String myModuleName;
@Attribute(MODULE_NAME_ATTRIBUTE)
public String getModuleName() {
return myModuleName;
}
public void setModuleName(String moduleName) {
myModuleName = moduleName;
}
}
@@ -58,7 +58,10 @@ public class PackagingElementFactoryImpl extends PackagingElementFactory {
public static final PackagingElementType<ArtifactRootElement<?>> ARTIFACT_ROOT_ELEMENT_TYPE = new ArtifactRootElementType();
private static final PackagingElementType[] STANDARD_TYPES = {
DIRECTORY_ELEMENT_TYPE, ARCHIVE_ELEMENT_TYPE,
LibraryElementType.LIBRARY_ELEMENT_TYPE, ProductionModuleOutputElementType.ELEMENT_TYPE, TestModuleOutputElementType.ELEMENT_TYPE,
LibraryElementType.LIBRARY_ELEMENT_TYPE,
ProductionModuleOutputElementType.ELEMENT_TYPE,
TestModuleOutputElementType.ELEMENT_TYPE,
ProductionModuleSourceElementType.ELEMENT_TYPE,
ArtifactElementType.ARTIFACT_ELEMENT_TYPE, FILE_COPY_ELEMENT_TYPE, DIRECTORY_COPY_ELEMENT_TYPE, EXTRACTED_DIRECTORY_ELEMENT_TYPE
};
@@ -191,6 +194,13 @@ public class PackagingElementFactoryImpl extends PackagingElementFactory {
return new ProductionModuleOutputPackagingElement(module.getProject(), modulePointer);
}
@NotNull
@Override
public PackagingElement<?> createModuleSource(@NotNull Module module) {
final ModulePointer modulePointer = ModulePointerManager.getInstance(module.getProject()).create(module);
return new ProductionModuleSourcePackagingElement(module.getProject(), modulePointer);
}
@NotNull
@Override
public PackagingElement<?> createTestModuleOutput(@NotNull Module module) {
@@ -31,7 +31,7 @@ import javax.swing.*;
public class ProductionModuleOutputElementType extends ModuleOutputElementTypeBase<ProductionModuleOutputPackagingElement> {
public static final ProductionModuleOutputElementType ELEMENT_TYPE = new ProductionModuleOutputElementType();
ProductionModuleOutputElementType() {
private ProductionModuleOutputElementType() {
super("module-output", CompilerBundle.message("element.type.name.module.output"));
}
@@ -49,8 +49,14 @@ public class ProductionModuleOutputElementType extends ModuleOutputElementTypeBa
return AllIcons.Nodes.Module;
}
@NotNull
@Override
public boolean isSuitableModule(ModulesProvider modulesProvider, Module module) {
public String getElementText(@NotNull String moduleName) {
return CompilerBundle.message("node.text.0.compile.output", moduleName);
}
@Override
public boolean isSuitableModule(@NotNull ModulesProvider modulesProvider, @NotNull Module module) {
return modulesProvider.getRootModel(module).getSourceRootUrls(false).length > 0;
}
}
@@ -18,7 +18,6 @@ package com.intellij.packaging.impl.elements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.elements.ArtifactAntGenerationContext;
@@ -51,14 +50,10 @@ public class ProductionModuleOutputPackagingElement extends ModuleOutputPackagin
return "module:" + getModuleName();
}
protected String getModuleOutputAntProperty(ArtifactAntGenerationContext generationContext) {
protected String getDirectoryAntProperty(ArtifactAntGenerationContext generationContext) {
return generationContext.getModuleOutputPath(myModulePointer.getModuleName());
}
protected VirtualFile getModuleOutputPath(CompilerModuleExtension extension) {
return extension.getCompilerOutputPath();
}
@NotNull
@Override
public Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context) {
@@ -71,6 +66,6 @@ public class ProductionModuleOutputPackagingElement extends ModuleOutputPackagin
@NotNull
public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
return new DelegatedPackagingElementPresentation(new ModuleElementPresentation(myModulePointer, context, false));
return new DelegatedPackagingElementPresentation(new ModuleElementPresentation(myModulePointer, context, ProductionModuleOutputElementType.ELEMENT_TYPE));
}
}
@@ -0,0 +1,29 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.packaging.impl.elements
import com.intellij.icons.AllIcons
import com.intellij.openapi.compiler.CompilerBundle
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModulePointer
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
import javax.swing.Icon
class ProductionModuleSourceElementType private constructor() : ModuleElementTypeBase<ProductionModuleSourcePackagingElement>(
"module-source", CompilerBundle.message("element.type.name.module.source")) {
override fun isSuitableModule(modulesProvider: ModulesProvider, module: Module): Boolean {
return modulesProvider.getRootModel(module).getSourceRootUrls(false).isNotEmpty()
}
override fun createElement(project: Project, pointer: ModulePointer) = ProductionModuleSourcePackagingElement(project, pointer)
override fun createEmpty(project: Project) = ProductionModuleSourcePackagingElement(project)
override fun getCreateElementIcon(): Icon = AllIcons.Modules.SourceFolder
override fun getElementIcon(module: Module?): Icon = AllIcons.Modules.SourceFolder
override fun getElementText(moduleName: String) = CompilerBundle.message("node.text.0.module.sources", moduleName)
companion object {
@JvmField
val ELEMENT_TYPE = ProductionModuleSourceElementType()
}
}
@@ -0,0 +1,52 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.packaging.impl.elements
import com.intellij.compiler.ant.Generator
import com.intellij.openapi.module.ModulePointer
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.packaging.artifacts.ArtifactType
import com.intellij.packaging.elements.AntCopyInstructionCreator
import com.intellij.packaging.elements.ArtifactAntGenerationContext
import com.intellij.packaging.elements.PackagingElementOutputKind
import com.intellij.packaging.elements.PackagingElementResolvingContext
import com.intellij.packaging.impl.ui.DelegatedPackagingElementPresentation
import com.intellij.packaging.impl.ui.ModuleElementPresentation
import com.intellij.packaging.ui.ArtifactEditorContext
import com.intellij.packaging.ui.PackagingElementPresentation
import org.jetbrains.annotations.NonNls
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes
class ProductionModuleSourcePackagingElement : ModulePackagingElementBase {
constructor(project: Project) : super(ProductionModuleSourceElementType.ELEMENT_TYPE, project) {}
constructor(project: Project, modulePointer: ModulePointer) : super(ProductionModuleSourceElementType.ELEMENT_TYPE,
project,
modulePointer)
override fun getSourceRoots(context: PackagingElementResolvingContext): Collection<VirtualFile> {
val module = findModule(context) ?: return emptyList()
val rootModel = context.modulesProvider.getRootModel(module)
return rootModel.getSourceRoots(JavaModuleSourceRootTypes.PRODUCTION)
}
override fun createPresentation(context: ArtifactEditorContext): PackagingElementPresentation {
return DelegatedPackagingElementPresentation(
ModuleElementPresentation(myModulePointer, context, ProductionModuleSourceElementType.ELEMENT_TYPE))
}
override fun computeAntInstructions(resolvingContext: PackagingElementResolvingContext,
creator: AntCopyInstructionCreator,
generationContext: ArtifactAntGenerationContext,
artifactType: ArtifactType): List<Generator> {
return getSourceRoots(resolvingContext).map {
creator.createDirectoryContentCopyInstruction(it.path)
}
}
override fun getFilesKind(context: PackagingElementResolvingContext) = PackagingElementOutputKind.OTHER
@NonNls
override fun toString() = "module sources:" + moduleName!!
}
@@ -15,13 +15,14 @@
*/
package com.intellij.packaging.impl.elements;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import javax.swing.*;
@@ -32,7 +33,7 @@ import javax.swing.*;
public class TestModuleOutputElementType extends ModuleOutputElementTypeBase<TestModuleOutputPackagingElement> {
public static final TestModuleOutputElementType ELEMENT_TYPE = new TestModuleOutputElementType();
public TestModuleOutputElementType() {
private TestModuleOutputElementType() {
super("module-test-output", CompilerBundle.message("element.type.name.module.test.output"));
}
@@ -48,10 +49,21 @@ public class TestModuleOutputElementType extends ModuleOutputElementTypeBase<Tes
@Override
public Icon getCreateElementIcon() {
return PlatformIcons.TEST_SOURCE_FOLDER;
return AllIcons.Modules.TestSourceFolder;
}
public boolean isSuitableModule(ModulesProvider modulesProvider, Module module) {
@Override
public Icon getElementIcon(@Nullable Module module) {
return AllIcons.Modules.TestSourceFolder;
}
@NotNull
@Override
public String getElementText(@NotNull String moduleName) {
return CompilerBundle.message("node.text.0.test.compile.output", moduleName);
}
public boolean isSuitableModule(@NotNull ModulesProvider modulesProvider, @NotNull Module module) {
return !modulesProvider.getRootModel(module).getSourceRoots(JavaModuleSourceRootTypes.TESTS).isEmpty();
}
}
@@ -18,7 +18,6 @@ package com.intellij.packaging.impl.elements;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.elements.ArtifactAntGenerationContext;
import com.intellij.packaging.elements.PackagingElementResolvingContext;
@@ -49,14 +48,10 @@ public class TestModuleOutputPackagingElement extends ModuleOutputPackagingEleme
return "module-tests:" + getModuleName();
}
protected String getModuleOutputAntProperty(ArtifactAntGenerationContext generationContext) {
protected String getDirectoryAntProperty(ArtifactAntGenerationContext generationContext) {
return generationContext.getModuleTestOutputPath(myModulePointer.getModuleName());
}
protected VirtualFile getModuleOutputPath(CompilerModuleExtension extension) {
return extension.getCompilerOutputPathForTests();
}
@NotNull
@Override
public Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context) {
@@ -68,6 +63,6 @@ public class TestModuleOutputPackagingElement extends ModuleOutputPackagingEleme
@NotNull
public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
return new DelegatedPackagingElementPresentation(new ModuleElementPresentation(myModulePointer, context, true));
return new DelegatedPackagingElementPresentation(new ModuleElementPresentation(myModulePointer, context, TestModuleOutputElementType.ELEMENT_TYPE));
}
}
@@ -16,16 +16,14 @@
package com.intellij.packaging.impl.ui;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModuleType;
import com.intellij.packaging.impl.elements.ModuleElementTypeBase;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingElementWeights;
import com.intellij.packaging.ui.TreeNodePresentation;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,12 +33,14 @@ import org.jetbrains.annotations.Nullable;
public class ModuleElementPresentation extends TreeNodePresentation {
private final ModulePointer myModulePointer;
private final ArtifactEditorContext myContext;
private final boolean myTestOutput;
private final ModuleElementTypeBase myElementType;
public ModuleElementPresentation(@Nullable ModulePointer modulePointer, @NotNull ArtifactEditorContext context, final boolean testOutput) {
public ModuleElementPresentation(@Nullable ModulePointer modulePointer,
@NotNull ArtifactEditorContext context,
@NotNull ModuleElementTypeBase elementType) {
myModulePointer = modulePointer;
myContext = context;
myTestOutput = testOutput;
myElementType = elementType;
}
public String getPresentableName() {
@@ -65,14 +65,12 @@ public class ModuleElementPresentation extends TreeNodePresentation {
}
}
public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
public void render(@NotNull PresentationData presentationData,
SimpleTextAttributes mainAttributes,
SimpleTextAttributes commentAttributes) {
final Module module = findModule();
if (myTestOutput) {
presentationData.setIcon(PlatformIcons.TEST_SOURCE_FOLDER);
}
else if (module != null) {
presentationData.setIcon(ModuleType.get(module).getIcon());
}
presentationData.setIcon(myElementType.getElementIcon(module));
String moduleName;
if (module != null) {
ModifiableModuleModel moduleModel = myContext.getModifiableModuleModel();
@@ -90,8 +88,7 @@ public class ModuleElementPresentation extends TreeNodePresentation {
moduleName = "<unknown>";
}
String text = myTestOutput ? CompilerBundle.message("node.text.0.test.compile.output", moduleName)
: CompilerBundle.message("node.text.0.compile.output", moduleName);
String text = myElementType.getElementText(moduleName);
presentationData.addText(text, module != null ? mainAttributes : SimpleTextAttributes.ERROR_ATTRIBUTES);
}
@@ -30,6 +30,7 @@ import java.util.ResourceBundle;
*/
public class CompilerBundle {
@NotNull
public static String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, @NotNull Object... params) {
return CommonBundle.message(getBundle(), key, params);
}
@@ -54,6 +54,9 @@ public abstract class PackagingElementFactory {
@NotNull
public abstract PackagingElement<?> createModuleOutput(@NotNull Module module);
@NotNull
public abstract PackagingElement<?> createModuleSource(@NotNull Module module);
@NotNull
public abstract PackagingElement<?> createTestModuleOutput(@NotNull Module module);
@@ -15,13 +15,16 @@
*/
package com.intellij.packaging.elements;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class PackagingElementOutputKind {
public static final PackagingElementOutputKind DIRECTORIES_WITH_CLASSES = new PackagingElementOutputKind(true, false);
public static final PackagingElementOutputKind JAR_FILES = new PackagingElementOutputKind(false, true);
public static final PackagingElementOutputKind OTHER = new PackagingElementOutputKind(false, false);
@NotNull public static final PackagingElementOutputKind DIRECTORIES_WITH_CLASSES = new PackagingElementOutputKind(true, false);
@NotNull public static final PackagingElementOutputKind JAR_FILES = new PackagingElementOutputKind(false, true);
@NotNull public static final PackagingElementOutputKind OTHER = new PackagingElementOutputKind(false, false);
private final boolean myContainsDirectoriesWithClasses;
private final boolean myContainsJarFiles;
@@ -24,6 +24,7 @@ public class SourceItemWeights {
public static final int MODULE_GROUP_WEIGHT = 100;
public static final int MODULE_WEIGHT = 50;
public static final int MODULE_OUTPUT_WEIGHT = 30;
public static final int MODULE_SOURCE_WEIGHT = 25;
public static final int LIBRARY_WEIGHT = 10;
private SourceItemWeights() {
@@ -71,6 +71,11 @@ public class TestPackagingElementBuilder {
return this;
}
public TestPackagingElementBuilder moduleSource(Module module) {
myElement.addOrFindChild(getFactory().createModuleSource(module));
return this;
}
public TestPackagingElementBuilder lib(Library library) {
myElement.addOrFindChildren(getFactory().createLibraryElements(library));
return this;
@@ -69,10 +69,11 @@ public class UpdateArtifactsAfterRenameTest extends PackagingElementsTestCase {
Module res = moduleManager.newModule(getProjectBasePath() + "/myModule.iml", StdModuleTypes.JAVA.getId());
return res;
});
final Artifact artifact = addArtifact(root().module(module));
final Artifact artifact = addArtifact(root().module(module).moduleSource(module));
assertLayout(artifact, "<root>\n" +
" module:myModule");
" module:myModule\n" +
" module sources:myModule");
WriteAction.runAndWait(() -> {
final ModifiableModuleModel model = moduleManager.getModifiableModel();
model.renameModule(module, "newName");
@@ -80,12 +81,14 @@ public class UpdateArtifactsAfterRenameTest extends PackagingElementsTestCase {
});
assertLayout(artifact, "<root>\n" +
" module:newName");
" module:newName\n" +
" module sources:newName");
moduleManager.disposeModule(module);
assertLayout(artifact, "<root>\n" +
" module:newName");
" module:newName\n" +
" module sources:newName");
}
private void moveFile(final VirtualFile file, final VirtualFile newParent) {
@@ -2,6 +2,7 @@ package com.intellij.compiler.artifacts.ui;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.elements.ProductionModuleOutputElementType;
import com.intellij.packaging.impl.elements.ProductionModuleSourceElementType;
/**
* @author nik
@@ -26,6 +27,16 @@ public class AddNewElementActionTest extends ArtifactEditorTestCase {
" module:mod");
}
public void testAddSourcesToDirectory() {
addModule();
createEditor(addArtifact(root().dir("dir")));
selectNode("dir");
myArtifactEditor.addNewPackagingElement(ProductionModuleSourceElementType.ELEMENT_TYPE);
assertLayout("<root>\n" +
" dir/\n" +
" module sources:mod");
}
public void testAddToDirectoryInIncludedArtifact() {
addModule();
Artifact included = addArtifact("included", root().dir("dir"));
@@ -32,7 +32,7 @@ import com.intellij.packaging.impl.artifacts.PackagingElementProcessor;
import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
import com.intellij.packaging.impl.elements.FacetBasedPackagingElement;
import com.intellij.packaging.impl.elements.LibraryPackagingElement;
import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement;
import com.intellij.packaging.impl.elements.ModulePackagingElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -102,8 +102,8 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement {
public static ProjectStructureElement getProjectStructureElementFor(PackagingElement<?> packagingElement,
final StructureConfigurableContext context,
final ArtifactsStructureConfigurableContext artifactsStructureContext) {
if (packagingElement instanceof ModuleOutputPackagingElement) {
final Module module = ((ModuleOutputPackagingElement)packagingElement).findModule(artifactsStructureContext);
if (packagingElement instanceof ModulePackagingElement) {
final Module module = ((ModulePackagingElement)packagingElement).findModule(artifactsStructureContext);
if (module != null) {
return new ModuleProjectStructureElement(context, module);
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.elements.PackagingElementOutputKind;
import com.intellij.packaging.impl.elements.ProductionModuleOutputElementType;
import com.intellij.packaging.impl.elements.ProductionModuleOutputPackagingElement;
import com.intellij.packaging.impl.ui.ModuleElementPresentation;
import com.intellij.packaging.ui.*;
@@ -54,7 +55,7 @@ public class ModuleOutputSourceItem extends PackagingSourceItem {
@Override
public SourceItemPresentation createPresentation(@NotNull ArtifactEditorContext context) {
final ModulePointer modulePointer = ModulePointerManager.getInstance(context.getProject()).create(myModule);
return new DelegatedSourceItemPresentation(new ModuleElementPresentation(modulePointer, context, false)) {
return new DelegatedSourceItemPresentation(new ModuleElementPresentation(modulePointer, context, ProductionModuleOutputElementType.ELEMENT_TYPE)) {
@Override
public int getWeight() {
return SourceItemWeights.MODULE_OUTPUT_WEIGHT;
@@ -23,8 +23,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
import com.intellij.packaging.impl.elements.PackagingElementFactoryImpl;
import com.intellij.packaging.impl.elements.ProductionModuleOutputElementType;
import com.intellij.packaging.impl.elements.*;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.packaging.ui.PackagingSourceItem;
import com.intellij.packaging.ui.PackagingSourceItemsProvider;
@@ -49,17 +48,22 @@ public class ModulesAndLibrariesSourceItemsProvider extends PackagingSourceItems
return createModuleItems(editorContext, ((ModuleGroupItem)parent).getPath());
}
else if (parent instanceof ModuleSourceItemGroup) {
return createClasspathItems(editorContext, artifact, ((ModuleSourceItemGroup)parent).getModule());
return createAvailableItems(editorContext, artifact, ((ModuleSourceItemGroup)parent).getModule());
}
return Collections.emptyList();
}
@NotNull
private static Collection<? extends PackagingSourceItem> createClasspathItems(@NotNull ArtifactEditorContext editorContext,
private static Collection<? extends PackagingSourceItem> createAvailableItems(@NotNull ArtifactEditorContext editorContext,
@NotNull Artifact artifact, @NotNull Module module) {
final List<PackagingSourceItem> items = new ArrayList<>();
final ModuleRootModel rootModel = editorContext.getModulesProvider().getRootModel(module);
for (Module toAdd : getAvailableModules(editorContext, artifact, ProductionModuleOutputElementType.ELEMENT_TYPE, module)) {
items.add(new ModuleOutputSourceItem(toAdd));
}
List<Library> libraries = new ArrayList<>();
final ModuleRootModel rootModel = editorContext.getModulesProvider().getRootModel(module);
for (OrderEntry orderEntry : rootModel.getOrderEntries()) {
if (orderEntry instanceof LibraryOrderEntry) {
final LibraryOrderEntry libraryEntry = (LibraryOrderEntry)orderEntry;
@@ -71,10 +75,6 @@ public class ModulesAndLibrariesSourceItemsProvider extends PackagingSourceItems
}
}
for (Module toAdd : getNotAddedModules(editorContext, artifact, module)) {
items.add(new ModuleOutputSourceItem(toAdd));
}
for (Library library : getNotAddedLibraries(editorContext, artifact, libraries)) {
items.add(new LibrarySourceItem(library));
}
@@ -102,11 +102,19 @@ public class ModulesAndLibrariesSourceItemsProvider extends PackagingSourceItems
}
@NotNull
private static List<? extends Module> getNotAddedModules(@NotNull final ArtifactEditorContext context, @NotNull Artifact artifact,
final Module... allModules) {
final Set<Module> modules = new HashSet<>(Arrays.asList(allModules));
ArtifactUtil.processPackagingElements(artifact, ProductionModuleOutputElementType.ELEMENT_TYPE, moduleOutputPackagingElement -> {
modules.remove(moduleOutputPackagingElement.findModule(context));
private static <E extends ModulePackagingElementBase> List<? extends Module> getAvailableModules(@NotNull final ArtifactEditorContext context,
@NotNull Artifact artifact,
@NotNull ModuleElementTypeBase<E> elementType,
final Module... allModules) {
final Set<Module> modules = new HashSet<>();
for (Module module : allModules) {
if (elementType.isSuitableModule(context.getModulesProvider(), module)) {
modules.add(module);
}
}
ArtifactUtil.processPackagingElements(artifact, elementType, moduleElement -> {
modules.remove(moduleElement.findModule(context));
return true;
}, context, true);
return new ArrayList<>(modules);
@@ -29,9 +29,10 @@ import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructions
import org.jetbrains.jps.incremental.artifacts.instructions.CopyToDirectoryInstructionCreator;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.elements.*;
import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement;
import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement;
import org.jetbrains.jps.model.java.*;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot;
import org.jetbrains.jps.service.JpsServiceManager;
import org.jetbrains.jps.util.JpsPathUtil;
@@ -62,6 +63,7 @@ public class LayoutElementBuildersRegistry {
LayoutElementBuilderService<?>[] standardBuilders = {
new RootElementBuilder(), new DirectoryElementBuilder(), new ArchiveElementBuilder(), new DirectoryCopyElementBuilder(),
new FileCopyElementBuilder(), new ExtractedDirectoryElementBuilder(), new ModuleOutputElementBuilder(),
new ModuleSourceElementBuilder(),
new ModuleTestOutputElementBuilder(), new ComplexElementBuilder(), new ArtifactOutputElementBuilder()
};
for (LayoutElementBuilderService<?> builder : standardBuilders) {
@@ -124,6 +126,24 @@ public class LayoutElementBuildersRegistry {
}
}
private static void generateModuleSourceInstructions(@NotNull List<JpsModuleSourceRoot> roots,
@NotNull ArtifactCompilerInstructionCreator creator,
@NotNull JpsPackagingElement contextElement) {
for (JpsModuleSourceRoot root : roots) {
File source = root.getFile();
ArtifactCompilerInstructionCreator target;
JavaSourceRootProperties javaProperties = root.getProperties(JavaModuleSourceRootTypes.SOURCES);
if (javaProperties != null) {
String prefix = javaProperties.getPackagePrefix().replace('.', '/');
target = creator.subFolderByRelativePath(prefix);
} else {
target = creator;
}
target.addDirectoryCopyInstructions(source, null, target.getInstructionsBuilder().createCopyingHandler(source, contextElement, target));
}
}
private static void generateModuleOutputInstructions(@Nullable String outputUrl,
@NotNull ArtifactCompilerInstructionCreator creator,
@NotNull JpsPackagingElement contextElement) {
@@ -262,6 +282,28 @@ public class LayoutElementBuildersRegistry {
}
}
private static class ModuleSourceElementBuilder extends LayoutElementBuilderService<JpsProductionModuleSourcePackagingElement> {
public ModuleSourceElementBuilder() {
super(JpsProductionModuleSourcePackagingElement.class);
}
@Override
public void generateInstructions(JpsProductionModuleSourcePackagingElement element,
ArtifactCompilerInstructionCreator instructionCreator,
ArtifactInstructionsBuilderContext builderContext) {
JpsModule module = element.getModuleReference().resolve();
if (module != null) {
generateModuleSourceInstructions(module.getSourceRoots(), instructionCreator, element);
}
}
@Override
public Collection<? extends BuildTarget<?>> getDependencies(@NotNull JpsProductionModuleSourcePackagingElement element,
TargetOutputIndex outputIndex) {
return Collections.emptyList();
}
}
private static class ModuleTestOutputElementBuilder extends LayoutElementBuilderService<JpsTestModuleOutputPackagingElement> {
public ModuleTestOutputElementBuilder() {
super(JpsTestModuleOutputPackagingElement.class);
@@ -20,6 +20,7 @@ import com.intellij.util.PathUtil
import com.intellij.util.io.directoryContent
import org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.archive
import org.jetbrains.jps.incremental.artifacts.LayoutElementTestUtil.root
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.util.JpsPathUtil
import java.io.BufferedOutputStream
@@ -171,6 +172,49 @@ class ArtifactBuilderTest : ArtifactBuilderTestCase() {
assertOutput(artifact, directoryContent { file("A.class") })
}
fun testModuleSources() {
val file = createFile("src/A.java", "class A{}")
val m = addModule("m", PathUtil.getParentPath(file))
val a = addArtifact(root().moduleSource(m))
buildAll()
assertOutput(a, directoryContent {
file("A.java")
})
val b = createFile("src/B.java", "class B{}")
buildAll()
assertOutput(a, directoryContent {
file("A.java")
file("B.java")
})
delete(b)
buildAll()
assertOutput(a, directoryContent {
file("A.java")
})
}
fun testModuleSourcesWithPackagePrefix() {
val file = createFile("src/A.java", "class A{}")
val m = addModule("m", PathUtil.getParentPath(file))
val sourceRoot = assertOneElement(m.sourceRoots)
val typed = sourceRoot.asTyped(JavaSourceRootType.SOURCE)
assertNotNull(typed)
typed!!.properties.packagePrefix = "org.foo"
val a = addArtifact(root().moduleSource(m))
buildAll()
assertOutput(a, directoryContent {
dir("org") {
dir("foo") {
file("A.java")
}
}
})
}
fun testCopyResourcesFromModuleOutput() {
val file = createFile("src/a.xml", "")
JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(myProject).addResourcePattern("*.xml")
@@ -82,6 +82,10 @@ public class LayoutElementTestUtil {
return element(JpsJavaExtensionService.getInstance().createProductionModuleOutput(module.createReference()));
}
public LayoutElementCreator moduleSource(JpsModule module) {
return element(JpsJavaExtensionService.getInstance().createProductionModuleSource(module.createReference()));
}
public LayoutElementCreator element(JpsPackagingElement element) {
myElement.addChild(element);
return this;
@@ -41,6 +41,9 @@ public abstract class JpsJavaExtensionService {
@NotNull
public abstract JpsProductionModuleOutputPackagingElement createProductionModuleOutput(@NotNull JpsModuleReference moduleReference);
@NotNull
public abstract JpsProductionModuleSourcePackagingElement createProductionModuleSource(@NotNull JpsModuleReference moduleReference);
@NotNull
public abstract JpsTestModuleOutputPackagingElement createTestModuleOutput(@NotNull JpsModuleReference moduleReference);
@@ -0,0 +1,11 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.jps.model.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
import org.jetbrains.jps.model.module.JpsModuleReference;
public interface JpsProductionModuleSourcePackagingElement extends JpsPackagingElement {
@NotNull
JpsModuleReference getModuleReference();
}
@@ -206,6 +206,12 @@ public class JpsJavaExtensionServiceImpl extends JpsJavaExtensionService {
return new JpsProductionModuleOutputPackagingElementImpl(moduleReference);
}
@Override
@NotNull
public JpsProductionModuleSourcePackagingElement createProductionModuleSource(@NotNull JpsModuleReference moduleReference) {
return new JpsProductionModuleSourcePackagingElementImpl(moduleReference);
}
@Override
@NotNull
public JpsTestModuleOutputPackagingElement createTestModuleOutput(@NotNull JpsModuleReference moduleReference) {
@@ -0,0 +1,37 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.jps.model.java.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsElementChildRole;
import org.jetbrains.jps.model.ex.JpsCompositeElementBase;
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase;
import org.jetbrains.jps.model.java.JpsProductionModuleSourcePackagingElement;
import org.jetbrains.jps.model.module.JpsModuleReference;
public class JpsProductionModuleSourcePackagingElementImpl extends JpsCompositeElementBase<JpsProductionModuleSourcePackagingElementImpl>
implements JpsProductionModuleSourcePackagingElement {
private static final JpsElementChildRole<JpsModuleReference>
MODULE_REFERENCE_CHILD_ROLE = JpsElementChildRoleBase.create("module reference");
public JpsProductionModuleSourcePackagingElementImpl(JpsModuleReference moduleReference) {
myContainer.setChild(MODULE_REFERENCE_CHILD_ROLE, moduleReference);
}
@Override
@NotNull
public JpsModuleReference getModuleReference() {
return myContainer.getChild(MODULE_REFERENCE_CHILD_ROLE);
}
private JpsProductionModuleSourcePackagingElementImpl(JpsProductionModuleSourcePackagingElementImpl original) {
super(original);
}
@NotNull
@Override
public JpsProductionModuleSourcePackagingElementImpl createCopy() {
return new JpsProductionModuleSourcePackagingElementImpl(this);
}
}
@@ -163,7 +163,9 @@ public class JpsJavaModelSerializerExtension extends JpsModelSerializerExtension
@NotNull
@Override
public List<? extends JpsPackagingElementSerializer<?>> getPackagingElementSerializers() {
return Arrays.asList(new JpsModuleOutputPackagingElementSerializer(), new JpsTestModuleOutputPackagingElementSerializer());
return Arrays.asList(new JpsModuleOutputPackagingElementSerializer(),
new JpsTestModuleOutputPackagingElementSerializer(),
new JpsModuleSourcePackagingElementSerializer());
}
@NotNull
@@ -281,6 +283,24 @@ public class JpsJavaModelSerializerExtension extends JpsModelSerializerExtension
}
}
private static class JpsModuleSourcePackagingElementSerializer
extends JpsPackagingElementSerializer<JpsProductionModuleSourcePackagingElement> {
private JpsModuleSourcePackagingElementSerializer() {
super("module-source", JpsProductionModuleSourcePackagingElement.class);
}
@Override
public JpsProductionModuleSourcePackagingElement load(Element element) {
JpsModuleReference reference = JpsElementFactory.getInstance().createModuleReference(element.getAttributeValue("name"));
return getService().createProductionModuleSource(reference);
}
@Override
public void save(JpsProductionModuleSourcePackagingElement element, Element tag) {
tag.setAttribute("name", element.getModuleReference().getModuleName());
}
}
private static class JpsTestModuleOutputPackagingElementSerializer extends JpsPackagingElementSerializer<JpsTestModuleOutputPackagingElement> {
private JpsTestModuleOutputPackagingElementSerializer() {
super("module-test-output", JpsTestModuleOutputPackagingElement.class);
@@ -121,6 +121,8 @@ element.type.name.library.files=Library Files
node.text.0.compile.output=''{0}'' compile output
node.text.0.test.compile.output=''{0}'' test compile output
node.text.0.with.dependencies=''{0}'' with dependencies
node.text.0.module.sources=''{0}'' sources
element.type.name.module.source=Module Sources
element.type.name.module.output=Module Output
element.type.name.module.test.output=Module Test Output
element.type.name.directory=Directory