Skip to content

Commit

Permalink
fix(JDTBasedSpoonCompiler): fix annotation bug when templates are used (
Browse files Browse the repository at this point in the history
closes #921)
  • Loading branch information
pvojtechovsky authored and monperrus committed Nov 7, 2016
1 parent cd3d1f1 commit 3b88ba8
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 95 deletions.
17 changes: 14 additions & 3 deletions src/main/java/spoon/SpoonModelBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.visitor.Filter;
import spoon.support.compiler.jdt.FactoryCompilerConfig;
import spoon.support.compiler.jdt.FileCompilerConfig;
import spoon.support.compiler.jdt.JDTBatchCompiler;

import java.io.File;
import java.util.Collection;
Expand Down Expand Up @@ -76,9 +79,17 @@ public interface SpoonModelBuilder {
*/
boolean build(JDTBuilder builder);

/** The types of compilable elements */
enum InputType {
FILES, CTTYPES
/** The types of compilable elements
* FILES - compiles the java files from the file system, which were registered by {@see SpoonModelBuilder#addInputSource()} and {@see SpoonModelBuilder#addTemplateSource(File)}
* CTTYPES - compiles virtual java files, which are dynamically generated from the all top level classes of the CtModel by {@see DefaultJavaPrettyPrinter}
*/
interface InputType {
InputType FILES = FileCompilerConfig.INSTANCE;
InputType CTTYPES = FactoryCompilerConfig.INSTANCE;
/**
* responsible for setting the parameters of JDTBatchCompiler, must call setCompilationUnits()
*/
void initializeCompiler(JDTBatchCompiler compiler);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,29 @@

import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;

import spoon.SpoonModelBuilder;
import spoon.reflect.declaration.CtType;

class FactoryCompiler extends JDTBatchCompiler {
public class FactoryCompilerConfig implements SpoonModelBuilder.InputType {

FactoryCompiler(JDTBasedSpoonCompiler jdtCompiler) {
super(jdtCompiler);
}
public static final SpoonModelBuilder.InputType INSTANCE = new FactoryCompilerConfig();

//avoid direct instantiation. But somebody can inherit
protected FactoryCompilerConfig() {
};

/**
* returns the compilation units corresponding to the types in the factory.
*/
@Override
public CompilationUnit[] getCompilationUnits() {
// gets the one that are in factory (when compiling the model to bytecode )
List<CompilationUnit> unitList = new ArrayList();
public void initializeCompiler(JDTBatchCompiler compiler) {
JDTBasedSpoonCompiler jdtCompiler = compiler.getJdtCompiler();
List<CompilationUnit> unitList = new ArrayList<>();
for (CtType<?> ctType : jdtCompiler.getFactory().Type().getAll()) {
if (ctType.isTopLevel()) {
unitList.add(new CompilationUnitWrapper(ctType));
}
}
return unitList.toArray(new CompilationUnit[unitList.size()]);
compiler.setCompilationUnits(unitList.toArray(new CompilationUnit[unitList.size()]));
}

}
62 changes: 0 additions & 62 deletions src/main/java/spoon/support/compiler/jdt/FileCompiler.java

This file was deleted.

83 changes: 83 additions & 0 deletions src/main/java/spoon/support/compiler/jdt/FileCompilerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright (C) 2006-2016 INRIA and contributors
* Spoon - http://spoon.gforge.inria.fr/
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.support.compiler.jdt;

import java.util.ArrayList;
import java.util.List;

import spoon.SpoonException;
import spoon.SpoonModelBuilder;
import spoon.compiler.SpoonFile;
import spoon.compiler.SpoonFolder;

import org.apache.commons.io.IOUtils;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;

public class FileCompilerConfig implements SpoonModelBuilder.InputType {

/**
* Default implementation of which initializes {@link JDTBatchCompiler} by all sources and templates registered in {@link SpoonModelBuilder}
*/
public static final SpoonModelBuilder.InputType INSTANCE = new FileCompilerConfig((List<SpoonFile>) null) {
@Override
public List<SpoonFile> getFiles(JDTBatchCompiler compiler) {
JDTBasedSpoonCompiler jdtCompiler = compiler.getJdtCompiler();
List<SpoonFile> files = new ArrayList<>();
files.addAll(jdtCompiler.sources.getAllJavaFiles());
files.addAll(jdtCompiler.templates.getAllJavaFiles());
return files;
}
};

private final List<SpoonFile> files;

public FileCompilerConfig(List<SpoonFile> files) {
this.files = files;
}

public FileCompilerConfig(SpoonFolder folder) {
this(folder.getAllJavaFiles());
}

@Override
public void initializeCompiler(JDTBatchCompiler compiler) {
JDTBasedSpoonCompiler jdtCompiler = compiler.getJdtCompiler();
List<CompilationUnit> culist = new ArrayList<>();
for (SpoonFile f : getFiles(compiler)) {
if (compiler.filesToBeIgnored.contains(f.getPath())) {
continue;
}
try {
String fName = "";
if (f.isActualFile()) {
fName = f.getPath();
} else {
fName = f.getName();
}
culist.add(new CompilationUnit(IOUtils.toCharArray(f
.getContent(), jdtCompiler.encoding), fName, null));
} catch (Exception e) {
throw new SpoonException(e);
}
}
compiler.setCompilationUnits(culist.toArray(new CompilationUnit[0]));
}

protected List<SpoonFile> getFiles(JDTBatchCompiler compiler) {
return files;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ protected boolean buildSources(JDTBuilder jdtBuilder) {
if (sources.getAllJavaFiles().isEmpty()) {
return true;
}
JDTBatchCompiler batchCompiler = createBatchCompiler(InputType.FILES);
JDTBatchCompiler batchCompiler = createBatchCompiler(new FileCompilerConfig(sources));
String[] args;
if (jdtBuilder == null) {
args = new JDTBuilderImpl() //
Expand Down Expand Up @@ -376,21 +376,28 @@ protected boolean buildSources(JDTBuilder jdtBuilder) {
return probs.size() == 0;
}

protected JDTBatchCompiler createBatchCompiler() {
return new JDTBatchCompiler(this);
}

protected JDTBatchCompiler createBatchCompiler(InputType... types) {
JDTBatchCompiler batchCompiler = createBatchCompiler();
// backward compatible
if (types.length == 0 || types[0] == InputType.CTTYPES) {
return new FactoryCompiler(this);
} else {
return new FileCompiler(this);
if (types.length == 0) {
types = new InputType[]{InputType.CTTYPES};
}
for (InputType inputType : types) {
inputType.initializeCompiler(batchCompiler);
}
return batchCompiler;
}

protected boolean buildTemplates(JDTBuilder jdtBuilder) {
if (templates.getAllJavaFiles().isEmpty()) {
return true;
}

JDTBatchCompiler batchCompiler = createBatchCompiler(InputType.FILES);
JDTBatchCompiler batchCompiler = createBatchCompiler(new FileCompilerConfig(templates));

File f = null;
String[] templateClasspath = new String[0];
Expand Down
18 changes: 14 additions & 4 deletions src/main/java/spoon/support/compiler/jdt/JDTBatchCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@
*
* (we use a fully qualified name in inheritance to make it clear we are extending jdt)
*/
abstract class JDTBatchCompiler extends org.eclipse.jdt.internal.compiler.batch.Main {
public class JDTBatchCompiler extends org.eclipse.jdt.internal.compiler.batch.Main {

protected JDTBasedSpoonCompiler jdtCompiler;
protected final JDTBasedSpoonCompiler jdtCompiler;
protected CompilationUnit[] compilationUnits;

JDTBatchCompiler(JDTBasedSpoonCompiler jdtCompiler) {
// by default we don't want anything from JDT
Expand All @@ -63,9 +64,14 @@ abstract class JDTBatchCompiler extends org.eclipse.jdt.internal.compiler.batch.
}
}

/** we force this method of JDT to be re-implemented, see subclasses */
@Override
public abstract CompilationUnit[] getCompilationUnits();
public CompilationUnit[] getCompilationUnits() {
return compilationUnits;
}

public void setCompilationUnits(CompilationUnit[] compilationUnits) {
this.compilationUnits = compilationUnits;
}

@Override
public ICompilerRequestor getBatchRequestor() {
Expand Down Expand Up @@ -136,4 +142,8 @@ this.jdtCompiler.requestor, getProblemFactory(), this.out,
return result;
}

public JDTBasedSpoonCompiler getJdtCompiler() {
return jdtCompiler;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected boolean buildSources(JDTBuilder jdtBuilder) {
if (sources.getAllJavaFiles().isEmpty()) {
return true;
}
JDTBatchCompiler batchCompiler = createBatchCompiler(InputType.FILES);
JDTBatchCompiler batchCompiler = createBatchCompiler(new FileCompilerConfig(sources));

File source = createTmpJavaFile(new File("."));
String[] args;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public void testExtendedStringLiteral() throws Exception {
public SpoonCompiler createCompiler() {
return new JDTBasedSpoonCompiler(getFactory()) {
@Override
protected JDTBatchCompiler createBatchCompiler(InputType... types) {
return new FileCompiler(this) {
protected JDTBatchCompiler createBatchCompiler() {
return new JDTBatchCompiler(this) {
@Override
public CompilationUnitDeclaration[] getUnits(List<SpoonFile> files) {
startTime = System.currentTimeMillis();
Expand Down
11 changes: 3 additions & 8 deletions src/test/java/spoon/test/compilation/CompilationTest.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
package spoon.test.compilation;

import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.junit.Assert;
import org.junit.Test;
import spoon.Launcher;
import spoon.compiler.SpoonCompiler;
import spoon.reflect.code.BinaryOperatorKind;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtReturn;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.ModifierKind;
import spoon.reflect.factory.CodeFactory;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.CtScanner;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.compiler.jdt.FileCompiler;
import spoon.support.compiler.jdt.JDTBasedSpoonCompiler;
import spoon.support.reflect.reference.SpoonClassNotFoundException;
import spoon.test.compilation.testclasses.Bar;
import spoon.test.compilation.testclasses.IBar;
Expand All @@ -34,8 +29,8 @@
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

public class CompilationTest {
Expand Down Expand Up @@ -158,7 +153,7 @@ public void testNewInstance() throws Exception {
}

}

/*
@Test
public void testFilterResourcesFile() throws Exception {
// shows how to filter input java files, for https://github.com/INRIA/spoon/issues/877
Expand Down Expand Up @@ -232,7 +227,7 @@ public CompilationUnit[] getCompilationUnits() {
}
}

*/
@Test
public void testPrecompile() {
// without precompile
Expand Down
Loading

0 comments on commit 3b88ba8

Please sign in to comment.