From 816d405060b4c6c3206643793c63391885301c1a Mon Sep 17 00:00:00 2001 From: Alxandr Date: Fri, 24 Jul 2015 02:15:24 +0200 Subject: [PATCH] add constructors --- sample/NativeSample/Class1.cs | 11 +++ .../NativeGenerator.cs | 86 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/sample/NativeSample/Class1.cs b/sample/NativeSample/Class1.cs index 30735a1..a4dca14 100644 --- a/sample/NativeSample/Class1.cs +++ b/sample/NativeSample/Class1.cs @@ -1,10 +1,21 @@ using System.Runtime.InteropServices; +using Microsoft.Framework.Runtime; using YoloDev.Dnx.NativeUtils; namespace NativeSample { + abstract class FooBar : NativeMethods { + public class TestAttribute : System.Attribute {} + readonly IRuntimeEnvironment _env; + + [Test] + public FooBar(IRuntimeEnvironment env) + { + _env = env; + } + [NativeMethod("somelib", CallingConvention.Cdecl, BestFitMapping = false)] public abstract void Test(); diff --git a/src/YoloDev.Dnx.NativeUtils.Generator/NativeGenerator.cs b/src/YoloDev.Dnx.NativeUtils.Generator/NativeGenerator.cs index 6d1947b..6187e90 100644 --- a/src/YoloDev.Dnx.NativeUtils.Generator/NativeGenerator.cs +++ b/src/YoloDev.Dnx.NativeUtils.Generator/NativeGenerator.cs @@ -31,6 +31,11 @@ public NativeGenerator(NativeModel api, Compilation compilation) SyntaxTree Generate() { + foreach (var ctor in _api.Symbol.Constructors) + { + GenerateCtor(ctor); + } + foreach (var method in _api.Methods) { GenerateMethod(method); @@ -40,6 +45,64 @@ SyntaxTree Generate() .WithMembers(new SyntaxList().Add(_ns.AddMembers(_class.AddMembers(_members.ToArray())))).NormalizeWhitespace()); } + void GenerateCtor(IMethodSymbol ctor) + { + var syntax = SyntaxFactory.ConstructorDeclaration(_class.Identifier) + .WithModifiers(GetModifiers(ctor.DeclaredAccessibility)) + .WithBody(SyntaxFactory.Block()) + .AddAttributeLists(SyntaxFactory.AttributeList().AddAttributes(ctor.GetAttributes().Select(RecreateAttribute).ToArray())); + + var parameters = new List (); + var arguments = new List (); + + foreach (var p in ctor.Parameters) + { + var identifier = SyntaxFactory.Identifier(p.Name); + var type = SyntaxFactory.ParseTypeName(p.Type.ToDisplayString()); + var parameter = SyntaxFactory.Parameter(identifier).WithType(type); + var argument = SyntaxFactory.Argument(SyntaxFactory.IdentifierName(identifier)); + + parameters.Add(parameter); + arguments.Add(argument); + } + + syntax = syntax + .AddParameterListParameters(parameters.ToArray()) + .WithInitializer( + SyntaxFactory.ConstructorInitializer( + SyntaxKind.BaseConstructorInitializer, + SyntaxFactory.ArgumentList().AddArguments(arguments.ToArray()) + ) + ); + + _members.Add(syntax); + } + + static SyntaxTokenList GetModifiers(Accessibility accessibility) + { + var tokens = new List (); + switch (accessibility) + { + case Accessibility.Public: + tokens.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); break; + case Accessibility.Private: + tokens.Add(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)); break; + case Accessibility.Protected: + tokens.Add(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword)); break; + case Accessibility.Internal: + tokens.Add(SyntaxFactory.Token(SyntaxKind.InternalKeyword)); break; + case Accessibility.ProtectedAndInternal: + tokens.Add(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword)); + tokens.Add(SyntaxFactory.Token(SyntaxKind.InternalKeyword)); break; + default: + // CommonAccessibility.ProtectedOrInternal can't be expressed in C# + // but is legal in metadata. + throw new NotSupportedException(); + } + + return SyntaxFactory.TokenList(tokens); + } + void GenerateMethod(IMethodSymbol method) { var name = method.Name; @@ -164,6 +227,29 @@ static MethodDeclarationSyntax CreateMethod(IMethodSymbol baseSymbol, DelegateDe return method; } + static AttributeSyntax RecreateAttribute(AttributeData attr) + { + var args = new List(); + + foreach (var ctorArg in attr.ConstructorArguments) + { + var arg = SyntaxFactory.AttributeArgument(SyntaxFactory.ParseExpression(ctorArg.ToCSharpString())); + args.Add(arg); + } + + foreach (var namedArg in attr.NamedArguments) + { + var arg = SyntaxFactory.AttributeArgument(SyntaxFactory.ParseExpression(namedArg.Value.ToCSharpString())) + .WithNameEquals(SyntaxFactory.NameEquals(namedArg.Key)); + args.Add(arg); + } + + var syntax = SyntaxFactory.Attribute(SyntaxFactory.ParseName(attr.AttributeClass.ToDisplayString())) + .AddArgumentListArguments(args.ToArray()); + + return syntax; + } + static ExpressionSyntax InstansiateAttribute(AttributeData attr) { var expr = SyntaxFactory.ObjectCreationExpression(SyntaxFactory.ParseTypeName(attr.AttributeClass.ToDisplayString()));