Skip to content

Commit 1c2e39b

Browse files
author
Jett Jones
committed
support constructor arguments
1 parent dcf8e30 commit 1c2e39b

20 files changed

+224
-30
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
Debug
22
*.log
33
_Resharper.Sharp
4+
.node-gyp
5+
bindings.sln*
6+
ipch
7+
Release
8+
*\ipch
49
*.sdf
510
*.suo
611
*\bin\*
7-
*\obj\*
12+
*\obj\*

Sharp/Helpers.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "Helpers.h"
2+
#include "v8value.h"
3+
#include "MatchType.h"
4+
5+
using namespace System::Text;
6+
using namespace System::Collections::Generic;
7+
using namespace System::Reflection;
8+
9+
System::String^ Helpers::GetError(System::Exception^ e)
10+
{
11+
StringBuilder^ sb = gcnew StringBuilder();
12+
13+
while(e != nullptr)
14+
{
15+
sb->AppendLine(e->Message);
16+
sb->AppendLine("----------");
17+
e = e->InnerException;
18+
}
19+
20+
return sb->ToString();
21+
}
22+
23+
array<System::Object^>^ Helpers::ConvertArguments(const v8::Arguments& args, int startIndex, array<System::Reflection::ParameterInfo^>^ types)
24+
{
25+
List<System::Object^>^ argList = gcnew List<System::Object^>();
26+
if (args.Length() > startIndex)
27+
{
28+
for(int i=startIndex; i < args.Length(); i++)
29+
{
30+
argList->Add(v8sharp::V8Interop::FromV8(args[i]));
31+
}
32+
}
33+
34+
array<System::Object^>^ result = MatchType::AdjustArguments(argList->ToArray(), types);
35+
36+
return result;
37+
}

Sharp/Helpers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
#include <uv.h>
4+
#include <v8.h>
5+
#include <vcclr.h>
6+
#include <node.h>
7+
8+
class Helpers
9+
{
10+
public:
11+
static System::String^ GetError(System::Exception^ e);
12+
static array<System::Object^>^ ConvertArguments(const v8::Arguments & args, int startIndex, array<System::Reflection::ParameterInfo^>^ types);
13+
};

Sharp/Sharp.sln

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 11.00
3+
# Visual Studio 2010
4+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sharp", "Sharp.vcxproj", "{74153EEB-90DB-4E5B-AA58-2AD21AEDD3CD}"
5+
EndProject
6+
Global
7+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8+
Debug|Win32 = Debug|Win32
9+
Release|Win32 = Release|Win32
10+
EndGlobalSection
11+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
12+
{74153EEB-90DB-4E5B-AA58-2AD21AEDD3CD}.Debug|Win32.ActiveCfg = Debug|Win32
13+
{74153EEB-90DB-4E5B-AA58-2AD21AEDD3CD}.Debug|Win32.Build.0 = Debug|Win32
14+
{74153EEB-90DB-4E5B-AA58-2AD21AEDD3CD}.Release|Win32.ActiveCfg = Release|Win32
15+
{74153EEB-90DB-4E5B-AA58-2AD21AEDD3CD}.Release|Win32.Build.0 = Release|Win32
16+
EndGlobalSection
17+
GlobalSection(SolutionProperties) = preSolution
18+
HideSolutionNode = FALSE
19+
EndGlobalSection
20+
EndGlobal

Sharp/Sharp.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
</Link>
7272
</ItemDefinitionGroup>
7373
<ItemGroup>
74+
<ClCompile Include="Helpers.cpp" />
7475
<ClCompile Include="MatchType.cpp" />
7576
<ClCompile Include="SharpAddon.cpp">
7677
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
@@ -85,6 +86,7 @@
8586
<ClCompile Include="WrapInstance.cpp" />
8687
</ItemGroup>
8788
<ItemGroup>
89+
<ClInclude Include="Helpers.h" />
8890
<ClInclude Include="MatchType.h" />
8991
<ClInclude Include="SharpLibHelper.h" />
9092
<ClInclude Include="v8external.h" />

