Skip to content

Commit

Permalink
Adding support for class and methods in reflection
Browse files Browse the repository at this point in the history
Added tests for class and methods (factories).
  • Loading branch information
andry-tino committed May 16, 2017
1 parent ff70da0 commit 9d61ca0
Show file tree
Hide file tree
Showing 23 changed files with 961 additions and 21 deletions.
15 changes: 9 additions & 6 deletions src/Reflection.ScriptSharp/helpers/Namespace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Rosetta.Reflection.ScriptSharp.Helpers
using Rosetta.Reflection.Proxies;

/// <summary>
/// Helper for <see cref="TypeInfo"/> in order to retrieve information about its namespace.
/// Helper for <see cref="ITypeInfoProxy"/> in order to retrieve information about its namespace.
/// </summary>
public class Namespace : Rosetta.Reflection.Helpers.Namespace
{
Expand Down Expand Up @@ -43,14 +43,17 @@ public override string FullName

IEnumerable<ICustomAttributeDataProxy> customAttributes = this.Type.CustomAttributes;

foreach (ICustomAttributeDataProxy attribute in customAttributes)
if (customAttributes != null)
{
if (ScriptNamespaceAttributeDecoration.IsScriptNamespaceAttributeDecoration(attribute.AttributeType))
foreach (ICustomAttributeDataProxy attribute in customAttributes)
{
var helper = new ScriptNamespaceAttributeDecoration(attribute);
this.fullName = helper.OverridenNamespace;
if (ScriptNamespaceAttributeDecoration.IsScriptNamespaceAttributeDecoration(attribute.AttributeType))
{
var helper = new ScriptNamespaceAttributeDecoration(attribute);
this.fullName = helper.OverridenNamespace;

break;
break;
}
}
}
}
Expand Down
46 changes: 37 additions & 9 deletions src/Reflection/ASTBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ namespace Rosetta.Reflection
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

using Rosetta.Reflection.Factories;
using Rosetta.Reflection.Helpers;
using Rosetta.Reflection.Proxies;

Expand All @@ -26,7 +26,7 @@ namespace Rosetta.Reflection
/// - Supports only classes, interfaces, enums and structs.
/// - Does not support nested types. Only types in namespaces are supported.
/// </remarks>
public class ASTBuilder : IASTBuilder
public partial class ASTBuilder : IASTBuilder
{
private readonly IAssemblyProxy assembly;
private readonly Stream rawAssembly;
Expand Down Expand Up @@ -109,7 +109,7 @@ public ASTInfo Build()

private MemberDeclarationSyntax BuildClassNode(ITypeInfoProxy type)
{
return this.BuildNode(type, SyntaxFactory.ClassDeclaration);
return this.BuildNode(type, this.BuildClassNodeCore(type));
}

private MemberDeclarationSyntax BuildStructNode(ITypeInfoProxy type)
Expand Down Expand Up @@ -142,14 +142,46 @@ private Compilation BuildCompilationUnit(SyntaxTree tree)
return CSharpCompilation.Create("GeneratedCompilation", new[] { tree }, references);
}

private MemberDeclarationSyntax BuildClassNodeCore(ITypeInfoProxy type)
{
return new ClassDeclarationSyntaxFactory(type).Create();
}

// TODO: Remove this once all core methods have been built
private MemberDeclarationSyntax BuildNode(ITypeInfoProxy type, RoslynNodeFactory factory)
{
var helper = this.CreateNamespaceHelper(type);

MemberDeclarationSyntax node = null;

var namespaceNode = helper.Exists ? SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(helper.FullName)) : null;
var typeNode = factory(type.Name);
var typeNode = factory(type.Name); // Creates the node to put in the namespace (if any)

if (namespaceNode != null)
{
namespaceNode = namespaceNode.AddMembers(typeNode);
node = namespaceNode;
}
else
{
node = typeNode;
}

return node;
}

/// <summary>
/// Places the built node in the right namespace.
/// </summary>
/// <param name="type"></param>
/// <param name="typeNode"></param>
/// <returns></returns>
private MemberDeclarationSyntax BuildNode(ITypeInfoProxy type, MemberDeclarationSyntax typeNode)
{
var helper = this.CreateNamespaceHelper(type);
var namespaceNode = helper.Exists ? SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(helper.FullName)) : null;

MemberDeclarationSyntax node = null;

