Skip to content

Conversation

@dustin-wojciechowski
Copy link
Contributor

@dustin-wojciechowski dustin-wojciechowski commented Feb 12, 2024

This is a String Wrapper for generated text. It will handle things like newlines and indents that are currently managed manually and somewhat inconsistently (for example, an indent variable is incremented and decremented alongside the use of \t escape character)

There are still some things I wanted to do but split it into another PR:

  1. Enable option to not include {}, such as when an if-condition only has one line underneath it.
  2. Other kind of constructions such as while loops and switch-case (although a lot of these can just be constructed as code-blocks with custom header text)
  3. Actually integrating this into the generator itself.

@github-actions
Copy link
Contributor

⚠️ Your code has been reformatted. ⚠️

If this is not desired, add the actions-disable-autoformat label, and revert the reformatting commit.

If files unrelated to your change were modified, try reverting the reformatting commit + merging with the target branch (and push those changes).

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Copy link
Member

@mandel-macaque mandel-macaque left a comment

Choose a reason for hiding this comment

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

I like the idea, we should focus on working with Stream rather than strings and try to reduce the number of strings created. We want a fast efficient generator since it is ran a lot in our daily work.

@github-actions
Copy link
Contributor

⚠️ Your code has been reformatted. ⚠️

If this is not desired, add the actions-disable-autoformat label, and revert the reformatting commit.

If files unrelated to your change were modified, try reverting the reformatting commit + merging with the target branch (and push those changes).

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

CodeBlock? ElseBlock = null;
public IfBlock (string condition)
{
HeaderText = "if (" + condition + ")";
Copy link
Member

Choose a reason for hiding this comment

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

This is still an issue :)

allParameters.Append (", ");
}
}
HeaderText = methodSignature + "(" + allParameters + ")";
Copy link
Member

Choose a reason for hiding this comment

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

A lot of string concatenation in this class.

Comment on lines 50 to 52
MethodBlock methodBlock = new (methodName, methodArguments);
methodBlock.AddLine (inputText1);
methodBlock.AddLine (inputText2);
Copy link
Member

Choose a reason for hiding this comment

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

In general how test code is written doesn't matter all that much, except that for these changes the test code is an example of what kind of code we'll have to write in the generator, so the nicer test code we can write, the nicer code we can write in the generator too.

With that in mind: while using variables for text is generally a good idea, in this case it just makes the code much harder to read, because you have to go back and forth between the declaration and the usage to determine what's going on.

If something like this were possible, it would look much nicer (using a collection initializer):

var methodBlock = new MethodBlock ("public void Foobinate", "int count", "bool isFoo")
{
	"int fooCount = 1;",
	"string[] fooNames = new [] {\"foo\"};",
};

Now if you squint a little bit, it's relatively easy to see what will be generated.

Comment on lines +66 to +67
List<ICodeBlock> blocks = new List<ICodeBlock> () { new LineBlock ("int fooCount = 1;"), new LineBlock ("string[] fooNames = new [] {\"foo\"};") };
MethodBlock methodBlock = new ("public void Foobinate", blocks, "int count", "bool isFoo");
Copy link
Member

Choose a reason for hiding this comment

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

Like above, something like this would be easier to read (one reason being that the layout here is in the same order the code will be generated, you don't have to reorder chunks of text in your head to make sense of it):

MethodBlock methodBlock = new ("public void Foobinate", "int count", "bool isFoo") {
	new LineBlock ("int fooCount = 1;"),
	new LineBlock ("string [] ...;"),
};

Just to be clear: this is how I'd like to use the new API in the generator, and the idea is to change the API to make something like this possible.

"}\n";
List<ICodeBlock> blocks = new ();
blocks.Add (new LineBlock (line1));
IfBlock ifBlock = new (ifConditionText, blocks);
Copy link
Member

Choose a reason for hiding this comment

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

Same:

var ifBlock = new IfBlock ("fooCount == 5") {
	"Console.WriteLine(fooCount);",
};

Comment on lines 118 to 122
List<ICodeBlock> blocks = new ();
List<ICodeBlock> elseBlocks = new List<ICodeBlock> () { new LineBlock (line2) };
blocks.Add (new LineBlock (line1));
IfBlock ifBlock = new (ifConditionText, blocks);
ifBlock.AddElse (elseBlocks);
Copy link
Member

Choose a reason for hiding this comment

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

var ifBlock = new IfBlock ("fooCount == 5") {
	"Console.WriteLine(fooCount);"
}.AddElse (
	"Console.WriteLine(booCount);"
);

Comment on lines 148 to 154
List<ICodeBlock> blocks = new ();
List<ICodeBlock> elseIfBlocks = new List<ICodeBlock> () { new LineBlock (line2) };
List<ICodeBlock> elseBlocks = new List<ICodeBlock> () { new LineBlock (line3) };
blocks.Add (new LineBlock (line1));
IfBlock ifBlock = new (ifConditionText, blocks);
ifBlock.AddElseIf (elseIfConditionText, elseIfBlocks);
ifBlock.AddElse (elseBlocks);
Copy link
Member

Choose a reason for hiding this comment

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

var ifBlock = new IfBlock ("fooCount == 5") {
	"Console.WriteLine(fooCount);",
}.AddElseIf ("fooCount == 10",
	"Console.WriteLine(booCount);"
).AddElse (
	"Console.WriteLine(zooCount);"
);

Comment on lines 179 to 181
BlockContainer blockContainer = new ();
blockContainer.AddLine (usingText);
blockContainer.AddLine ("");
Copy link
Member

Choose a reason for hiding this comment

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

BlockContainer block = new {
	"using Network";
}

or:

BlockContainer block = new ();
block.AddUsing ("Network");

Comment on lines 183 to 189
CodeBlock namespaceBlock = new CodeBlock (namespaceText);
CodeBlock classBlock = new CodeBlock (headerText);
MethodBlock methodBlock = new MethodBlock (methodName, methodArguments);
classBlock.AddLine (variableText);
classBlock.AddBlock (methodBlock);
namespaceBlock.AddBlock (classBlock);
blockContainer.AddBlock (namespaceBlock);
Copy link
Member

Choose a reason for hiding this comment

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

var block = new CodeBlock ("public namespace FooSpace") {
	new CodeBlock ("public class FooClass") {
		"public string FooText { get; set; }",
		new MethodBlock ("public void Foobinate", "int count", "bool isFoo") { }
	}
}

Blocks.AddRange (blocks);
}