Sharp/Sharp.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
<ClCompile Include="WrapBase.cpp">
2828
<Filter>wrap</Filter>
2929
</ClCompile>
30+
<ClCompile Include="Helpers.cpp">
31+
<Filter>wrap</Filter>
32+
</ClCompile>
3033
</ItemGroup>
3134
<ItemGroup>
3235
<ClInclude Include="v8wrap.h">
@@ -54,6 +57,9 @@
5457
<ClInclude Include="WrapBase.h">
5558
<Filter>wrap</Filter>
5659
</ClInclude>
60+
<ClInclude Include="Helpers.h">
61+
<Filter>wrap</Filter>
62+
</ClInclude>
5763
</ItemGroup>
5864
<ItemGroup>
5965
<Filter Include="v8sharp">

Sharp/SharpLibHelper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ using namespace v8;
1414
System::Reflection::Assembly ^OnAssemblyResolve(System::Object ^obj, System::ResolveEventArgs ^args)
1515
{
1616
System::String ^path = System::Environment::CurrentDirectory;
17+
18+
Console::WriteLine("Resolving an assembly..." + path);
19+
1720
array<System::String^>^ assemblies =
1821
System::IO::Directory::GetFiles(path, "*.dll");
1922
for (long ii = 0; ii < assemblies->Length; ii++) {

Sharp/WrapAssembly.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "WrapAssembly.h"
22
#include "WrapInstance.h"
33
#include "v8value.h"
4+
#include "Helpers.h"
45

6+
using namespace System::Text;
57
using namespace System::Collections::Generic;
68
using namespace System::Reflection;
79
using namespace v8;
@@ -53,20 +55,43 @@ Handle<Value> WrapAssembly::CreateInstance(const Arguments& args)
5355
try
5456
{
5557
Type^ t = self->_assembly->GetType(path);
56-
ConstructorInfo^ zeroArg = t->GetConstructor(gcnew array<Type^>(0));
5758

58-
if (zeroArg == nullptr)
59+
if (t == nullptr)
5960
{
60-
throw gcnew System::NotSupportedException("Class: '" + path + "' does not have a zero-argument constructor");
61+
throw gcnew System::NotSupportedException("Class: '" + path + "' was not found");
6162
}
6263

63-
System::Object^ result = zeroArg->Invoke(gcnew array<System::Object^>(0));
64+
array<ConstructorInfo^>^ cInfoList = t->GetConstructors();
6465

66+
List<ConstructorInfo^>^ matches = gcnew List<ConstructorInfo^>();
67+
int otherArgCount = args.Length() - 1;
68+
for (int i = 0; i < cInfoList->Length; i++)
69+
{
70+
ConstructorInfo^ ci = cInfoList[i];
71+
array<System::Reflection::ParameterInfo^>^ params = ci->GetParameters();
72+
if (params->Length == otherArgCount)
73+
{
74+
matches->Add(ci);
75+
}
76+
}
77+
78+
if (matches->Count == 0)
79+
{
80+
throw gcnew System::NotSupportedException("Class: '" + path + "' does not have a constructor with " + otherArgCount + " arguments.");
81+
}
82+
else if (matches->Count > 1)
83+
{
84+
Console::WriteLine("Node-Sharp Warning: Constructor matching by length found multiple options.");
85+
}
86+
87+
array<System::Object^>^ argList = Helpers::ConvertArguments(args, 1, matches[0]->GetParameters());
88+
System::Object^ result = matches[0]->Invoke(argList);
89+
6590
return scope.Close(WrapInstance::New(t, result));
6691
}
6792
catch (System::Exception^ e)
6893
{
69-
v8::Handle<v8::Value> str = v8sharp::V8Interop::ToV8(e->Message);
94+
v8::Handle<v8::Value> str = v8sharp::V8Interop::ToV8(Helpers::GetError(e));
7095
v8::Handle<v8::String> err = v8::Handle<v8::String>::Cast(str);
7196

7297
return ThrowException(v8::Exception::Error(err));

Sharp/WrapInstance.cpp

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,12 @@
11
#include "WrapInstance.h"
22
#include "v8value.h"
33
#include "MatchType.h"
4+
#include "Helpers.h"
45

56
using namespace System::Collections::Generic;
67
using namespace System::Reflection;
78
using namespace v8;
89

9-
array<System::Object^>^ ConvertArguments(const Arguments& args, int startIndex, MethodInfo^ m)
10-
{
11-
List<System::Object^>^ argList = gcnew List<System::Object^>();
12-
if (args.Length() > startIndex)
13-
{
14-
for(int i=startIndex; i < args.Length(); i++)
15-
{
16-
argList->Add(v8sharp::V8Interop::FromV8(args[i]));
17-
}
18-
}
19-
20-
array<System::Object^>^ result = MatchType::AdjustArguments(argList->ToArray(), m->GetParameters());
21-
22-
return result;
23-
}
24-
2510
Handle<Value> WrapInstance::New(System::Type^ t, System::Object^ o)
2611
{
2712
HandleScope scope;
@@ -113,7 +98,7 @@ Handle<Value> WrapInstance::CallMethod(const Arguments& args)
11398
return ThrowException(v8::Exception::TypeError(
11499
v8::String::New("First argument must be a string, for method name.")));
115100
}
116-
101+
117102
System::String^ path = safe_cast<System::String^>(v8sharp::V8Interop::FromV8(args[0]));
118103

119104
HandleScope scope;
@@ -128,7 +113,7 @@ Handle<Value> WrapInstance::CallMethod(const Arguments& args)
128113
throw gcnew System::NotSupportedException(System::String::Format("Method {0} not found", path));
129114
}
130115

131-
array<System::Object^>^ argList = ConvertArguments(args, 1, m);
116+
array<System::Object^>^ argList = Helpers::ConvertArguments(args, 1, m->GetParameters());
132117

133118
System::Object^ r = m->Invoke(self->_instance, argList);
134119

@@ -138,9 +123,9 @@ Handle<Value> WrapInstance::CallMethod(const Arguments& args)
138123
}
139124
catch(System::Exception^ e)
140125
{
141-
v8::Handle<v8::Value> str = v8sharp::V8Interop::ToV8(e->Message);
126+
v8::Handle<v8::Value> str = v8sharp::V8Interop::ToV8(Helpers::GetError(e));
142127
v8::Handle<v8::String> err = v8::Handle<v8::String>::Cast(str);
143-
128+
144129
return ThrowException(v8::Exception::Error(err));
145130
}
146131
}
@@ -176,12 +161,12 @@ Handle<Value> WrapInstance::Async(const Arguments& args)
176161
MethodInfo^ m = self->_type->GetMethod(safe_cast<System::String^>(v8sharp::V8Interop::FromV8(path)));
177162
baton->method = m;
178163