if (namespaceNode != null)
{
Expand All @@ -171,11 +203,7 @@ protected virtual Namespace CreateNamespaceHelper(ITypeInfoProxy type)

#region Types

/// <summary>
///
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
// TODO: Remove it once we get rid of old implementation of BuildNode
protected delegate MemberDeclarationSyntax RoslynNodeFactory(string typeName);

#endregion
Expand Down
12 changes: 10 additions & 2 deletions src/Reflection/Reflection.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@
<Private>True</Private>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Reflection.Metadata, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Reference Include="System.Reflection.Metadata, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Reflection">
<Reference Include="System.Reflection">
<HintPath>..\..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
<Private>True</Private>
</Reference>
Expand All @@ -123,23 +123,31 @@
<ItemGroup>
<Compile Include="assembly-proxying\ICustomAttributeDataProxy.cs" />
<Compile Include="assembly-proxying\ICustomAttributeTypedArgumentProxy.cs" />
<Compile Include="assembly-proxying\IMethodInfoProxy.cs" />
<Compile Include="assembly-proxying\IParameterInfoProxy.cs" />
<Compile Include="assembly-proxying\ITypeInfoProxy.cs" />
<Compile Include="assembly-proxying\ITypeProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoAssemblyProxy.cs" />
<Compile Include="assembly-proxying\IAssemblyProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoCustomAttributeDataProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoCustomAttributeTypedArgumentProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoMethodInfoProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoParameterInfoProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoTypeInfoProxy.cs" />
<Compile Include="assembly-proxying\mono\MonoTypeProxy.cs" />
<Compile Include="ASTBuilder.cs" />
<Compile Include="ASTInfo.cs" />
<Compile Include="factories\ClassDeclarationSyntaxFactory.cs" />
<Compile Include="factories\MethodDeclarationSyntaxFactory.cs" />
<Compile Include="helpers\Visibility.cs" />
<Compile Include="loading\MonoFSAssemblyLoader.cs" />
<Compile Include="helpers\Namespace.cs" />
<Compile Include="loading\IAssemblyLoader.cs" />
<Compile Include="IASTBuilder.cs" />
<Compile Include="loading\MonoStreamAssemblyLoader.cs" />
<Compile Include="ProgramWrapper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="utilities\DummyBody.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
Expand Down
47 changes: 47 additions & 0 deletions src/Reflection/assembly-proxying/IMethodInfoProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// <summary>
/// IMethodInfoProxy.cs
/// Andrea Tino - 2017
/// </summary>

namespace Rosetta.Reflection.Proxies
{
using System;
using System.Collections.Generic;

/// <summary>
/// Abstracts type info API.
/// </summary>
public interface IMethodInfoProxy
{
/// <summary>
/// Gets the name of the current member.
/// </summary>
string Name { get; }

/// <summary>
/// Gets the parameters of the specified method or constructor.
/// </summary>
IEnumerable<IParameterInfoProxy> Parameters { get; }

/// <summary>
/// Gets the return type of this method.
/// </summary>
ITypeProxy ReturnType { get; }

/// <summary>
/// Gets a value indicating whether the method or constructor is visible only within its class
/// and derived classes.
/// </summary>
bool IsFamily { get; }

/// <summary>
/// Gets a value indicating whether this member is private.
/// </summary>
bool IsPrivate { get; }

/// <summary>
/// Gets a value indicating whether this member is public.
/// </summary>
bool IsPublic { get; }
}
}
25 changes: 25 additions & 0 deletions src/Reflection/assembly-proxying/IParameterInfoProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/// <summary>
/// IParameterInfoProxy.cs
/// Andrea Tino - 2017
/// </summary>

namespace Rosetta.Reflection.Proxies
{
using System;

/// <summary>
/// Abstracts type info API.
/// </summary>
public interface IParameterInfoProxy
{
/// <summary>
/// Gets the name of the parameter.
/// </summary>
string Name { get; }

/// <summary>
/// Gets the Type of this parameter.
/// </summary>
ITypeProxy ParameterType { get; }
}
}
25 changes: 25 additions & 0 deletions src/Reflection/assembly-proxying/ITypeInfoProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,34 @@ public interface ITypeInfoProxy
/// </summary>
string Name { get; }

/// <summary>
/// Gets a value indicating whether the type is declared public.
/// </summary>
bool IsPublic { get; }

/// <summary>
/// Gets a value indicating whether the type is not declared public.
/// </summary>
bool IsNotPublic { get; }

/// <summary>
/// Gets a collection that contains this member's custom attributes.
/// </summary>
IEnumerable<ICustomAttributeDataProxy> CustomAttributes { get; }

/// <summary>
/// Gets a collection of the interfaces implemented by the current type.
/// </summary>
IEnumerable<ITypeProxy> ImplementedInterfaces { get; }

/// <summary>
/// Gets the type from which the current Type directly inherits.
/// </summary>
ITypeProxy BaseType { get; }

/// <summary>
/// Gets a collection of the methods defined by the current type.
/// </summary>
IEnumerable<IMethodInfoProxy> DeclaredMethods { get; }
}
}
9 changes: 8 additions & 1 deletion src/Reflection/assembly-proxying/ITypeProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@
namespace Rosetta.Reflection.Proxies
{
using System;
using System.Collections.Generic;

/// <summary>
/// Abstracts type API.
/// </summary>
/// <remarks>
/// The difference with <see cref="ITypeInfoProxy"/> is that this one does not provide info about the type definition.
/// </remarks>
public interface ITypeProxy
{
/// <summary>
/// Gets the name of the type.
/// </summary>
string Name { get; }

/// <summary>
/// Gets the full name of the type.
/// </summary>
string FullName { get; }
}
}
1 change: 1 addition & 0 deletions src/Reflection/assembly-proxying/mono/MonoAssemblyProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public MonoAssemblyProxy(ModuleDefinition monoModuleDefinition)
/// </summary>
public IEnumerable<ITypeInfoProxy> DefinedTypes => this.moduleDefinition.Types.Select(type => new MonoTypeInfoProxy(type));

// Used by debugger
private string AssemblyName => this.moduleDefinition.FullyQualifiedName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ public MonoCustomAttributeDataProxy(CustomAttribute monoCustomAttribute)
public IEnumerable<ICustomAttributeTypedArgumentProxy> ConstructorArguments =>
this.customAttribute.ConstructorArguments.Select(arg => new MonoCustomAttributeTypedArgumentProxy(arg));

// Used by debugger
private string AttributeTypeName => this.customAttribute.AttributeType.Name;

// Used by debugger
private string AttributeTypeFullName => this.customAttribute.AttributeType.FullName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ public MonoCustomAttributeTypedArgumentProxy(CustomAttributeArgument monoCustomA

private string StringValue => this.Value.ToString();

// Used by debugger
private string StringArumentTypeName => this.customAttributeArgument.Type.Name;

// Used by debugger
private string StringArumentTypeFullName => this.customAttributeArgument.Type.FullName;
}
}
Loading

1 comment on commit 9d61ca0

@andry-tino
Copy link
Owner Author

Choose a reason for hiding this comment

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

Targets #41

Please sign in to comment.