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

review: refactor SubstitutionVisitor #1359

Merged
merged 16 commits into from
Jun 19, 2017

Conversation

pvojtechovsky
Copy link
Collaborator

@pvojtechovsky pvojtechovsky commented Jun 4, 2017

Here is refactored SubstitutionVisitor. There are following changes:

C1) The SubstitutionVisitor can be used on any Spoon model and Map<String, Object> parameters. It does not need Template, TemplateParameter, Parameter. Of course they may be still used if it makes sense for client. See new constructor SubstitutionVisitor(Factory f, Map<String, Object> templateParameters)

C2) The SubstitutionVisitor can substitute the root node of substitution model by zero, one or more nodes.
See new method <E extends CtElement> List<E> SubstitutionVisitor#substitute(E element)

C3) There is possible to directly generate new Class, Interface, Enum, ... thanks to (C1). See
CtType<T> Substitution#insertType(CtPackage targetPackage, String typeName, CtType<T> templateOfType, Map<String, Object> templateParameters)

C4) The SubstitutionVisitor use Context, which knows current substitution parameters. It is needed to correctly substitute all parameters of blocks generated by SubstitutionVisitor#visitCtForEach

C5) The SubstitutionVisitor has less scanning methods now. It does all substitutions here:

  • scanCtElement - substitutes comments, which are on all elements
  • scanCtNamedElement - substitutes names or part's of names. Or replaces whole nodes by zero, one or more other nodes. For example legacy CtExecutable one parameter replacement by many parameters, is implemented this more generic way. Now we can replace everything this way. For example: one Annotation by many annotations; one field by many fields; one enum value many enum values, ...
  • scanCtReference - substitutes all kinds of references. See code for each case
  • visitCtForEach - like before
  • visitCtFieldRead, visitCtFieldWrite - like before
  • visitCtInvocation - like before

C6) the package protected fields of SubstitutionVisitor were made private - may be it was public intentional? Then I will rollback this change

C7) the conversion of parameter values to required types were extracted to private methods and made more reliable. Missuses throws exception, and if conversion is possible then parameter value is automatically converted to required type. See SubstitutionVisitor#getParameterValueAsXxx methods.

@pvojtechovsky pvojtechovsky force-pushed the simplifySubstVisitor branch 2 times, most recently from 3269ae8 to ebfbba9 Compare June 8, 2017 20:40
@pvojtechovsky pvojtechovsky changed the title WiP: remove useless code from SubstitutionVisitor WiP: refactor SubstitutionVisitor Jun 8, 2017
@pvojtechovsky pvojtechovsky force-pushed the simplifySubstVisitor branch 3 times, most recently from fe0689c to 3f3c20c Compare June 11, 2017 20:27
@pvojtechovsky pvojtechovsky changed the title WiP: refactor SubstitutionVisitor review2: refactor SubstitutionVisitor Jun 11, 2017
@monperrus
Copy link
Collaborator

rebase?

@monperrus monperrus changed the title review2: refactor SubstitutionVisitor WIP: refactor SubstitutionVisitor Jun 12, 2017
@pvojtechovsky pvojtechovsky force-pushed the simplifySubstVisitor branch from 3f3c20c to 10aca7c Compare June 12, 2017 08:09
@pvojtechovsky pvojtechovsky force-pushed the simplifySubstVisitor branch from 10aca7c to 2eaef6c Compare June 12, 2017 20:33
@pvojtechovsky
Copy link
Collaborator Author

I have added some more tests to increase coverage of the new implementation of SubstitutionVisitor.
This PR is ready for review. I know that it is not baby step, but it is hard to split it, because it depends on each other ...

@INRIA INRIA deleted a comment from spoon-bot Jun 13, 2017
@INRIA INRIA deleted a comment from spoon-bot Jun 13, 2017
@INRIA INRIA deleted a comment from spoon-bot Jun 13, 2017
@surli surli changed the title WIP: refactor SubstitutionVisitor review: refactor SubstitutionVisitor Jun 13, 2017
@spoon-bot
Copy link
Collaborator

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.8.0-20170612.224545-39

