Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template class gets added to the import as well as its source code gets added to the output source folder #2987

Closed
yaadyaad opened this issue May 24, 2019 · 7 comments · Fixed by #3580

Comments

@yaadyaad
Copy link

Dear All,

I have two projects and therefore two source code folders

  • gen - where the spoon-related code resides
  • myapp - where the sources of a main application lives and where the generated code is being added

When generating a new class with some class template that extends ExtensionTemplate, lets say BaseLogicTemplate, an UNUSED import statement import spoon.template.ExtensionTemplate; gets added to the generated class.

I have another template, CustomLogicTemplate that extends BaseLogicTemplate, and when generating a class with this CustomLogicTemplate, another an UNUSED import statement import spoon.template.BaseLogicTemplate; gets added to the generated class.

In addition, source code of both templates BaseLogicTemplate and CustomLogicTemplate are copied from gen project source code to myapp source code.

Here is how a Launcher gets created:

    Launcher launcher = new Launcher();
    launcher.addInputResource(mainProjectFolder + "/src/main/java");
    launcher.addTemplateResource(new FileSystemFolder("./src/main/java/gen/core/templates"));
    launcher.setSourceOutputDirectory(mainProjectFolder + "/src/main/java");
    launcher.getEnvironment().setAutoImports(true);
    launcher.getEnvironment().setCommentEnabled(true);

The code is generated with launcher.prettyprint() method.

Expected behaviour:

  • No UNUSED import statement gets added to the generated class.
  • Source code of templates should not be copied to the sourceOutputDirectory.

Can you please point me out where and how I can fix it?

I use the following version of Spoon in my gradle build file:
compile 'fr.inria.gforge.spoon:spoon-core:7.4.0'

Thank you,
Dmitry

@monperrus
Copy link
Collaborator

Thanks for your report/ Imports have been reworked. Bug still present in 8.1.0?

@xsebek
Copy link
Contributor

xsebek commented Aug 30, 2020

I think this is still an issue in 8.2.01, but perhaps I am just using it wrong, @monperrus ?

To reproduce a small example could look like this:

src/main
├── java
│   └── example
│       ├── Launch.java
│       ├── StProcessor.java
│       └── StTemplate.java
└── resources
    └── Example.java
Launch.java
package example;

import spoon.*;
import spoon.support.compiler.FileSystemFile;
import spoon.support.sniper.SniperJavaPrettyPrinter;

public class Launch {
    public static void main(String[] args) {
        Launcher launcher = new Launcher();
        launcher.getEnvironment().setPrettyPrinterCreator(() ->
                new SniperJavaPrettyPrinter(launcher.getEnvironment())
        );

        launcher.addInputResource("./resources/Example.java");
        launcher.addProcessor(new StProcessor());
        launcher.addTemplateResource(new FileSystemFile("./java/example/StTemplate.java"));
        launcher.run();
    }
}
StProcessor.java
package example;

import spoon.processing.AbstractProcessor;
import spoon.reflect.code.CtAssert;

public class StProcessor extends AbstractProcessor<CtAssert> {
    public void process(CtAssert element) {
        var t = new StTemplate();
        t._asserted_ = element.getAssertExpression();
        var ifAssert = t.apply(null);
        element.replace(ifAssert);
    }
}
StTemplate.java
package example;

import spoon.reflect.code.CtExpression;
import spoon.template.Parameter;
import spoon.template.StatementTemplate;


public class StTemplate extends StatementTemplate {
    @Parameter
    public CtExpression<Boolean> _asserted_;

    public void statement() throws Throwable {
        if (_asserted_.S()) {
            assert true;
        } else {
            assert false;
        }
    }
}
Example.java
class Example {
    public void main() {
        assert 6 * 7 == 42;
    }
}

The quite unexpected result is this:

src/main/spooned
├── Example.java
└── example
    └── StTemplate.java
Example.java
class Example {
    public void main() {
		{
			{
				assert true;
			}
		}
    }
}
StTemplate.java
package example;

import spoon.reflect.code.CtExpression;
import spoon.template.Parameter;
import spoon.template.StatementTemplate;


public class StTemplate extends StatementTemplate {
    @Parameter
    public CtExpression<Boolean> _asserted_;

    public void statement() throws Throwable {
        if (_asserted_.S()) {
			{
				assert true;
			}
        } else {
			{
				assert false;
			}
        }
    }
}

