Skip to content

Commit

Permalink
Cleanup and work on statements
Browse files Browse the repository at this point in the history
  • Loading branch information
Kathleen Dollard committed Jul 11, 2014
1 parent afd2ac5 commit 58f147f
Show file tree
Hide file tree
Showing 35 changed files with 654 additions and 444 deletions.
Binary file not shown.
8 changes: 6 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
RoslynDOM
RoslynDom
=========
This provides programmer friendly view of your application via the Roslyn AST, currently in a very preliminary form
This provides programmer friendly view of your application via the .NET Compiler Platform (code named Roslyn) from Microsoft. This is an early, experimental release.

Available on NuGet
---
[Install-Package RoslynDOM -Pre](https://www.nuget.org/packages/RoslynDOM/)

More info
---
You can find more info on [my blog] (http://msmvps.com/blogs/kathleen/default.aspx)

Examples
---
```C#
Expand Down
202 changes: 165 additions & 37 deletions RoslynDom/RDomFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,26 @@ private static bool DoMembers<T>(MemberDeclarationSyntax val,
return (list.Count() > startCount);
}

private static bool DoStatement<T>(StatementSyntax val,
Func<T, IStatement> doAction, out IStatement retValue)
where T : class
{
var item = val as T;
retValue = item != null ? doAction(item) : null;
return (retValue != null);
}

private static bool DoStatements<T>(StatementSyntax val,
Action<T, List<IStatement>> doAction, List<IStatement> list)
where T : class
{
var item = val as T;
if (item == null) return false;
var startCount = list.Count();
doAction(item, list);
return (list.Count() > startCount);
}

/// <summary>
/// Creates namespace and class
/// </summary>
Expand Down Expand Up @@ -177,9 +197,109 @@ private static IParameter MakeParameter(ParameterSyntax rawParm)

private static IStatement MakeStatement(StatementSyntax rawStatement)
{
var statements = ListUtilities.MakeList(rawStatement, x => GetStatements(x), x => MakeStatement(x));
var publicAnnotations = GetPublicAnnotations(rawStatement).ToArray();
return new RDomStatement(rawStatement, statements, publicAnnotations);
IStatement ret;
// The action happens in DoMember. I felt it read better with else than negation and it made copying new lines easier
if (DoStatement<BlockSyntax>(rawStatement, MakeBlockStatement, out ret)) { }
else if (DoStatement<IfStatementSyntax>(rawStatement, MakeIfStatement, out ret)) { }
return ret as IStatement;

//ForEach,
//For,
//Empty,
//Return,
//Declaration,
//Try,

////While, variation of Do
////Else, characteristic of If
////Using, characteristic of Block
////Catch, characteristic of Try
////Switch, // can this be handled as a special case of if?
//Break, // probably have to support
//Continue, // probably have to support
//Throw, // probably have to support

////Expression statements, // break this appart into two kinds
//Invocation,
//Assignment,

//Special // (platform or lanuguage specific)
////Checked (block)
////Lock,
////Yield, Split into YieldBreak and YieldReturn (expression)

// Planning to avoid unless someone has a scenario
//Unsafe,
//Fixed,
//Goto,
//Labeled,
}

private static IBlockStatement MakeBlockStatement(BlockSyntax rawBlock)
{
var publicAnnotations = GetPublicAnnotations(rawBlock).ToArray();
var statements = ListUtilities.MakeList(rawBlock, x => x.Statements, x => MakeStatement(x));
return new RDomBlockStatement(rawBlock, statements, publicAnnotations);
}

private static IIfStatement MakeIfStatement(IfStatementSyntax rawIf)
{
var publicAnnotations = GetPublicAnnotations(rawIf).ToArray();
var hasBlock = false;
var statements = new List<IStatement>();
var block = rawIf.Statement as BlockSyntax;
if (block != null)
{
hasBlock = true;
statements.AddRange(ListUtilities.MakeList(rawIf, x => block.Statements, x => MakeStatement(x)));
}
else
{ statements.Add(MakeStatement(rawIf.Statement)); }
IEnumerable<IIfStatement> elses = null;
if (rawIf.Else != null)
{ elses = MakeElses(rawIf.Else.Statement); }
return new RDomIfStatement(rawIf, hasBlock, statements, elses, publicAnnotations);
}

private static IEnumerable<IIfStatement> MakeElses(StatementSyntax rawElseStatement)
{
var publicAnnotations = GetPublicAnnotations(rawElseStatement).ToArray();
var elses = new List<IIfStatement>();
var elseStatement = rawElseStatement as IfStatementSyntax;
if (elseStatement != null)
{
elses.Add(MakeIfStatement(elseStatement));
elses.AddRange(MakeElses(elseStatement.Else.Statement));
}
else
{
var statements = new List<IStatement>();
bool hasBlock = false;
var blockElseStatement = rawElseStatement as BlockSyntax;
if (blockElseStatement != null)
{
hasBlock = true;
statements.AddRange(ListUtilities.MakeList(rawElseStatement, x => blockElseStatement.Statements, x => MakeStatement(x)));
}
else
{ statements.Add(MakeStatement(rawElseStatement)); }
elses.Add(new RDomIfStatement(null, hasBlock, statements, null, publicAnnotations));

}
return elses;
}

private static IEnumerable<IDeclarationStatement> MakeDeclarationStatement(LocalDeclarationStatementSyntax rawDeclaration)
{
var list = new List<IDeclarationStatement>();
var declaration = rawDeclaration.Declaration;
var variables = declaration.Variables.OfType<VariableDeclaratorSyntax>();
foreach (var variable in variables)
{
var publicAnnotations = GetPublicAnnotations(rawDeclaration).ToArray();
list.Add(new RDomDeclarationStatement(rawDeclaration, declaration, variable, publicAnnotations));
}
return list;
}

private static IEnumerable<StatementSyntax> GetStatements(MethodDeclarationSyntax rawMethod)
Expand All @@ -188,47 +308,55 @@ private static IEnumerable<StatementSyntax> GetStatements(MethodDeclarationSynta
return rawMethod.Body.Statements;
}


private static IEnumerable<StatementSyntax> GetStatements(StatementSyntax rawStatement)
{
var list = new List<StatementSyntax>();

// These have nested block syntax
// This handles method and property
if (LoadStatementListFromList<BlockSyntax>(rawStatement, x => x.Statements, list)) { return list; }
if (LoadStatementListFromList<UnsafeStatementSyntax>(rawStatement, x => x.Block.Statements, list)) { return list; }
if (LoadStatementListFromList<CheckedStatementSyntax>(rawStatement, x => x.Block.Statements, list)) { return list; }
if (LoadStatementListFromList<TryStatementSyntax>(rawStatement, x => x.Block.Statements, list)) { return list; }

// These have a statement which often, but not always, holds a nested block
if (LoadStatementListFromItem<DoStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
if (LoadStatementListFromItem<ForEachStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
if (LoadStatementListFromItem<ForStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
if (LoadStatementListFromItem<LockStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
if (LoadStatementListFromItem<WhileStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
if (LoadStatementListFromItem<UsingStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
if (LoadStatementListFromItem<IfStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; } // if has a second block for else

// These do not have nested blocksyntax or statements
// BreakStatementSyntax
// ContinueStatementSyntax
// EmptyStatementSyntax
// ExpressionStatementSyntax
// LocalDeclarationStatement
// ReturnStatementSyntax
// ThrowStatementSyntax
// YieldStatementSyntax

// This is a very weird special case
// SwitchStatementSyntax

// These are items I currently do not plan to support - although need to confirm that switch doesn't use labeled statements
// FixedStatementSyntax
// GotoStatementSyntax
// LabeledStatementSyntax

//// These have nested block syntax
//if (LoadStatementListFromList<BlockSyntax>(rawStatement, x => x.Statements, list)) { return list; }
//if (LoadStatementListFromList<CheckedStatementSyntax>(rawStatement, x => x.Block.Statements, list)) { return list; }

//// These have a statement which often, but not always, holds a nested block
//if (LoadStatementListFromItem<DoStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
//if (LoadStatementListFromItem<ForEachStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
//if (LoadStatementListFromItem<ForStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
//if (LoadStatementListFromItem<LockStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
//if (LoadStatementListFromItem<WhileStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }
//if (LoadStatementListFromItem<UsingStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; }

//// These have more than one statement block
//if (LoadStatementListFromItem<IfStatementSyntax>(rawStatement, x => x.Statement, list)) { return list; } // if has a second block for else
//if (LoadStatementListFromList<TryStatementSyntax>(rawStatement, x => x.Block.Statements, list)) { return list; }

//// These do not have nested blocksyntax or statements
//// BreakStatementSyntax
//// ContinueStatementSyntax
//// EmptyStatementSyntax
//// ExpressionStatementSyntax
//// LocalDeclarationStatement
//// ReturnStatementSyntax
//// ThrowStatementSyntax
//// YieldStatementSyntax

//// This is a very weird special case
//// SwitchStatementSyntax

//// These are items I currently do not plan to support - although need to confirm that switch doesn't use labeled statements
//// FixedStatementSyntax
//// GotoStatementSyntax
//// LabeledStatementSyntax
//// UnsafeStatementSyntax

return list;
}

private static bool LoadStatementListFromList<T>(StatementSyntax rawStatement, Func<T, IEnumerable<StatementSyntax>> getList, List<StatementSyntax> list)
private static bool LoadStatementListFromList<T>(
StatementSyntax rawStatement,
Func<T, IEnumerable<StatementSyntax>> getList,
List<StatementSyntax> list)
where T : StatementSyntax
{
var typed = rawStatement as T;
Expand Down Expand Up @@ -256,7 +384,7 @@ private static IMember MakeProperty(PropertyDeclarationSyntax rawProperty)
return new RDomProperty(rawProperty, parms, getAccessor, setAccessor, publicAnnotations);
}

private static IAccessor MakeAccessor(AccessorDeclarationSyntax rawAccessor)
private static IAccessor MakeAccessor(AccessorDeclarationSyntax rawAccessor)
{
if (rawAccessor == null) return null;
var statements = ListUtilities.MakeList(rawAccessor, x => GetStatements(rawAccessor.Body), x => MakeStatement(x));
Expand Down
8 changes: 7 additions & 1 deletion RoslynDom/RoslynDom.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@
<Compile Include="Implementations\RDomInterface.cs" />
<Compile Include="Implementations\RDomInvalidTypeMember.cs" />
<Compile Include="Implementations\RDomAccessor.cs" />
<Compile Include="Implementations\RDomStatement.cs" />
<Compile Include="StatementImplementations\RDomAssignmentStatement.cs" />
<Compile Include="StatementImplementations\RDomReturnStatemen.cs" />
<Compile Include="StatementImplementations\RDomDeclarationStatement.cs" />
<Compile Include="StatementImplementations\RDomStatement.cs" />
<Compile Include="Implementations\RDomMethod.cs" />
<Compile Include="Implementations\RDomNamespace.cs" />
<Compile Include="Implementations\RDomParameter.cs" />
Expand All @@ -88,6 +91,9 @@
<Compile Include="RDomFactory.cs" />
<Compile Include="RoslynUtilities.cs" />
<Compile Include="RoslynDomUtilities.cs" />
<Compile Include="StatementImplementations\RDomBaseBlock.cs" />
<Compile Include="StatementImplementations\RDomIfStatement.cs" />
<Compile Include="StatementImplementations\RDomBlockStatement.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
Expand Down
42 changes: 42 additions & 0 deletions RoslynDom/StatementImplementations/RDomAssignmentStatement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using RoslynDom.Common;

namespace RoslynDom
{
public class RDomAssignmentStatement : RDomStatement, IAssignmentStatement
{
private VariableDeclarationSyntax _variableSyntax;
private VariableDeclaratorSyntax _declaratorSyntax;


internal RDomAssignmentStatement(
ExpressionStatementSyntax rawExpression,
params PublicAnnotation[] publicAnnotations)
: base(rawExpression, StatementKind.Assignment, publicAnnotations)
{
Initialize();
}

internal RDomAssignmentStatement(RDomAssignmentStatement oldRDom)
: base(oldRDom)
{ }

protected override void Initialize()
{
base.Initialize();
}

public override StatementSyntax BuildSyntax()
{
return null;
}

public string VarName { get; set; }
public IExpression Expression { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,42 @@

namespace RoslynDom
{
public class RDomStatement : RDomBase<IStatement, StatementSyntax, ISymbol>, IStatement
public abstract class RDomBaseBlock : RDomStatement
{
private IList<IStatement> _statements = new List<IStatement>();

internal RDomStatement(
internal RDomBaseBlock(
StatementSyntax rawItem,
IEnumerable<IStatement> statements,
StatementKind statementKind,
params PublicAnnotation[] publicAnnotations)
: base(rawItem, publicAnnotations)
: base(rawItem, statementKind, publicAnnotations)
{
foreach (var statement in statements)
{ AddStatement(statement); }
Initialize();
{ AddOrMoveStatement(statement); }
}

internal RDomStatement(RDomStatement oldRDom)
internal RDomBaseBlock(RDomBaseBlock oldRDom)
: base(oldRDom)
{
var newStatements = RoslynDomUtilities.CopyMembers(oldRDom._statements);
foreach (var statement in newStatements)
{ AddStatement(statement); }

IsBlock = oldRDom.IsBlock;
StatementKind = oldRDom.StatementKind;
}

protected override void Initialize()
{
base.Initialize();
IsBlock = _statements.Count() > 1 || TypedSyntax is BlockSyntax;
{ AddOrMoveStatement(statement); }
}

public override StatementSyntax BuildSyntax()
{
return TypedSyntax;
return null;
}

public void RemoveStatement(IStatement statement)
{ _statements.Remove(statement); }

public void AddStatement(IStatement statement)
public void AddOrMoveStatement(IStatement statement)
{ _statements.Add(statement); }


public bool IsBlock { get; set; }

public StatementKind StatementKind { get; set; }

public IEnumerable<IStatement> Statements
{ get { return _statements; } }

}
}
Loading

0 comments on commit 58f147f

Please sign in to comment.