179-
array<System::Object^>^ argList = ConvertArguments(args, 2, m);
164+
array<System::Object^>^ argList = Helpers::ConvertArguments(args, 2, m->GetParameters());
180165
baton->args = argList;
181166
}
182167
catch(System::Exception^ e)
183168
{
184-
v8::Handle<v8::Value> str = v8sharp::V8Interop::ToV8(e->Message);
169+
v8::Handle<v8::Value> str = v8sharp::V8Interop::ToV8(Helpers::GetError(e));
185170
v8::Handle<v8::String> err = v8::Handle<v8::String>::Cast(str);
186171

187172
return ThrowException(v8::Exception::Error(err));
@@ -207,7 +192,7 @@ void WrapInstance::StartAsync(uv_work_t* req)
207192
catch(System::Exception^ e)
208193
{
209194
baton->error = true;
210-
baton->error_message = e->Message;
195+
baton->error_message = Helpers::GetError(e);
211196
}
212197
}
213198

StubClass/Constructor.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace StubClass
5+
{
6+
public class Constructor
7+
{
8+
private readonly int _int;
9+
private readonly string _str;
10+
private readonly List<int> _array;
11+
12+
public Constructor()
13+
{
14+
_int = 0;
15+
_str = "";
16+
_array = new List<int>();
17+
}
18+
19+
public Constructor(int i, string s)
20+
{
21+
_int = i;
22+
_str = s;
23+
_array = new List<int>();
24+
}
25+
26+
public Constructor(int i, string s, int[] values )
27+
{
28+
_int = i;
29+
_str = s;
30+
_array = new List<int>(values);
31+
}
32+
33+
public Constructor(StubClass.ReturnValue value)
34+
{
35+
_int = value.IntValue;
36+
_str = value.StringValue;
37+
_array = new List<int>();
38+
}
39+
40+
public override string ToString()
41+
{
42+
return String.Format("[{0}, {1}, {2}]", _int, _str, String.Join(",", _array));
43+
}
44+
}
45+
}

