SyntaxRewriter and multiple statements - roslyn

I've encountered a tricky situation using the SyntaxRewriter in Roslyn. I'd like to rewrite certain kinds of statements, including local variable declarations. The solution requires me to transform the statements in question into multiple statements, as in the following trivial example:
void method()
{
int i;
}
becomes
void method()
{
int i;
Console.WriteLine("I declared a variable.");
}
I've seen other examples where blocks are used to accomplish something similar, but of course in the case of a variable declaration, the scope of the declaration will be affected. I came up with the following solution, but I'm balking at it. It seems over-complicated, and requires a break in the visitor pattern:
class Rewriter: SyntaxRewriter
{
public override SyntaxList<TNode> VisitList<TNode>(SyntaxList<TNode> list)
{
if (typeof(TNode) == typeof(StatementSyntax))
return Syntax.List<TNode>(list.SelectMany(st => RewriteStatementInList(st as StatementSyntax).Cast<TNode>()));
else
return base.VisitList<TNode>(list);
}
private IEnumerable<SyntaxNode> RewriteStatementInList(StatementSyntax node)
{
if (node is LocalDeclarationStatementSyntax)
return PerformRewrite((LocalDeclarationStatementSyntax)node);
//else if other cases (non-visitor)
return Visit(node).AsSingleEnumerableOf();
}
private IEnumerable<SyntaxNode> PerformRewrite(LocalDeclarationStatementSyntax orig)
{
yield return orig;
yield return Syntax.ParseStatement("Console.WriteLine(\"I declared a variable.\");");
}
}
What am I missing? Editing statements and removing them (via empty statement) seem more straight forward than rewriting to multiples.
My take on the answer:
class Rewriter : SyntaxRewriter
{
readonly ListVisitor _visitor = new ListVisitor();
public override SyntaxList<TNode> VisitList<TNode>(SyntaxList<TNode> list)
{
var result = Syntax.List(list.SelectMany(_visitor.Visit).Cast<TNode>());
return base.VisitList(result);
}
private class ListVisitor : SyntaxVisitor<IEnumerable<SyntaxNode>>
{
protected override IEnumerable<SyntaxNode> DefaultVisit(SyntaxNode node)
{
yield return node;
}
protected override IEnumerable<SyntaxNode> VisitLocalDeclarationStatement(
LocalDeclarationStatementSyntax node)
{
yield return node;
yield return Syntax.ParseStatement("Console.WriteLine(\"I declared a variable.\");");
}
}
}

I think there is a simple way to make your Rewriter more visitor-like: use another visitor to process the nodes in the list:
class Rewriter: SyntaxRewriter
{
readonly Visitor m_visitor = new Visitor();
public override SyntaxList<TNode> VisitList<TNode>(SyntaxList<TNode> list)
{
var result = Syntax.List(list.SelectMany(m_visitor.Visit).Cast<TNode>());
return base.VisitList(result);
}
}
class Visitor : SyntaxVisitor<IEnumerable<SyntaxNode>>
{
protected override IEnumerable<SyntaxNode> DefaultVisit(SyntaxNode node)
{
return new[] { node };
}
protected override IEnumerable<SyntaxNode> VisitLocalDeclarationStatement(
LocalDeclarationStatementSyntax node)
{
return new SyntaxNode[]
{
node,
Syntax.ParseStatement(
"Console.WriteLine(\"I declared a variable.\");")
};
}
}
Note that this is not safe and will throw an InvalidCastException if you return a collection that contains object that is not TNode from the Visitor.

I don't know of a radically better way to handle this. One other approach that is slightly more "visitor like" is to use VisitLocalDeclaration to annotate nodes that you want to replace with something like: return (base.Visit(node).WithAdditionalAnnoations(myAnnotation);. Then in VisitList, you can just find the child nodes that your annotation and do the rewrite at that point.

