Skip to content

Commit

Permalink
Wriring up Reflection to execution layer
Browse files Browse the repository at this point in the history
Tests added by extending the build task example project.
Extended runner in ScriptSharp for keeping into account the assembly.

Attention: The runner does not work because the assembly is not loaded
into the inspection only context and all reference errors are surfacing.
This must be fixed in later pack.

Targets #41
  • Loading branch information
andry-tino committed Apr 9, 2017
1 parent 799a169 commit f471095
Show file tree
Hide file tree
Showing 17 changed files with 303 additions and 74 deletions.
4 changes: 0 additions & 4 deletions src/Reflection.ScriptSharp/ASTBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ namespace Rosetta.Reflection.ScriptSharp
using System;
using System.Reflection;

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

using Rosetta.Reflection.ScriptSharp.Helpers;

/// <summary>
Expand Down
27 changes: 27 additions & 0 deletions src/Reflection.ScriptSharp/ProgramWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/// <summary>
/// ProgramWrapper.cs
/// Andrea Tino - 2017
/// </summary>

namespace Rosetta.Reflection.ScriptSharp
{
using System;
using System.Reflection;

/// <summary>
/// Initiates the translation.
/// </summary>
public class ProgramWrapper : Rosetta.Reflection.ProgramWrapper
{
/// <summary>
/// Initializes a new instance of the <see cref="ProgramWrapper"/> class.
/// </summary>
/// <param name="assemblyPath"></param>
public ProgramWrapper(string assemblyPath)
: base(assemblyPath)
{
}

protected override IASTBuilder CreateASTBuilder(Assembly assembly) => new ASTBuilder(assembly);
}
}
1 change: 1 addition & 0 deletions src/Reflection.ScriptSharp/Reflection.ScriptSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
<Compile Include="ASTBuilder.cs" />
<Compile Include="helpers\Namespace.cs" />
<Compile Include="helpers\ScriptNamespaceAttributeDecoration.cs" />
<Compile Include="ProgramWrapper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
20 changes: 19 additions & 1 deletion src/Reflection/ASTBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Rosetta.Reflection
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand Down Expand Up @@ -58,7 +59,24 @@ public ASTInfo Build()
return this.astInfo;
}

var types = this.assembly.DefinedTypes;
IEnumerable<System.Reflection.TypeInfo> types = null;
try
{
types = this.assembly.DefinedTypes;
}
catch(ReflectionTypeLoadException ex)
{
// Rethrow by emitting all errors
var errorMessage = new StringBuilder();
errorMessage.AppendLine($"Error loading defined types in assembly {this.assembly.FullName}. Found {ex.LoaderExceptions.Length} errors:");

foreach (var innerException in ex.LoaderExceptions)
{
errorMessage.AppendLine($"{innerException.GetType().Name} - {innerException.HResult}: {innerException.Message}");
}

throw new InvalidOperationException(errorMessage.ToString(), ex);
}

var nodes = new List<MemberDeclarationSyntax>();
var numberOfClasses = 0;
Expand Down
7 changes: 5 additions & 2 deletions src/Reflection/ProgramWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@ public string Output
}
}

protected virtual IASTBuilder CreateASTBuilder(Assembly assembly) => new ASTBuilder(assembly);