StubClass/StubClass.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<Reference Include="System.Core" />
3636
</ItemGroup>
3737
<ItemGroup>
38+
<Compile Include="Constructor.cs" />
3839
<Compile Include="Input.cs" />
3940
<Compile Include="Output.cs" />
4041
<Compile Include="Properties\AssemblyInfo.cs" />

StubClass/StubClass.sln

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 11.00
3+
# Visual Studio 2010
4+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StubClass", "StubClass.csproj", "{A8548808-FD18-4AD4-9D0D-6CD94052E668}"
5+
EndProject
6+
Global
7+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8+
Debug|Any CPU = Debug|Any CPU
9+
Release|Any CPU = Release|Any CPU
10+
EndGlobalSection
11+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
12+
{A8548808-FD18-4AD4-9D0D-6CD94052E668}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13+
{A8548808-FD18-4AD4-9D0D-6CD94052E668}.Debug|Any CPU.Build.0 = Debug|Any CPU
14+
{A8548808-FD18-4AD4-9D0D-6CD94052E668}.Release|Any CPU.ActiveCfg = Release|Any CPU
15+
{A8548808-FD18-4AD4-9D0D-6CD94052E668}.Release|Any CPU.Build.0 = Release|Any CPU
16+
EndGlobalSection
17+
GlobalSection(SolutionProperties) = preSolution
18+
HideSolutionNode = FALSE
19+
EndGlobalSection
20+
EndGlobal

bin/Sharp.node

2.5 KB
Binary file not shown.

bin/StubClass.dll

512 Bytes
Binary file not shown.

bin/bit32.dll

4 KB
Binary file not shown.

bin/bit64.dll

3.5 KB
Binary file not shown.

bin/bitAny.dll

4 KB
Binary file not shown.

bin/bitRef.dll

4 KB
Binary file not shown.

bin/sharptest.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,11 @@ oc.async('ReturnList', function(e, d){
1818

1919
var ic = stub.new('StubClass.Input');
2020

21-
console.log('Object: ' + ic.call('AcceptObject', oc.call('ReturnObject')));
21+
console.log('Object: ' + ic.call('AcceptObject', oc.call('ReturnObject')));
22+
23+
// calling a constructor with parameters
24+
var str = stub.new('StubClass.Constructor', 4, 'string', [1,2,3]).call('ToString')
25+
console.log(str);
26+
27+
str = stub.new('StubClass.Constructor', oc.call('ReturnObject')).call('ToString')
28+
console.log(str);

bindings.gyp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'Sharp',
5+
'type': 'static_library',
6+
'sources': [ 'Sharp/MatchType.cpp',
7+
'Sharp/SharpAddon.cpp',
8+
'Sharp/SharpLibHelper.cpp',
9+
'Sharp/v8external.cpp',
10+
'Sharp/v8function.cpp',
11+
'Sharp/v8value.cpp',
12+
'Sharp/v8wrap.cpp',
13+
'Sharp/WrapAssembly.cpp',
14+
'Sharp/WrapBase.cpp',
15+
'Sharp/WrapInstance.cpp'
16+
] ,
17+
'libraries': ['-lm'],
18+
'conditions': [
19+
['OS=="win"', {
20+
'cflags': ['/clr']
21+
}]
22+
],
23+
}
24+
]
25+
}

0 commit comments

Comments
 (0)