New API: fr.inria.gforge.spoon:spoon-core:jar:5.8.0-SNAPSHOT

Detected changes: 2.

Change 1

Name Element
Old class spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner
New class spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner
Code java.class.visibilityReduced
Description Visibility was reduced from 'public' to 'private'.
Breaking binary: breaking,

Change 2

Name Element
Old method void spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner::(spoon.support.template.SubstitutionVisitor)
New method void spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner::()
Code java.method.visibilityReduced
Description visibility reduced
Breaking binary: breaking,

@INRIA INRIA deleted a comment from spoon-bot Jun 15, 2017
@INRIA INRIA deleted a comment from spoon-bot Jun 15, 2017
@INRIA INRIA deleted a comment from spoon-bot Jun 15, 2017
Copy link
Collaborator

@monperrus monperrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very nice, thanks. See my comments.

spoon.buildModel();
Factory factory = spoon.getFactory();

CtBlock<?> model = factory.Class().get(InvocationSubstitutionByStatementTemplate.class).getMethod("sample").getBody();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

model confusing here what about templateArg

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

@Test
public void testArrayLengthAccess() throws Exception {
//contract: the template engine replaces length of collection of parameter values by number
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK


@Test
public void testInvocationSubstitutionByExpression() throws Exception {
//contract: the template engine supports substitution of any method invocation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//contract: the template engine supports substitution of method arguments

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is misunderstanding. The origin contract is correct.

System.out.println(_expression_().substring(1));

is substituted by

System.out.println("abc".substring(1));

so not the method arguments, but any method invocation can be substituted.


@Test
public void testStatementTemplateRootSubstitution() throws Exception {
//contract: the template engine supports substitution of root element
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure to understand. there is no "root" in this test

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SubstituteRootTemplate extends StatementTemplate, which internally calls

CtStatement result = c.getMethod("statement").getBody().getStatements().get(0).clone();

where result is block.S(); ... so it is substitution of the root element in the spoon model represented by result.


@Test
public void testInsertType() throws Exception {
final Launcher launcher = new Launcher();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename the method createTypeFromTemplate

contract: the Substituion API provides a method createTypeFromTemplate

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Substitution.insertType was renamed to createTypeFromTemplate


//contract: we can generate interface
final CtType<?> aIfaceModel = launcher.getFactory().Interface().get(AnIfaceModel.class);
CtType<?> genIface = Substitution.insertType(targetPackage, "GenIface", aIfaceModel, parameters);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about only passing a String qualifiedName to simplify the API usage?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old insertType renamed to createTypeFromTemplate has now only String qualifiedName instead of CtPackage and simpleName.

@pvojtechovsky
Copy link
Collaborator Author

@monperrus Thanks for ideas and your time to review this bigger PR.
What next?

@spoon-bot
Copy link
Collaborator

Revapi Analysis results

Old API: fr.inria.gforge.spoon:spoon-core:jar:5.8.0-20170614.224555-42

New API: fr.inria.gforge.spoon:spoon-core:jar:5.8.0-SNAPSHOT

Detected changes: 2.

Change 1

Name Element
Old class spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner
New class spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner
Code java.class.visibilityReduced
Description Visibility was reduced from 'public' to 'private'.
Breaking binary: breaking,

Change 2

Name Element
Old method void spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner::(spoon.support.template.SubstitutionVisitor)
New method void spoon.support.template.SubstitutionVisitor.InheritanceSustitutionScanner::()
Code java.method.visibilityReduced
Description visibility reduced
Breaking binary: breaking,

@monperrus
Copy link
Collaborator

OK to merge.

@surli surli merged commit 293d8e8 into INRIA:master Jun 19, 2017
@pvojtechovsky pvojtechovsky deleted the simplifySubstVisitor branch June 20, 2017 15:18
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 this pull request may close these issues.

4 participants