public void AddElseIf (string condition, List<ICodeBlock> blocks)
Copy link
Contributor

Choose a reason for hiding this comment

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

If you make this look like this:

public IfBlock AddElseIf (string condition, List<ICodeBlock> blocks)
{
    ElseIfBlocks.Add (new CodeBlock ($"else if ({condition})", blocks));
    return this;
}

You get two things - string interpolation reads a little better and the fluent interface lets you write:

var test = new IfBlock ("someTest", blocks)
                          .AddElse ("someOtherTest", otherBlocks)
                          .AddElse ("someOtherOtherTest", otherOtherBlocks)
                          .AddElse ("other code);

Copy link
Member

Choose a reason for hiding this comment

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

If you make the blocks a params:

public IfBlock AddElseIf (string condition, params ICodeBlock[] blocks)
{
    ElseIfBlocks.Add (new CodeBlock ($"else if ({condition})", blocks));
    return this;
}

you can do:

var test = new IfBlock ("someTest", blocks)
                          .AddElseIf ("someOtherTest", 
							new Block ("Console.WriteLine(var1);"),
							new Block ("Console.WriteLine(var2);"))
                          .AddElseIf ("someOtherOtherTest",
							new Block ("Console.WriteLine(var3);"))
                          .AddElse ("other code);

@vs-mobiletools-engineering-service2

This comment has been minimized.

@rolfbjarne
Copy link
Member

FWIW I'm not sure we should go in this direction, here runtime people recommend using either Roslyn or StringBuilder/StringWriter/etc (which we're already doing): dotnet/runtimelab#2526 (comment)

@dalexsoto dalexsoto marked this pull request as draft March 5, 2024 19:46
@dustin-wojciechowski
Copy link
Contributor Author

Pushed work I had in progress, last things needed would be to replace string concatenation in MethodBlock and clean up the Print inside of IfBlock if this were to be picked up again.

Work on this PR is suspended until further notice.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2024

⚠️ Your code has been reformatted. ⚠️

If this is not desired, add the actions-disable-autoformat label, and revert the reformatting commit.

If files unrelated to your change were modified, try reverting the reformatting commit + merging with the target branch (and push those changes).

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS X64 - Mac Sonoma (14) passed 💻

All tests on macOS X64 - Mac Sonoma (14) passed.

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

📚 [PR Build] Artifacts 📚

Packages generated

View packages

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS M1 - Mac Monterey (12) passed 💻

All tests on macOS M1 - Mac Monterey (12) passed.

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS M1 - Mac Ventura (13) passed 💻

All tests on macOS M1 - Mac Ventura (13) passed.

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

Legacy Xamarin (No breaking changes)
  • iOS (no change detected)
  • tvOS (no change detected)
  • watchOS (no change detected)
  • macOS (no change detected)
NET (empty diffs)
  • iOS: (empty diff detected)
  • tvOS: (empty diff detected)
  • MacCatalyst: (empty diff detected)
  • macOS: (empty diff detected)

✅ API diff vs stable

Legacy Xamarin (No breaking changes)
.NET (No breaking changes)
Legacy Xamarin (stable) vs .NET

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: f77ade5ac1a987a1482496b3b4d010830542d07c [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🚀 [CI Build] Test results 🚀

Test results

✅ All tests passed on VSTS: test results.

🎉 All 170 tests passed 🎉

Tests counts

✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 8 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 7 tests passed. Html Report (VSDrops) Download
✅ generator: All 2 tests passed. Html Report (VSDrops) Download
✅ install-source: All 1 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 7 tests passed. Html Report (VSDrops) Download
✅ introspection: All 8 tests passed. Html Report (VSDrops) Download
✅ linker: All 65 tests passed. Html Report (VSDrops) Download
✅ mac-binding-project: All 1 tests passed. Html Report (VSDrops) Download
✅ mmp: All 2 tests passed. Html Report (VSDrops) Download
✅ mononative: All 6 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 11 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 7 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 8 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 11 tests passed. Html Report (VSDrops) Download
✅ monotouch (watchOS): All 4 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ mtouch: All 1 tests passed. Html Report (VSDrops) Download
✅ xammac: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 8 tests passed. Html Report (VSDrops) Download
✅ xtro: All 2 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: f77ade5ac1a987a1482496b3b4d010830542d07c [PR build]

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.

6 participants