private void Initialize()
{
Assembly assembly = null;
try
{
assembly = Assembly.LoadFrom(this.assemblyPath);
//assembly = Assembly.LoadFrom(this.assemblyPath);
assembly = Assembly.ReflectionOnlyLoadFrom(this.assemblyPath);
}
catch (FileNotFoundException ex)
{
Expand All @@ -75,7 +78,7 @@ private void Initialize()
throw new InvalidOperationException("Invalid assembly path", ex);
}

var builder = new ASTBuilder(assembly);
var builder = this.CreateASTBuilder(assembly);
var astInfo = builder.Build();

// Getting the AST node
Expand Down
5 changes: 2 additions & 3 deletions src/Runner/Program.ConvertProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ namespace Rosetta.Runner

/// <summary>
/// Part of program responsible for translating one single file.
///
/// TODO: Remove as a build task can be used instead.
/// </summary>
internal partial class Program
{
[Obsolete("This scenario is covered by Rosetta.ScriptSharp.Definition.BuildTask", false)]
protected virtual void ConvertProject()
{

// TODO
}

#region Helpers
Expand Down
65 changes: 36 additions & 29 deletions src/ScriptSharp.Definition.BuildTask/GenerateBundleTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,47 @@ namespace Rosetta.ScriptSharp.Definition.BuildTask
/// </summary>
public class GenerateBundleTask : GenerateTaskBase
{
private const string DefaultBundleName = "Bundle";

private readonly string bundleName;

private List<FileConversionInfo> outputs;

/// <summary>
/// Initializes a new instance of the <see cref="GenerateBundleTask"/> class.
/// </summary>
/// <param name="sourceFiles"></param>
/// <param name="outputFolder"></param>
/// <param name="bundleName"></param>
public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder, string bundleName = "Bundle")
/// <param name="sourceFiles">The collection of paths to the files to consider.</param>
/// <param name="outputFolder">The folder where to emit generated files.</param>
/// <param name="bundleName">The name of the bundle.</param>
public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder, string bundleName = null)
: this(sourceFiles, outputFolder, null, null, bundleName)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="GenerateBundleTask"/> class.
/// </summary>
/// <param name="sourceFiles"></param>
/// <param name="outputFolder"></param>
/// <param name="assemblyPath"></param>
/// <param name="bundleName"></param>
public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder, string assemblyPath, string bundleName = "Bundle")
/// <param name="sourceFiles">The collection of paths to the files to consider.</param>
/// <param name="outputFolder">The folder where to emit generated files.</param>
/// <param name="assemblyPath">The path to the assembly providing information on symbols in source files.</param>
/// <param name="bundleName">The name of the bundle.</param>
public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder, string assemblyPath, string bundleName = null)
: this(sourceFiles, outputFolder, assemblyPath, null, bundleName)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="GenerateBundleTask"/> class.
/// </summary>
/// <param name="sourceFiles"></param>
/// <param name="outputFolder"></param>
/// <param name="assemblyPath"></param>
/// <param name="references"></param>
/// <param name="bundleName"></param>
public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder, string assemblyPath, IEnumerable<string> references, string bundleName = "Bundle")
/// <param name="sourceFiles">The collection of paths to the files to consider.</param>
/// <param name="outputFolder">The folder where to emit generated files.</param>
/// <param name="assemblyPath">The path to the assembly providing information on symbols in source files.</param>
/// <param name="references">Additional references to add in the emitted bundle.</param>
/// <param name="bundleName">The name of the bundle.</param>
public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder, string assemblyPath, IEnumerable<string> references, string bundleName = null)
: base(sourceFiles, outputFolder, assemblyPath, references)
{
this.bundleName = bundleName;
this.bundleName = bundleName ?? DefaultBundleName;

this.outputs = new List<FileConversionInfo>();
}
Expand All @@ -65,19 +67,7 @@ public GenerateBundleTask(IEnumerable<string> sourceFiles, string outputFolder,
/// <returns></returns>
public override void Run()
{
foreach (var file in this.sourceFiles)
{
this.ConvertFile(file);
}

var chuncks = this.outputs.Select(output => string.Join(Environment.NewLine, new[] {
$"/**",
$" * File: {output.FileName}",
$" */",
$"{output.FileConversion}",
string.Empty }));

var bundle = string.Join(Environment.NewLine, chuncks);
var bundle = this.GenerateOutput();

// Handling references
bundle = this.GeneratePrependedText() + bundle;
Expand All @@ -93,6 +83,23 @@ public override void Run()
FileManager.WriteToFile(bundle, outputPath, this.bundleName + "." + extension);
}

protected virtual string GenerateOutput()
{
foreach (var file in this.sourceFiles)
{
this.ConvertFile(file);
}

var chuncks = this.outputs.Select(output => string.Join(Environment.NewLine, new[] {
$"/**",
$" * File: {output.FileName}",
$" */",
$"{output.FileConversion}",
string.Empty }));

return string.Join(Environment.NewLine, chuncks);
}

private void ConvertFile(string filePath)
{
var runner = new FileSilentConversionRunner(PerformFileConversion, new ConversionArguments()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/// <summary>
/// GenerateBundleWithReflectionTask.cs
/// Andrea Tino - 2016
/// </summary>

namespace Rosetta.ScriptSharp.Definition.BuildTask
{
using System;
using System.Collections.Generic;

using Rosetta.Reflection.ScriptSharp;

/// <summary>
/// The build task.
/// </summary>
public class GenerateBundleWithReflectionTask : GenerateBundleTask
{
/// <summary>
/// Initializes a new instance of the <see cref="GenerateBundleWithReflectionTask"/> class.
/// </summary>
/// <param name="outputFolder">The folder where to emit generated files.</param>
/// <param name="assemblyPath">The path to the assembly providing information on symbols in source files.</param>
/// <param name="references">Additional references to add in the emitted bundle.</param>
/// <param name="bundleName">The name of the bundle.</param>
public GenerateBundleWithReflectionTask(string outputFolder, string assemblyPath, IEnumerable<string> references, string bundleName = null)
: base(new string[0], outputFolder, assemblyPath, references, bundleName)
{
}

protected override string GenerateOutput() => new ProgramWrapper(this.assemblyPath).Output;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class GenerateDefinitionsBuildTask : Task
/// <summary>
/// Gets or sets the collection of source files to generate definition files from.
/// </summary>
[Required]
public ITaskItem[] Files { get; set; }

/// <summary>
Expand Down Expand Up @@ -91,8 +90,15 @@ public override bool Execute()

try
{
this.Log.LogMessage("Generating TypeScript definitions for {0} file{1}...",
this.Files.Count(), this.Files.Count() > 1 ? "s" : string.Empty);
if (this.SourceFiles != null)
{
this.Log.LogMessage("Generating TypeScript definitions for {0} file{1}...",
this.Files.Count(), this.Files.Count() > 1 ? "s" : string.Empty);
}
else
{
this.Log.LogMessage("Generating TypeScript definitions...");
}

this.CreateTask().Run();
}
Expand Down Expand Up @@ -128,9 +134,13 @@ public override bool Execute()

private GenerateTaskBase CreateTask()
{
return this.CreateBundle
? new GenerateBundleTask(this.SourceFiles, this.OutputFolder, this.AssemblyPath, this.ReferencedFiles, this.BundleName)
: new GenerateFilesTask(this.SourceFiles, this.OutputFolder, this.AssemblyPath, this.ReferencedFiles) as GenerateTaskBase;
return new GenerateTaskFactory(
this.SourceFiles,
this.OutputFolder,
this.AssemblyPath,
this.ReferencedFiles,
this.CreateBundle ? this.BundleName : null)
.Create();
}
}
}
65 changes: 65 additions & 0 deletions src/ScriptSharp.Definition.BuildTask/GenerateTaskFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/// <summary>
/// GenerateTaskFactory.cs
/// Andrea Tino - 2016
/// </summary>

namespace Rosetta.ScriptSharp.Definition.BuildTask
{
using System;
using System.Collections.Generic;
using System.Linq;

using Rosetta.Executable;

/// <summary>
/// Factory for creating a <see cref="GenerateTaskBase"/>.
/// </summary>
public class GenerateTaskFactory
{
private readonly IEnumerable<string> sourceFiles;
private readonly string outputFolder;
private readonly string assemblyPath;
private readonly IEnumerable<string> references;
private readonly string bundleName;

/// <summary>
/// Initializes a new instance of the <see cref="GenerateTaskFactory"/> class.
/// </summary>
/// <param name="sourceFiles">The collection of paths to the files to consider.</param>
/// <param name="outputFolder">The folder where to emit generated files.</param>
/// <param name="assemblyPath">The path to the assembly providing information on symbols in source files.</param>
/// <param name="references">Additional references to add in the emitted bundle.</param>
/// <param name="bundleName">The name of the bundle.</param>
public GenerateTaskFactory(IEnumerable<string> sourceFiles, string outputFolder, string assemblyPath, IEnumerable<string> references, string bundleName)
{
if (outputFolder == null)
{
throw new ArgumentNullException(nameof(outputFolder));
}

this.sourceFiles = sourceFiles;
this.outputFolder = outputFolder;
this.assemblyPath = assemblyPath;
this.references = references;
this.bundleName = bundleName;
}

/// <summary>
/// Creates the proper <see cref="GenerateTaskBase"/> given the input parameters.
/// </summary>
/// <returns>A <see cref="GenerateTaskBase"/>.</returns>
public GenerateTaskBase Create()
{
if (this.CreateBundle)
{
return this.sourceFiles != null
? new GenerateBundleTask(this.sourceFiles, this.outputFolder, this.assemblyPath, this.references, this.bundleName)
: new GenerateBundleWithReflectionTask(this.outputFolder, this.assemblyPath, this.references, this.bundleName);
}

return new GenerateFilesTask(this.sourceFiles, this.outputFolder, this.assemblyPath, this.references) as GenerateTaskBase;
}

private bool CreateBundle => this.bundleName != null && this.bundleName.Length > 0;
}
}
Loading

0 comments on commit f471095

Please sign in to comment.