The result I expected/hoped for is single spooned directory example with file Example.java like this:

class Example {
    public void main() {
        if (6 * 7 == 42;) {
            assert true;
        } else {
            assert false;
        }
    }
}

Thanks a lot for your work on 🥄 and I would be very grateful if you could help me understand the usage here 🙂
(Or is it a bug? 🐛 )


1: 8.2.0 (#3501) does not mention templates, unlike 8.1.0 (#3310)

@monperrus
Copy link
Collaborator

Hello! It seems you put the full directory as input resource. What happens if you put only Example.java?

@xsebek
Copy link
Contributor

xsebek commented Aug 31, 2020

I did, with the addInputResource("./resources/Example.java");. The result is the same with only "./resources", however.
If you meant the template, then that is already FileSystemFile("./java/example/StTemplate.java").

EDIT: You are welcome to have a look through the files above. 😉

EDIT2: This would be the logs with added print when the parent CtType is the template:

Click to expand the logs
2020-08-31 11:55:28,847 INFO spoon.Launcher - Running in NOCLASSPATH mode (doc: http://spoon.gforge.inria.fr/launcher.html).
2020-08-31 11:55:29,217 INFO spoon.Launcher - Spoon version 8.2.0
2020-08-31 11:55:29,218 INFO spoon.Launcher - running Spoon...
2020-08-31 11:55:29,218 INFO spoon.Launcher - start processing...
2020-08-31 11:55:29,219 DEBUG spoon.Launcher - building sources: [$EXAMPLE/src/main/resources/Example.java]
2020-08-31 11:55:29,497 DEBUG spoon.Launcher - build args: [-encoding, UTF-8, -1.8, -preserveAllLocals, -noExit, -enableJavadoc, $EXAMPLE/src/main/resources/Example.java]
2020-08-31 11:55:30,702 DEBUG spoon.Launcher - built in 1483 ms
2020-08-31 11:55:30,703 DEBUG spoon.Launcher - building templates: [$EXAMPLE/src/main/java/example/StTemplate.java]
2020-08-31 11:55:30,704 DEBUG spoon.Launcher - template build args: [-encoding, UTF-8, -1.8, -preserveAllLocals, -noExit, -enableJavadoc, $EXAMPLE/src/main/java/example/StTemplate.java]
2020-08-31 11:55:31,024 DEBUG spoon.Launcher - built in 321 ms
2020-08-31 11:55:31,047 DEBUG spoon.Launcher - model built in 1829
2020-08-31 11:55:31,048 DEBUG spoon.Launcher - Loaded processor example.StProcessor@7d446ed1.
2020-08-31 11:55:31,048 INFO spoon.Launcher - example.StProcessor
-- DO NOT REPLACE THE TEMPLATE --
-- DO NOT REPLACE THE TEMPLATE --
2020-08-31 11:55:35,037 DEBUG spoon.Launcher - model processed in 3990 ms
2020-08-31 11:55:35,038 DEBUG spoon.Launcher - Generating source using compilation units...
2020-08-31 11:55:35,038 DEBUG spoon.Launcher - Generating source files to: $EXAMPLE/src/main/spooned
2020-08-31 11:55:35,078 DEBUG spoon.Launcher - pretty-printed in 41 ms
2020-08-31 11:55:35,078 DEBUG spoon.Launcher - program spooning done in 5860 ms
2020-08-31 11:55:35,078 INFO spoon.Launcher - end of processing: 
2020-08-31 11:55:35,078 INFO spoon.Launcher - no errors, no warnings

@monperrus
Copy link
Collaborator

If you only have addInputResource("./resources/Example.java"), with no other call in addInputResource, the template code is written to the output?

If yes, that's clearly a bug.

@xsebek
Copy link
Contributor

xsebek commented Sep 1, 2020

Yes, as in the example Launch.java above, adding InputResource, Processor and TemplateResource and then run() modifies the template before using it as well as adding it to the output.

Is there any way I could help with this, @monperrus ?

@monperrus
Copy link
Collaborator

monperrus commented Sep 2, 2020 via email

xsebek added a commit to xsebek/spoon that referenced this issue Sep 9, 2020
- add template to change `assert p` to `if (p) assert true; else assert false;`
- add simple class with one assert and its desired transformation
- add test method to check Launcher.run output with the template
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants