Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
brunomlopes committed Aug 6, 2011
1 parent a0eec27 commit 715f015
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 135 deletions.
51 changes: 0 additions & 51 deletions src/Plugins/IronPython/CreatePartsFromTypes.cs

This file was deleted.

92 changes: 47 additions & 45 deletions src/Plugins/IronPython/ExtractTypesFromScript.cs
Original file line number Diff line number Diff line change
@@ -1,54 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using Core.Abstractions;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Runtime.Types;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.Scripting.Hosting;

namespace Plugins.IronPython
{
public class ExtractTypesFromScript
{
public class DefinedType
{
private readonly ScriptEngine _engine;
private readonly ObjectHandle _classHandle;
private ObjectHandle _instanceHandle;
private object _instance;

public DefinedType(ScriptEngine engine, string name, PythonType pythonType, ObjectHandle classHandle)
{
Name = name;
PythonType = pythonType;
_engine = engine;
_classHandle = classHandle;
}

public string Name { get; protected set; }
public PythonType PythonType { get; protected set; }
public Type Type { get { return PythonType; } }
public object Activator()
{
_instanceHandle = _engine.Operations.Invoke(_classHandle, new object[] {});
_instance = _engine.Operations.Unwrap<object>(_instanceHandle);
return _instance;
}

public void InvokeMethodWithArgument(string methodName, object argument)
{
_engine.Operations.InvokeMember(_instance, methodName, argument);
}
}
private readonly ScriptEngine _engine;

public ExtractTypesFromScript(ScriptEngine engine)
{
_engine = engine;
}

public IEnumerable<DefinedType> GetTypesFromScript(ScriptSource script)
public IEnumerable<IronPythonComposablePart> GetPartsFromScript(ScriptSource script)
{
return GetParts(GetTypesFromScript(script));
}

public IEnumerable<IronPythonTypeWrapper> GetTypesFromScript(ScriptSource script)
{
CompiledCode code = script.Compile();
var types = new[]
Expand All @@ -67,34 +43,60 @@ public IEnumerable<DefinedType> GetTypesFromScript(ScriptSource script)
{
scope.InjectType(type);
}

// "force" all classes to be new style classes
dynamic metaclass;
if(!scope.TryGetVariable("__metaclass__", out metaclass))
{
scope.SetVariable("__metaclass__", _engine.GetBuiltinModule().GetVariable("type"));
}


scope.SetVariable("clr", _engine.GetClrModule());
code.Execute(scope);

var pluginClasses = scope.GetItems()
.Where(kvp => kvp.Value is PythonType && !kvp.Key.StartsWith("__"))
.Select(kvp => new DefinedType(_engine, kvp.Key, kvp.Value, scope.GetVariableHandle(kvp.Key)))
//.Concat(scope.GetItems()
//.Where(kvp => kvp.Value is OldClass)
//.Select(kvp => new DefinedType()
//{
// Name = kvp.Key,
// PythonType = new PythonType((OldClass)kvp.Value).,
// Type = (OldClass)kvp.Value,
// Activator = () => _engine.Operations.Invoke(kvp.Value, new object[] { })
//})

//)
.Select(kvp => new IronPythonTypeWrapper(_engine, kvp.Key, kvp.Value, scope.GetVariableHandle(kvp.Key)))
.Where(kvp => !types.Contains(kvp.Type));

return pluginClasses;
}
public IEnumerable<IronPythonComposablePart> GetParts(IEnumerable<IronPythonTypeWrapper> types)
{
foreach (var definedType in types)
{
dynamic type = definedType.PythonType;
IEnumerable<object> exportObjects = new List();
IDictionary<string, object> importObjects = new Dictionary<string, object>();
PythonDictionary pImportObjects = null;

try
{
exportObjects = ((IEnumerable<object>)type.__exports__);
}
catch (RuntimeBinderException)
{
}
try
{
pImportObjects = type.__imports__;
importObjects = pImportObjects.ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value);
}
catch (RuntimeBinderException)
{
}

if (importObjects.Count + exportObjects.Count() == 0)
{
continue;
}

var exports = exportObjects.Cast<PythonType>().Select(o => (Type)o);
var imports =
importObjects.Keys
.Select(key => new KeyValuePair<string, Type>(key, (PythonType)importObjects[key]));
yield return new IronPythonComposablePart(definedType, exports, imports);
}
}
}
}
3 changes: 1 addition & 2 deletions src/Plugins/IronPython/IronPythonCommandsMefExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ private void ExportCommandsFromFilesIntoMef(IEnumerable<FileInfo> pythonFiles)

try
{
var types = new ExtractTypesFromScript(_engine).GetTypesFromScript(script);
var parts = new CreatePartsFromTypes().GetParts(types);
var parts = new ExtractTypesFromScript(_engine).GetPartsFromScript(script);

var batch = new CompositionBatch(parts, new ComposablePart[]{});
_mefContainer.Compose(batch);
Expand Down
30 changes: 5 additions & 25 deletions src/Plugins/IronPython/IronPythonComposablePart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,17 @@

namespace Plugins.IronPython
{
public class IronPythonContractBasedImportDefinition : ContractBasedImportDefinition
{
public string MethodName { get; private set; }

protected IronPythonContractBasedImportDefinition()
{
}

public IronPythonContractBasedImportDefinition(string methodName, string contractName,
string requiredTypeIdentity,
IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
ImportCardinality cardinality, bool isRecomposable,
bool isPrerequisite, CreationPolicy requiredCreationPolicy)
: base(
contractName, requiredTypeIdentity, requiredMetadata, cardinality, isRecomposable, isPrerequisite,
requiredCreationPolicy)
{
MethodName = methodName;
}
}
public class IronPythonComposablePart : ComposablePart
{
private readonly dynamic _instance;
private readonly Dictionary<string, ImportDefinition> _imports;
private readonly IList<ExportDefinition> _exports;
private ExtractTypesFromScript.DefinedType _definedType;
private readonly IronPythonTypeWrapper _typeWrapper;

public IronPythonComposablePart(ExtractTypesFromScript.DefinedType definedType, IEnumerable<Type> exports, IEnumerable<KeyValuePair<string, Type>> imports)
public IronPythonComposablePart(IronPythonTypeWrapper typeWrapper, IEnumerable<Type> exports, IEnumerable<KeyValuePair<string, Type>> imports)
{
_definedType = definedType;
_instance = definedType.Activator();
_typeWrapper = typeWrapper;
_instance = typeWrapper.Activator();
_exports = new List<ExportDefinition>(exports.Count());
_imports = new Dictionary<string, ImportDefinition>(imports.Count());
foreach (var export in exports)
Expand Down Expand Up @@ -86,7 +66,7 @@ public override void SetImport(ImportDefinition definition, IEnumerable<Export>
var importDefinition = definition as IronPythonContractBasedImportDefinition;
if (importDefinition == null)
throw new InvalidOperationException("ImportDefinition should have been an IronPythonContractBasedImportDefinition");
_definedType.InvokeMethodWithArgument(importDefinition.MethodName, exports.Select(e => e.Value).ToList());
_typeWrapper.InvokeMethodWithArgument(importDefinition.MethodName, exports.Select(e => e.Value).ToList());
}

public override IEnumerable<ExportDefinition> ExportDefinitions
Expand Down
24 changes: 24 additions & 0 deletions src/Plugins/IronPython/IronPythonContractBasedImportDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Primitives;

namespace Plugins.IronPython
{
public class IronPythonContractBasedImportDefinition : ContractBasedImportDefinition
{
public string MethodName { get; private set; }

public IronPythonContractBasedImportDefinition(string methodName, string contractName,
string requiredTypeIdentity,
IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
ImportCardinality cardinality, bool isRecomposable,
bool isPrerequisite, CreationPolicy requiredCreationPolicy)
: base(
contractName, requiredTypeIdentity, requiredMetadata, cardinality, isRecomposable, isPrerequisite,
requiredCreationPolicy)
{
MethodName = methodName;
}
}
}
38 changes: 38 additions & 0 deletions src/Plugins/IronPython/IronPythonTypeWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Runtime.Remoting;
using IronPython.Runtime.Types;
using Microsoft.Scripting.Hosting;

namespace Plugins.IronPython
{
public class IronPythonTypeWrapper
{
private readonly ScriptEngine _engine;
private readonly ObjectHandle _classHandle;
private ObjectHandle _instanceHandle;
private object _instance;

public IronPythonTypeWrapper(ScriptEngine engine, string name, PythonType pythonType, ObjectHandle classHandle)
{
Name = name;
PythonType = pythonType;
_engine = engine;
_classHandle = classHandle;
}

public string Name { get; private set; }
public PythonType PythonType { get; private set; }
public Type Type { get { return PythonType; } }
public object Activator()
{
_instanceHandle = _engine.Operations.Invoke(_classHandle, new object[] {});
_instance = _engine.Operations.Unwrap<object>(_instanceHandle);
return _instance;
}

public void InvokeMethodWithArgument(string methodName, object argument)
{
_engine.Operations.InvokeMember(_instance, methodName, argument);
}
}
}
3 changes: 2 additions & 1 deletion src/Plugins/Plugins.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@
<Compile Include="ExportLearnings.cs" />
<Compile Include="Google.cs" />
<Compile Include="IronPython\BasePythonItemSource.cs" />
<Compile Include="IronPython\CreatePartsFromTypes.cs" />
<Compile Include="IronPython\ExtractTypesFromScript.cs" />
<Compile Include="IronPython\IronPythonCommandsMefExport.cs" />
<Compile Include="IronPython\IronPythonComposablePart.cs" />
<Compile Include="IronPython\IronPythonContractBasedImportDefinition.cs" />
<Compile Include="IronPython\IronPythonTypeWrapper.cs" />
<Compile Include="IronPython\ScriptScopeExtensionMethods.cs" />
<Compile Include="Processes\CloseProcess.cs" />
<Compile Include="Processes\KillProcess.cs" />
Expand Down
14 changes: 3 additions & 11 deletions src/Tests/IronPythonSupportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ def GetAllItems(self):
var _engine = Python.CreateEngine();
var script = _engine.CreateScriptSourceFromString(pythonCode);
var typeExtractor = new ExtractTypesFromScript(_engine);
var types = typeExtractor.GetTypesFromScript(script).ToList();

var createExports = new CreatePartsFromTypes();
var exports = createExports.GetParts(types).ToList();
var exports = typeExtractor.GetPartsFromScript(script).ToList();

var container = new CompositionContainer();
var batch = new CompositionBatch(exports, new ComposablePart[] {});
Expand Down Expand Up @@ -84,10 +81,7 @@ def import_actions(self, actions):
var script = _engine.CreateScriptSourceFromString(pythonCode);

var typeExtractor = new ExtractTypesFromScript(_engine);
var types = typeExtractor.GetTypesFromScript(script).ToList();

var parts = new CreatePartsFromTypes();
var exports = parts.GetParts(types).ToList();
var exports = typeExtractor.GetPartsFromScript(script).ToList();

var container = new CompositionContainer(new TypeCatalog(typeof(MockExporter), typeof(MockImportActions)));

Expand Down Expand Up @@ -115,10 +109,8 @@ def GetAllItems(self):
var _engine = Python.CreateEngine();
var script = _engine.CreateScriptSourceFromString(pythonCode);
var typeExtractor = new ExtractTypesFromScript(_engine);
var types = typeExtractor.GetTypesFromScript(script).ToList();
var exports = typeExtractor.GetPartsFromScript(script).ToList();

var createExports = new CreatePartsFromTypes();
var exports = createExports.GetParts(types).ToList();
Assert.Equal(0, exports.Count());
}
}
Expand Down

0 comments on commit 715f015

Please sign in to comment.