-
-
Notifications
You must be signed in to change notification settings - Fork 352
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
Conversation
3269ae8
to
ebfbba9
Compare
fe0689c
to
3f3c20c
Compare
rebase? |
3f3c20c
to
10aca7c
Compare
10aca7c
to
2eaef6c
Compare
I have added some more tests to increase coverage of the new implementation of SubstitutionVisitor. |
Revapi Analysis resultsOld 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
Change 2
|
There was a problem hiding this 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(); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
@monperrus Thanks for ideas and your time to review this bigger PR. |
Revapi Analysis resultsOld 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
Change 2
|
OK to merge. |
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 constructorSubstitutionVisitor(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:
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.