I was browsing through the Roslyn source code to see how the Roslyn team themselves do this. Here's an example: http://source.roslyn.codeplex.com/Microsoft.CodeAnalysis.CSharp.Features/R/bcd389b836bf7b4c.html
In a nutshell, I think it looks more or less like this. (this rewriter happens to just delete StatementExpressions, but you can see it's built out of an iterator method, so it's easy to add methods too).
class TreeRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitBlock(BlockSyntax node)
=> node.WithStatements(VisitList(SyntaxFactory.List(ReplaceStatements(node.Statements))));
public override SyntaxNode VisitSwitchSection(SwitchSectionSyntax node)
=> node.WithStatements(VisitList(SyntaxFactory.List(ReplaceStatements(node.Statements))));
IEnumerable<StatementSyntax> ReplaceStatements(IEnumerable<StatementSyntax> statements)
{
foreach (var statement in statements)
{
if (statement is ExpressionStatementSyntax) continue;
yield return statement;
}
}
}
Here's how I drive that code:
var rewriter = new TreeRewriter();
var syntaxTree = await document.GetSyntaxTreeAsync();
var root = await syntaxTree.GetRootAsync();
var newRoot = rewriter.Visit(root);
var newDocument = document.WithSyntaxRoot(newRoot);

Related

Declare one object to be of multiple classes, depending on a condition

