Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Rewriting #599

Closed
wants to merge 12 commits into from
7 changes: 7 additions & 0 deletions src/ScriptCs.Contracts/ICodeRewriter.cs
@@ -0,0 +1,7 @@
namespace ScriptCs.Contracts
{
public interface ICodeRewriter
{
FilePreProcessorResult Rewrite(FilePreProcessorResult code);
}
}
2 changes: 1 addition & 1 deletion src/ScriptCs.Contracts/IModule.cs
Expand Up @@ -2,6 +2,6 @@
{
public interface IModule
{
void Initialize(IModuleConfiguration config);
void Initialize(IServiceOverrides<IModuleConfiguration> config);
Copy link
Contributor

Choose a reason for hiding this comment

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

@jjrdk, this will break all existing implementers of modules. Why are you changing the signature?

}
}
7 changes: 7 additions & 0 deletions src/ScriptCs.Contracts/IModuleConfiguration.cs
@@ -1,5 +1,8 @@
namespace ScriptCs.Contracts
{
using System;
using System.Collections.Generic;

public interface IModuleConfiguration : IServiceOverrides<IModuleConfiguration>
{
bool Cache { get; }
Expand All @@ -9,5 +12,9 @@ public interface IModuleConfiguration : IServiceOverrides<IModuleConfiguration>
bool Repl { get; }

LogLevel LogLevel { get; }

IEnumerable<Type> CodeRewriters { get; }

IEnumerable<Type> LineProcessors { get; }
}
}
6 changes: 5 additions & 1 deletion src/ScriptCs.Contracts/IServiceOverrides.cs
@@ -1,6 +1,8 @@
namespace ScriptCs.Contracts
{
public interface IServiceOverrides { }
public interface IServiceOverrides
{
}

public interface IServiceOverrides<out TConfig> : IServiceOverrides where TConfig : IServiceOverrides<TConfig>
{
Expand Down Expand Up @@ -32,6 +34,8 @@ public interface IServiceOverrides<out TConfig> : IServiceOverrides where TConfi

TConfig LineProcessor<T>() where T : ILineProcessor;

TConfig CodeRewriter<T>() where T : ICodeRewriter;

TConfig Console<T>() where T : IConsole;

TConfig ScriptHostFactory<T>() where T : IScriptHostFactory;
Expand Down
5 changes: 1 addition & 4 deletions src/ScriptCs.Contracts/ScriptCs.Contracts.csproj
Expand Up @@ -12,11 +12,7 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyReferences.cs" />
Expand All @@ -30,6 +26,7 @@
<Compile Include="FilePreProcessorResult.cs" />
<Compile Include="IAssemblyResolver.cs" />
<Compile Include="IAssemblyUtility.cs" />
<Compile Include="ICodeRewriter.cs" />
<Compile Include="IConsole.cs" />
<Compile Include="IFileParser.cs" />
<Compile Include="IFilePreProcessor.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/ScriptCs.Core/FilePreProcessor.cs
Expand Up @@ -101,7 +101,7 @@ public virtual void ParseFile(string path, FileParserContext context)
context.LoadedScripts.Add(fullPath);

var scriptLines = _fileSystem.ReadFileLines(fullPath).ToList();

InsertLineDirective(fullPath, scriptLines);
InDirectory(fullPath, () => ParseScript(scriptLines, context));
}
Expand Down
30 changes: 30 additions & 0 deletions src/ScriptCs.Core/RewritingFilePreProcessor.cs
@@ -0,0 +1,30 @@
namespace ScriptCs
{
using System;
using System.Collections.Generic;
using System.Linq;

using Common.Logging;

using ScriptCs.Contracts;

public class RewritingFilePreProcessor : FilePreProcessor
{
private readonly IEnumerable<ICodeRewriter> _rewriters;

public RewritingFilePreProcessor(IFileSystem fileSystem, ILog logger, IEnumerable<ILineProcessor> lineProcessors, IEnumerable<ICodeRewriter> rewriters)
: base(fileSystem, logger, lineProcessors)
{
_rewriters = rewriters;
}

protected override FilePreProcessorResult Process(Action<FileParserContext> parseAction)
{
var result = base.Process(parseAction);

var rewrittenResult = _rewriters.Aggregate(result, (r, rewriter) => rewriter.Rewrite(r));

return rewrittenResult;
}
}
}
5 changes: 1 addition & 4 deletions src/ScriptCs.Core/ScriptCs.Core.csproj
Expand Up @@ -15,11 +15,7 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyResolver.cs" />
Expand All @@ -45,6 +41,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReferenceLineProcessor.cs" />
<Compile Include="Repl.cs" />
<Compile Include="RewritingFilePreProcessor.cs" />
<Compile Include="ScriptEnvironment.cs" />
<Compile Include="ScriptExecutorExtensions.cs" />
<Compile Include="ScriptHost.cs" />
Expand Down
6 changes: 3 additions & 3 deletions src/ScriptCs.Core/ScriptServices.cs
Expand Up @@ -7,11 +7,11 @@ public class ScriptServices
{
public ScriptServices(
IFileSystem fileSystem,
IPackageAssemblyResolver packageAssemblyResolver,
IPackageAssemblyResolver packageAssemblyResolver,
IScriptExecutor executor,
IScriptEngine engine,
IFilePreProcessor filePreProcessor,
IScriptPackResolver scriptPackResolver,
IScriptPackResolver scriptPackResolver,
IPackageInstaller packageInstaller,
IObjectSerializer objectSerializer,
ILog logger,
Expand Down Expand Up @@ -44,6 +44,6 @@ public class ScriptServices
public IFilePreProcessor FilePreProcessor { get; private set; }
public IConsole Console { get; private set; }
public IAssemblyResolver AssemblyResolver { get; private set; }
public IInstallationProvider InstallationProvider { get; private set; }
public IInstallationProvider InstallationProvider { get; private set; }
}
}
4 changes: 0 additions & 4 deletions src/ScriptCs.Engine.Roslyn/ScriptCs.Engine.Roslyn.csproj
Expand Up @@ -20,11 +20,7 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\common\CommonAssemblyInfo.cs">
Expand Down
4 changes: 2 additions & 2 deletions src/ScriptCs.Hosting/IScriptServicesBuilder.cs
Expand Up @@ -4,7 +4,7 @@ namespace ScriptCs.Hosting
{
public interface IScriptServicesBuilder : IServiceOverrides<IScriptServicesBuilder>
{
ScriptServices Build();
ScriptServices Build(IModuleConfiguration config);

IScriptServicesBuilder Cache(bool cache = true);

Expand All @@ -16,6 +16,6 @@ public interface IScriptServicesBuilder : IServiceOverrides<IScriptServicesBuild

IScriptServicesBuilder LogLevel(LogLevel level);

IScriptServicesBuilder LoadModules(string extension, params string[] moduleNames);
IModuleConfiguration LoadModules(string extension, params string[] moduleNames);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this change to return IModuleConfiguration? This breaks the fluent API.

}
}
17 changes: 10 additions & 7 deletions src/ScriptCs.Hosting/RuntimeServices.cs
Expand Up @@ -13,17 +13,19 @@ namespace ScriptCs.Hosting
public class RuntimeServices : ScriptServicesRegistration, IRuntimeServices
{
private readonly IList<Type> _lineProcessors;
private readonly IList<Type> _codeRewriters;
private readonly IConsole _console;
private readonly Type _scriptEngineType;
private readonly Type _scriptExecutorType;
private readonly bool _initDirectoryCatalog;
private readonly IInitializationServices _initializationServices;
private readonly string _scriptName;

public RuntimeServices(ILog logger, IDictionary<Type, object> overrides, IList<Type> lineProcessors, IConsole console, Type scriptEngineType, Type scriptExecutorType, bool initDirectoryCatalog, IInitializationServices initializationServices, string scriptName) :
public RuntimeServices(ILog logger, IDictionary<Type, object> overrides, IList<Type> lineProcessors, IList<Type> codeRewriters, IConsole console, Type scriptEngineType, Type scriptExecutorType, bool initDirectoryCatalog, IInitializationServices initializationServices, string scriptName) :
base(logger, overrides)
{
_lineProcessors = lineProcessors;
_codeRewriters = codeRewriters;
_console = console;
_scriptEngineType = scriptEngineType;
_scriptExecutorType = scriptExecutorType;
Expand All @@ -35,13 +37,14 @@ public class RuntimeServices : ScriptServicesRegistration, IRuntimeServices
protected override IContainer CreateContainer()
{
var builder = new ContainerBuilder();
this.Logger.Debug("Registering runtime services");
Logger.Debug("Registering runtime services");

builder.RegisterInstance<ILog>(this.Logger).Exported(x => x.As<ILog>());
builder.RegisterType(_scriptEngineType).As<IScriptEngine>().SingleInstance();
builder.RegisterType(_scriptExecutorType).As<IScriptExecutor>().SingleInstance();
builder.RegisterType<ScriptServices>().SingleInstance();

builder.RegisterTypes(_codeRewriters.ToArray()).As<ICodeRewriter>();
RegisterLineProcessors(builder);

RegisterOverrideOrDefault<IFileSystem>(builder, b => b.RegisterType<FileSystem>().As<IFileSystem>().SingleInstance());
Expand All @@ -50,7 +53,7 @@ protected override IContainer CreateContainer()
RegisterOverrideOrDefault<IPackageAssemblyResolver>(builder, b => b.RegisterType<PackageAssemblyResolver>().As<IPackageAssemblyResolver>().SingleInstance());
RegisterOverrideOrDefault<IAssemblyResolver>(builder, b => b.RegisterType<AssemblyResolver>().As<IAssemblyResolver>().SingleInstance());
RegisterOverrideOrDefault<IScriptHostFactory>(builder, b => b.RegisterType<ScriptHostFactory>().As<IScriptHostFactory>().SingleInstance());
RegisterOverrideOrDefault<IFilePreProcessor>(builder, b => b.RegisterType<FilePreProcessor>().As<IFilePreProcessor>().SingleInstance());
RegisterOverrideOrDefault<IFilePreProcessor>(builder, b => b.RegisterType<RewritingFilePreProcessor>().As<IFilePreProcessor>().SingleInstance());
RegisterOverrideOrDefault<IScriptPackResolver>(builder, b => b.RegisterType<ScriptPackResolver>().As<IScriptPackResolver>().SingleInstance());
RegisterOverrideOrDefault<IInstallationProvider>(builder, b => b.RegisterType<NugetInstallationProvider>().As<IInstallationProvider>().SingleInstance());
RegisterOverrideOrDefault<IPackageInstaller>(builder, b => b.RegisterType<PackageInstaller>().As<IPackageInstaller>().SingleInstance());
Expand All @@ -59,7 +62,7 @@ protected override IContainer CreateContainer()
RegisterOverrideOrDefault<IConsole>(builder, b => b.RegisterInstance(_console));

var assemblyResolver = _initializationServices.GetAssemblyResolver();

if (_initDirectoryCatalog)
{
var fileSystem = _initializationServices.GetFileSystem();
Expand All @@ -77,7 +80,7 @@ protected override IContainer CreateContainer()
catalog.Parts.ToList(); //force the Parts to be read
aggregateCatalog.Catalogs.Add(catalog);
}
catch(Exception ex)
catch (Exception ex)
{
assemblyLoadFailures = true;
Logger.DebugFormat("Failure loading assembly: {0}. Exception: {1}", assembly, ex.Message);
Expand All @@ -87,7 +90,7 @@ protected override IContainer CreateContainer()
{
if (_scriptName == null || _scriptName.Length == 0)
Logger.Warn("Some assemblies failed to load. Launch with '-repl -loglevel debug' to see the details");
else
else
Logger.Warn("Some assemblies failed to load. Launch with '-loglevel debug' to see the details");
}
builder.RegisterComposablePartCatalog(aggregateCatalog);
Expand All @@ -99,7 +102,7 @@ protected override IContainer CreateContainer()
private void RegisterLineProcessors(ContainerBuilder builder)
{
var loadProcessorType = _lineProcessors
.FirstOrDefault(x => typeof(ILoadLineProcessor).IsAssignableFrom(x))
.FirstOrDefault(x => typeof(ILoadLineProcessor).IsAssignableFrom(x))
?? typeof(LoadLineProcessor);

var usingProcessorType = _lineProcessors
Expand Down
4 changes: 0 additions & 4 deletions src/ScriptCs.Hosting/ScriptCs.Hosting.csproj
Expand Up @@ -30,11 +30,7 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\common\CommonAssemblyInfo.cs">
Expand Down
12 changes: 8 additions & 4 deletions src/ScriptCs.Hosting/ScriptServicesBuilder.cs
Expand Up @@ -6,6 +6,9 @@

namespace ScriptCs.Hosting
{
using System.Diagnostics;
using System.Linq;

public class ScriptServicesBuilder : ServiceOverrides<IScriptServicesBuilder>, IScriptServicesBuilder
{
private readonly IInitializationServices _initializationServices;
Expand All @@ -28,7 +31,7 @@ public ScriptServicesBuilder(IConsole console, ILog logger, IRuntimeServices run
_logger = logger;
}

public ScriptServices Build()
public ScriptServices Build(IModuleConfiguration configuration)
{
var defaultExecutorType = typeof(ScriptExecutor);
var defaultEngineType = _cache ? typeof(RoslynScriptPersistentEngine) : typeof(RoslynScriptEngine);
Expand All @@ -42,7 +45,7 @@ public ScriptServices Build()

if (_runtimeServices == null)
{
_runtimeServices = new RuntimeServices(_logger, Overrides, LineProcessors, _console,
_runtimeServices = new RuntimeServices(_logger, Overrides, configuration.LineProcessors.ToArray(), configuration.CodeRewriters.ToArray(), _console,
_scriptEngineType, _scriptExecutorType,
initDirectoryCatalog,
_initializationServices, _scriptName);
Expand All @@ -51,15 +54,16 @@ public ScriptServices Build()
return _runtimeServices.GetScriptServices();
}

public IScriptServicesBuilder LoadModules(string extension, params string[] moduleNames)
public IModuleConfiguration LoadModules(string extension, params string[] moduleNames)
{
var config = new ModuleConfiguration(_cache, _scriptName, _repl, _logLevel, Overrides);
var loader = _initializationServices.GetModuleLoader();

var fs = _initializationServices.GetFileSystem();
var folders = _debug ? new[] { fs.ModulesFolder, fs.CurrentDirectory } : new[] { fs.ModulesFolder };
loader.Load(config, folders, extension, moduleNames);
return this;

return config;
}

public IScriptServicesBuilder Cache(bool cache = true)
Expand Down
32 changes: 27 additions & 5 deletions src/ScriptCs.Hosting/ServiceOverrides.cs
Expand Up @@ -7,20 +7,36 @@ namespace ScriptCs.Hosting
public abstract class ServiceOverrides<TConfig> : IServiceOverrides<TConfig>
where TConfig : class, IServiceOverrides<TConfig>
{
protected readonly IList<Type> LineProcessors = new List<Type>();
private readonly IList<Type> lineProcessors = new List<Type>();
private readonly IList<Type> codeRewriters = new List<Type>();
private readonly TConfig _this;

public readonly IDictionary<Type, object> Overrides = new Dictionary<Type, object>();

private readonly TConfig _this;

protected ServiceOverrides()
{
_this = this as TConfig;
}

public IEnumerable<Type> LineProcessors
{
get
{
return lineProcessors;
}
}

public IEnumerable<Type> CodeRewriters
{
get
{
return codeRewriters;
}
}

public TConfig ScriptHostFactory<T>() where T : IScriptHostFactory
{
Overrides[typeof (IScriptHostFactory)] = typeof (T);
Overrides[typeof(IScriptHostFactory)] = typeof(T);
return _this;
}

Expand Down Expand Up @@ -115,7 +131,13 @@ protected ServiceOverrides(IDictionary<Type, object> overrides)

public TConfig LineProcessor<T>() where T : ILineProcessor
{
LineProcessors.Add(typeof(T));
this.lineProcessors.Add(typeof(T));
return _this;
}

public TConfig CodeRewriter<T>() where T : ICodeRewriter
{
this.codeRewriters.Add(typeof(T));
return _this;
}
}
Expand Down