This question is based on Create objects in conditional c++ statements.
However, in my case I need to declare one object from a choice of multiple classes which will then be passed as argument to a function. Hence, the object has to be declared with a pre-defined name (obj in this case).
Class1 obj;
Class2 obj;
if (...) {
obj = Class1(); }
if (...) {
obj = Class1(a, b); }
else
obj = Class2();
// Do something on declared object
DoSomething(obj.variable_);
Currently the above will not work because of conflicting declaration of obj. How should I go about doing this?
You might not need std::variant, if your object doesn't have to be "polymorphic" at run-time. Refactor your code to:
if (...) {
DoSomething(Class1());
if (...) {
DoSomething(Class1(a, b));
else
DoSomething(Class2());
And make DoSomething a template or overload set:
void DoSomething(const Class1&) { }
void DoSomething(const Class2&) { }
You can use std::variant.
std::variant<Class1, Class2> var;
if (...) {
var = Class1(); }
if (...) {
var = Class1(a, b); }
else
var = Class2();
std::visit([](auto&& obj) { DoSomething(obj.variable_); }, var);
The variant can hold one of the alternatives at a time, which is what you need. And std::visit will let you apply code generically to either alternative, so long as the generic lambda can be applied to it.
Solution using simple polymorphism,
ClassBase () {
}
Class1 : ClassBase (){
}
Class2 : ClassBase (){
}
Then you can use like,
ClassBase obj;
if (...) {
obj = Class1(); }
if (...) {
obj = Class1(a, b); }
else
obj = Class2();
// Do something on declared object
DoSomething(obj.variable_);
The OP said: "Class1 and Class2 can inherit from a common base class. I can provide overload of DoSomething"
Inheritance is OK. But only if it is in a form of "subtyping". Let's assume everyone is aware of that. Canonical example.
In this case OP's question and code is actually internals of a factory method. One solution might be:
Interface::ptr make ( Interface::subtype which)
{
if ( which == Interface::subtype::one )
return std::make_unique<Class1>();
return std::make_unique<Class2>();
}
And the usage is simple:
Interface::ptr one = make( Interface::subtype::one ) ;
Interface::ptr two = make( Interface::subtype::two ) ;
one->do_something() ;
two->do_something() ;
Jut one variant of the common concept. Working code is here.
Option with no polymorphism required
Is allways a good option. We do not need inheritance. We just need intances that do understand the message do_something().
// no inheritance required
template<typename T>
void do_something( T the_t_ ) { the_t_.do_something(); }
Ditto
if ( ... ) {
do_something(Class1{}) ;
}
else if ( ... ) {
do_something(Class1(a,b)) ;
} else {
do_something(Class2());
}
In that case Class1 and Class2 do not need a common base type.
ps: Vittorio's solution is very good. It can be also applied when Class1 and Class2 are completely unrelated.
An interesting variant of that variant could be:
if (...) {
Class1();
if (...) {
Class1(a, b);
else
Class2();
No function overloads DoSomething() but type instances that "do something". Might be the most feasible design but only for some app's.

Assign local method variable to class pointer

I'm changing some code to deal with a change in the signature of some functions which are being called by it. The original code looks something like (this is only illustrative):
int main()
{
TestClassA instance;
instance.MethodA();
instance.MethodB();
// do other stuff with instance
}
class TestClassA
{
void MethodA ()
{
UList* aList = NULL;
getListOfStuff(aList);
// do some stuff
fList = aList;
}
void MethodB ()
{
//do something with fList
}
UList* fList;
}
struct Ulist
{
int value;
std::vector<Ulist> components;
}
getListOfStuff(UList* aList)
{
aList = new UList();
PopulateOriginal(aList);
}
The signature of getListOfStuff has now changed (the change is beyond my control) to:
getListOfStuff(UList& aList)
{
aList=PopulateNewVersion();
}
Seems I wasn't clear about what I was asking, so to clarify...what I am asking is how to call the new version of the method getListOfStuff and safely store the returned data from it (the aList parameter) in a raw pointer field fList, which can then be accessed from MethodB later on.
Following on from #GuillaumeGris answer below, would the following work? (The bit I'm unsure about is whether the assignment within the new getListOfStuff affects whether fList is still pointing to valid data after MethodA has exited.)
void MethodA ()
{
UList* aList = new UList();
getListOfStuff(*aList);
// do some stuff
fList = aList;
}
You don't need an explicit heap allocation (new).
class TestClassA
{
void MethodA ()
{
// Clear components
fList.components.clear();
getListOfStuff(fList);
}
UList fList;
}
If fList is optional, I would recommend the use of a std::unique_ptr
class TestClassA
{
void MethodA ()
{
if (!fList)
fList = std::make_unique<Ulist>();
else
{
// Clear components
fList->components.clear();
}
getListOfStuff(*fList);
}
std::unique_ptr<UList> fList;
}

How to mock a static method call on an object in a static method?

I 'm a newie in Junit-testing but I have to test some code. I think now I know the basics of it, but I still got a problem on which I couldn't find anything on the Internet:
Here's the class I want to test:
public static void methodToTest(Label l2, Label l3, User u) {
int first = MyDB.someMethod(u.anotherMethod()).size();
int second = MyDB.someOtherMethod(u).size();
if (first == 1) {
l2.setCaption("...");
}
...
}
I don't want the System to create the Integers 'first' and 'second'. Instead I just want them to be '1' so I can test if the last lines of code work properly.
MyDB is a public class with static Methods (someMethod() and someOtherMethod())
I want to test the Method methodToTest. I tried to call this method with parms and at the end compare the modified params to the expected ones.
I use Mockito and PowerMockito.
This is one of my tries:
#PrepareForTest({ClassToTest.class, MyDB.class })
#RunWith(PowerMockRunner.class)
public class Test extends PowerMockTestCase{
PowerMockito.mockStatic(MyDB.class);
PowerMockito.doReturn(1).when(MyDB.someMethod(u.anotherMethod()).size());
PowerMockito.doReturn(1).when(MyDB.someOtherMethod(u).size());
ClassToTest.methodToTest(l1, l2, u);
assertTrue(l1.equals(l3) && l2.equals(l4));
}
The exception that I get is:
'Argument passed to when() is not a mock!'
I hope anyone can help me. I passed so many hours to solve this problem, without success.
Thank you!!!
As I mentioned in my comment, you have found that the static methods are an impediment to testing. So, I would suggest that you avoid static methods. Let's see what that might look like in your example:
You have some code you need to test..
public class ProductionClass {
public static void methodToTest(Label l2, Label l3, User u) {
int first = MyDB.someMethod(u.anotherMethod()).size();
int second = MyDB.someOtherMethod(u).size();
if (first == 1) {
l2.setCaption("...");
}
...
}
}
First things first..make the static method of the production class an instance method:
public class ProductionClass {
public void methodToTest(Label l2, Label l3, User u) { // removed "static"
int first = MyDB.someMethod(u.anotherMethod()).size();
int second = MyDB.someOtherMethod(u).size();
if (first == 1) {
l2.setCaption("...");
}
...
}
}
Ok, so you still have coupling to static methods on MyDB. Getting rid of that one static method just made your production class a lot more testable. Here's how..you can do a couple of extract method refactorings like this:
public class ProductionClass {
public void methodToTest(Label l2, Label l3, User u) {
int first = getFirst();
int second = getSecond();
if (first == 1) {
l2.setCaption("...");
}
...
}
int getFirst() {
return MyDB.someMethod(u.anotherMethod()).size();
}
int getSecond() {
return MyDB.someOtherMethod(u).size();
}
}
Now you can easily subclass that production class and override (or partial mock, if you prefer) the methods that you want to futz with..
public class TestableProductionClass extends ProductionClass {
#Override
int getFirst() {
return 1;
}
#Override
int getSecond() {
return 1;
}
}
Wouldn't make it any harder than it needs to be and introducing PowerMock tends to add complexity that I'd rather not deal with. YMMV. Good luck!

C++: Applying the Composite pattern

I am trying to apply the Composite pattern, so I need to create a Leaf class and a Composite class, both inheriting from the same Component class. In order for any of my Components to perform their duty they need to ask help from a single Helper object. We have the following
struct Helper {
void provide_help();
};
struct Component {
Component(Helper* helper)
: m_helper(helper) {
}
virtual void operation() = 0;
// the call_for_help function will be used by subclasses of Component to implement Component::operation()
void call_for_help() {
m_helper->provide_help();
}
private:
Helper* m_helper;
};
And here are two different Leaf subclasses:
struct Leaf1
: Component {
Leaf1(Helper* helper)
: Component(helper) {
}
void operation() override {
call_for_help();
operation1();
}
void operation1();
};
struct Leaf2
: Component {
Leaf2(Helper* helper)
: Component(helper) {
}
void operation() override {
call_for_help();
operation2();
}
void operation2();
};
So far, so good. Now the Composite class is giving me grief. The typical implementation is as follows
struct Composite
: Component {
Composite(Helper* helper)
: Component(helper) {
}
void operation() override {
for (auto el : m_children) el->operation();
}
private:
std::vector<Component*> m_children;
};
which by going through the m_children one by one and calling operation on each essentially calls the helper function multiple times, even though one call is enough for all children. Ideally, if the m_children consisted, say, of a Leaf1 and a Leaf2, I would like somehow the Composite operation to call the helper function only once and then call in succession Leaf1::operation1() and then Leaf2::operation2(). Is there any way to achieve what I need? Alternative designs are welcome. I hope my question makes sense. Thanks in advance!
You want a polymorphic operation but you are adding more responability to the method (calling the helper). It's better to separate these two things.
struct Component {
void call_operation(){
call_for_help();
operation();
}
virtual void operation() = 0;
void call_for_help();
};
Remove the call_for_help() from leaf::operation() (making operation1, operation2 redundant, polymorphism) and the rest should work fine.
You can even hide operation() from your public interface, you'll need friendship with your Composite in that case.
As it could happen at any level, one approach could be to handle this at the level of the helper.
A sketch of the approach would be:
class Helper {
bool composite_help = false;
bool help_provided;
public:
void provide_help() {
if ((composite_help && !help_provided) || !composite_help) {
//TO DO: provide help
help_provided = true;
}
}
void start_composite_help() {
composite_help = true;
help_provided = false;
}
void end_composite_help() {
composite_help = false;
}
};
The principle is that the call for help performed by individual components works as before. But when the composite calls for help, you take preacutions to make sure that the call is performed only once:
void operation() override {
m_helper->start_composite_help();
for (auto el : m_children) el->operation();
m_helper->start_composite_help();
}
As said, this is only a sketch: the code provided as such will not work as soon as you have several levels of composites. So this needs to be improved:
instead of a bool composite_help you'd need a counter, which gets incremented when entering a composite operation and decremented when you exit it. In this case, the counter would go back to 0 (re-enabling help) only when the last level of composte has finished its job.
may be the helper performs different operations to provide help. So you could also imagine to have a "transaction id" that uniquely identifies a group of related operations, and you manage the counter not for the helper overall, in a map of active transactions.
finally, the start/end is not so nice. A RAII helper to the helper could make the whole setup more robust (for example when an exception breaks the normal execution flow.)
I think this problem would be better solved with a combination of Composite and Mediator.
Heads up! I'll show you a different version of the mediator pattern, which is not the same as the canonical version.
It's not of the business of your composite structure to know if a helper was called or not. You'd better do this using some kind of event handler.
Since you have only one helper, you could try like this:
class Helper {
public:
void callHelper() { std::cout << "Helper called" << std::endl; }
};
class Mediator {
private:
std::map<std::string, std::vector<Helper>> subscribers;
int updateLimit = -1;
int currentUpdateCount = 0;
void resetUpdateCount() {
currentUpdateCount = 0;
}
public:
Mediator(){}
void subscribe(std::string evt, Helper helper) {
subscribers[evt].push_back(helper);
}
void update(std::string evt) {
for (auto& h: subscribers[evt]) {
h.callHelper();
}
}
void setUpdateLimit(int i) {
updateLimit = i;
resetUpdateCount();
}
void removeUpdateLimit() {
updateLimit = -1;
resetUpdateCount();
}
int getUpdateLimit() {
return updateLimit;
}
void updateLimited(std::string evt) {
if (updateLimit < 0 || currentUpdateCount < updateLimit) {
update(evt);
currentUpdateCount++;
}
}
};
int main(int argc, const char *argv[])
{
Mediator m;
Helper h1, h2;
m.subscribe("bar", h1);
m.setUpdateLimit(1);
// Will be called only once
m.updateLimited("bar");
m.updateLimited("bar");
m.updateLimited("bar");
m.removeUpdateLimit();
return 0;
}
Using it:
Mediator m;
Helper h1, h2;
m.subscribe("bar", h1);
m.setUpdateLimit(1);
// Will be called only once
m.updateLimited("bar");
m.updateLimited("bar");
m.updateLimited("bar");
m.removeUpdateLimit();
So, here is what you do to integrate this to you composite structure. Remove the helper from you nodes, add the Mediator to the base class:
struct Component {
Component(Mediator& mediator)
: m_helper(mediator) {
}
virtual void operation() = 0;
// the call_for_help function will be used by subclasses of Component to implement Component::operation()
void notify() {
m_mediator->updateFiltered(Component::updateEventName);
}
static std::string updateEventName;
private:
Mediator& m_mediator;
};
std::string Component::updateEventName = "update.composite";
struct Leaf1
: Component {
Leaf1(Helper* helper)
: Component(helper) {
}
void operation() override {
notify();
operation1();
}
void operation1();
};
Using it:
Mediator m;
Helper h;
Composite c(m);
Leaf1 l1(m), l2(m);
c.add(l1);
c.add(l2);
m.subscribe(Component::updateEventName, h);
m.setUpdateLimit(1);
// Will be called only once, even if it has childrens
c.update();
m.removeUpdateLimit();
IMPORTANT: This solution is suboptimal, it has some issues, like you having to pass a mediator instance to every node constructor, but it's just a raw idea for you to work on.
Hope it helps!

User defined attributes and compile time evaluation for setting class member variables

I'm trying to learn a little more about D's compile time evaluation and understand how its templates, mixins, attributes, etc all work. One thing I'd like to try and do is figure out an elegant way to mark a class's members as being serializable or loadable from a database. In the example below, I've created a tuple that lists which members to use when reading or (later on) serializing the instance.
My first question is, is this a proper usage of tuples as it stands below? And secondly, if so, is there a way to generate this tuple automatically at compile time using the user defined attributes I've assigned to the relevant member variables? I've dug through the various documentation pages like http://dlang.org/attribute.html and http://dlang.org/phobos/std_traits.html but I can't seem to figure out how to use them properly for this purpose (i.e. looping through a class's members and determining which variables have the desired attribute). I'm also not quite certain if I have completely the wrong idea about how attributes are supposed to be used. Any suggestions on the best way to go about this would be appreciated.
enum ENCODABLE = 1;
alias string[string] Row;
template Tuple (T...) { alias T Tuple; }
class A {
#(ENCODABLE) string name;
#(ENCODABLE) int x;
int* p;
alias Tuple!("name","x") encodables;
this(Row row) {
foreach (var; encodables) {
__traits(getMember, this, var) = to!(typeof(__traits(getMember, this, var)))(row[var]);
}
}
}
void main() {
Row row = ["name":"Asdf", "x":"120"]; // Simulated database row
auto a = new A(row);
writefln("%s,%d,%d", a.name, a.x, a.p); // Asdf,120,null
}
This isn't much of an answer, but I used them by defining my own helper templates, and using structs as UDAs (with their values indicating parameters). The helper templates are here:
https://github.com/CyberShadow/ae/blob/master/utils/meta.d#L133
They're used here, to allow overriding the JSON field for a JSON serializer/unserializer:
https://github.com/CyberShadow/ae/blob/master/utils/json.d#L505
I've managed to get it working with the following code, and a little help from the isValueInTuple template based on code provided in CyberShadow's answer. It still feels a bit clunky, but seems to get the job done. Comments/criticism welcome if I'm doing something horrible against the nature of templates!
enum {
ENCODABLE = "ENCODABLE",
};
alias string[string] Row;
template Tuple(T...) { alias T Tuple; }
template isValueInTuple(string s, T...) {
static if (T.length == 0) {
enum bool isValueInTuple = false;
} else static if (T.length == 1) {
static if (is(typeof(T[0]) == typeof(s))) {
enum bool isValueInTuple = T[0] == s;
} else {
enum bool isValueInTuple = false;
}
} else {
enum bool isValueInTuple = isValueInTuple!(s, T[0]) || isValueInTuple!(s, T[1..$]);
}
}
template GenEncodables(U) {
string GenEncodables() {
string ret = "alias Tuple!(";
int fn = 0;
foreach (index, field; __traits(allMembers, U)) {
static if (field != "Monitor") { // better way to avoid compilation errors here?
static if (isAssignable!(typeof(mixin(U.stringof~"."~field)))) {
static if (isValueInTuple!(ENCODABLE, __traits(getAttributes, mixin(U.stringof~"."~field)))) {
if (fn++)
ret ~= ",";
ret ~= `"`~field~`"`;
}
}
}
}
ret ~= ") encodables;";
return ret;
}
}
mixin template Encodables() {
mixin(GenEncodables!(typeof(this)));
}
class A {
#ENCODABLE string name;
#ENCODABLE int x;
int *p;
this() {}
mixin Encodables; // must come after this() definition, apparently!
this(Row row) {
foreach (var; encodables) {
pragma(msg, "Reading parameter "~var~" from row");
__traits(getMember, this, var) = to!(typeof(__traits(getMember, this, var)))(row[var]);
}
}
}