Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
2010-03-04 Jonathan Pryor <jpryor@novell.com>
* Driver.cs, CommandLineOptions.cs: Remove Mono.GetOptions use and use
Mono.Options instead (as Mono.GetOptions will be removed).
* Makefile: Remove Mono.GetOptions.dll reference.
* svcutil.exe.sources: Add Options.cs to the build.
2010-01-28 Atsushi Enomoto <atsushi@ximian.com>
* Driver.cs, MoonlightChannelBaseExtension.cs, CommandLineOptions.cs:
Now that ServiceContractGenerator generates both sync and async
methods, it has to explicitly remove sync methods from moonlight
proxies since they are not supported.
Also now we can generate sync proxies for monotouch, so
differentiate them again to support sync proxy generation (if you
don't want to generate sync methods, just use -moonlight).
2009-12-18 Atsushi Enomoto <atsushi@ximian.com>
* MoonlightChannelBaseExtension.cs : do not remove base EventArgs.
2009-12-18 Atsushi Enomoto <atsushi@ximian.com>
* how-client-proxy-is-created.txt : brief summary of code generation
behavior (it is rather about ServiceContractGenerator, but would
rather fit here).
2009-12-18 Atsushi Enomoto <atsushi@ximian.com>
* Driver.cs, MoonlightChannelBaseExtension.cs, CommandLineOptions.cs:
Added event-based async generator support (/tcv:35).
Some refactoring on async method generation.
Removed IExtensibleDataObject usage in moonlight proxy.
Added notes on MT profile + sync impossibility (so far).
2009-09-30 Atsushi Enomoto <atsushi@ximian.com>
* Driver.cs, MoonlightChannelBaseExtension.cs, CommandLineOptions.cs:
add experimental -monotouch option to generate proxy that are based
on moonlight but for sync methods.
2009-09-30 Atsushi Enomoto <atsushi@ximian.com>
* MoonlightChannelBaseExtension.cs : add CreateChannel() override.
2009-08-10 Atsushi Enomoto <atsushi@ximian.com>
* MoonlightChannelBaseExtension.cs : fixed a couple of generated
code to compile on .NET (not in mcs yet; some nested generics bug).
2009-08-10 Atsushi Enomoto <atsushi@ximian.com>
* Driver.cs, CommandLineOptions.cs : add moonlight proxy generator
support.
* MoonlightChannelBaseExtension.cs : new, moonlight proxy generator.
Implemented as I[Service|Operation]ContractGenerationExtension.
* svcutil.exe.sources : add above.
2006-10-19 Ankit Jain <jankit@novell.com>
* Driver.cs: Try to use HTTP GET to get wsdl, if it fails then try
ws-mex.
* Makefile: Add reference to System.Web.Services.dll
2006-06-27 Ankit Jain <jankit@novell.com>
* Copy of client-proxy-generator.
* Driver.cs: Hacked to use fetch metadata from a url.
2006-04-14 Atsushi Enomoto <atsushi@ximian.com>
* README : added, as this tool exists only in mono.
2006-04-14 Atsushi Enomoto <atsushi@ximian.com>
* CommandLineOptions.cs : set "" for default Namespace value.
2006-04-14 Atsushi Enomoto <atsushi@ximian.com>
* CommandLineOptions.cs, Driver.cs, Makefile,
client-proxy-gen.exe.sources :
new files for convenient client proxy generator *from contract Type*.

View File

@@ -0,0 +1,196 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using Mono.Options;
[assembly: AssemblyTitle ("Mono service contract conversion tool")]
[assembly: AssemblyDescription ("")]
[assembly: AssemblyVersion ("0.1.0")]
[assembly: AssemblyCopyright ("Copyright (C) 2006 Novell, Inc.")]
namespace Mono.ServiceContractTool
{
public enum OutputType
{
None,
[EnumMember (Value = "code")]
Code,
[EnumMember (Value = "metadata")]
Metadata,
[EnumMember (Value = "xmlSerializer")]
XmlSerializer,
}
public class CommandLineOptions
{
public CommandLineOptions ()
{
options = CreateOptions ();
}
public bool Help, Usage, Version;
OptionSet options;
public OptionSet CreateOptions ()
{
return new OptionSet {
{ "a|async",
"Generate async methods.",
v => GenerateAsync = v != null },
{ "config=",
"Configuration file names to generate.",
v => ConfigFiles.AddRange (v.Split (',')) },
{ "i|internal",
"Generate types as internal.",
v => GenerateTypesAsInternal = v != null },
{ "l|language=",
"Specify target code {LANGUAGE}. Default is 'csharp'.",
v => Language = v },
{ "monotouch",
"Generate MonoTouch client. (This option may vanish)",
v => GenerateMonoTouchProxy = v != null },
{ "moonlight",
"Generate moonlight client. (This option may vanish)",
v => GenerateMoonlightProxy = v != null },
{ "n|namespace=",
"Code namespace name to generate.",
v => Namespace = v },
{ "noConfig",
"Do not generate config file.",
v => NoConfig = v != null },
{ "noLogo",
"Do not show tool logo.",
v => NoLogo = v != null },
{ "o|out=",
"Output code filename.",
v => OutputFilename = v },
{ "r|reference=",
"Referenced assembly files.",
v => ReferencedAssemblies.AddRange (v.Split (',')) },
{ "tcv|targetClientVersion:",
"Indicate target client version. Valid values:\n" +
" Version35",
v => {
if (v == null)
return;
switch (v.ToLowerInvariant ()) {
case "version35":
TargetClientVersion35 = true;
break;
}
} },
{ "tm|typedMessage",
"Generate typed messages.",
v => GenerateTypedMessages = v != null },
{ "usage",
"Show usage syntax and exit.",
v => Usage = v != null },
{ "V|version",
"Display version and licensing information.",
v=> Version = v != null },
{ "h|?|help",
"Show this help list.",
v => Help = v != null },
};
}
public void ProcessArgs (string[] args)
{
RemainingArguments = options.Parse (args);
}
public void DoHelp ()
{
ShowBanner ();
Console.WriteLine ();
DoUsage ();
Console.WriteLine ("Options:");
options.WriteOptionDescriptions (Console.Out);
Console.WriteLine ();
Console.WriteLine ("metadataPath : ws-mex file path.");
Console.WriteLine ("metadataUrl: URL to ws-mex");
Console.WriteLine ("assemblyPath: path to an assembly");
}
public void DoUsage ()
{
Console.WriteLine ("Usage: svcutil [options] [metadataPath* | metadataUrl* | assemblyPath*]");
}
public void DoVersion ()
{
ShowBanner ();
}
public void ShowBanner ()
{
Console.WriteLine ("Mono service contract conversion tool {0} - Copyright (C) 2006 Novell, Inc.",
Assembly.GetExecutingAssembly ().GetName ().Version);
}
public List<string> RemainingArguments;
//[Option ("Target directory to create files", 'd', "directory")]
public string TargetDirectory;
public string OutputFilename;
//[Option ("Target output type", 't', "target")]
public OutputType OutputType = OutputType.Code;
//[Option ("Validate all service endpoints", 'v', "validate")]
public bool Validate;
public List<string> ConfigFiles = new List<string> ();
// FIXME: support it
public bool ChannelInterface;
// FIXME: support it
public bool GenerateProxy;
public bool GenerateAsync;
public bool GenerateTypedMessages;
public bool TargetClientVersion35;
bool generate_moonlight_proxy, generate_monotouch_proxy;
public bool GenerateMoonlightProxy {
get { return generate_moonlight_proxy; }
set {
if (!value)
return;
generate_moonlight_proxy = true;
GenerateAsync = true;
}
}
public bool GenerateMonoTouchProxy {
// this is a hack. It does not differentiate from GenerateMoonlightProxy on getter.
get { return generate_monotouch_proxy; }
set {
if (!value)
return;
GenerateMoonlightProxy = true;
generate_monotouch_proxy = true;
}
}
public bool GenerateTypesAsInternal;
public bool NoConfig;
public string Language = "csharp";
public string Namespace = String.Empty;
public List<string> ReferencedAssemblies = new List<string> ();
public bool NoLogo;
}
}

263
mcs/tools/svcutil/Driver.cs Normal file
View File

@@ -0,0 +1,263 @@
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Web.Services;
using System.Web.Services.Discovery;
using System.Collections.Generic;
using System.Runtime.Serialization;
using WSServiceDescrition = System.Web.Services.Description.ServiceDescription;
namespace Mono.ServiceContractTool
{
public class Driver
{
public static void Main (string [] args)
{
new Driver ().Run (args);
}
CommandLineOptions co = new CommandLineOptions ();
ServiceContractGenerator generator;
CodeDomProvider code_provider;
void Run (string [] args)
{
co.ProcessArgs (args);
if (co.Usage) {
co.DoUsage ();
return;
}
if (co.Version) {
co.DoVersion ();
return;
}
if (co.Help || co.RemainingArguments.Count == 0) {
co.DoHelp ();
return;
}
if (!co.NoLogo)
co.ShowBanner ();
CodeCompileUnit ccu = new CodeCompileUnit ();
CodeNamespace cns = new CodeNamespace (co.Namespace);
ccu.Namespaces.Add (cns);
generator = new ServiceContractGenerator (ccu);
generator.Options = GetGenerationOption ();
generator.Options |=ServiceContractGenerationOptions.ChannelInterface;
code_provider = GetCodeProvider ();
MetadataSet metadata = null;
// For now only assemblyPath is supported.
foreach (string arg in co.RemainingArguments) {
if (!File.Exists (arg)) {
Uri uri = null;
if (Uri.TryCreate (arg, UriKind.Absolute, out uri)) {
metadata = ResolveWithDisco (arg);
if (metadata == null)
metadata = ResolveWithWSMex (arg);
continue;
}
} else {
FileInfo fi = new FileInfo (arg);
switch (fi.Extension) {
case ".exe":
case ".dll":
GenerateContractType (fi.FullName);
break;
default:
throw new NotSupportedException ("Not supported file extension: " + fi.Extension);
}
}
}
if (metadata != null)
{
List<IWsdlImportExtension> list = new List<IWsdlImportExtension> ();
list.Add (new TransportBindingElementImporter ());
//list.Add (new DataContractSerializerMessageContractImporter ());
list.Add (new XmlSerializerMessageContractImporter ());
//WsdlImporter importer = new WsdlImporter (metadata, null, list);
WsdlImporter importer = new WsdlImporter (metadata);
ServiceEndpointCollection endpoints = importer.ImportAllEndpoints ();
Collection<ContractDescription> contracts = new Collection<ContractDescription> ();
if (endpoints.Count > 0) {
foreach (var se in endpoints)
contracts.Add (se.Contract);
} else {
foreach (var cd in importer.ImportAllContracts ())
contracts.Add (cd);
}
Console.WriteLine ("Generating files..");
// FIXME: could better become IWsdlExportExtension
foreach (ContractDescription cd in contracts) {
if (co.GenerateMoonlightProxy) {
var moonctx = new MoonlightChannelBaseContext ();
cd.Behaviors.Add (new MoonlightChannelBaseContractExtension (moonctx, co.GenerateMonoTouchProxy));
foreach (var od in cd.Operations)
od.Behaviors.Add (new MoonlightChannelBaseOperationExtension (moonctx, co.GenerateMonoTouchProxy));
generator.GenerateServiceContractType (cd);
moonctx.Fixup ();
}
else
generator.GenerateServiceContractType (cd);
}
}
/*if (cns.Types.Count == 0) {
Console.Error.WriteLine ("Argument assemblies have no types.");
Environment.Exit (1);
}*/
//FIXME: Generate .config
Console.WriteLine (GetOutputFilename ());
using (TextWriter w = File.CreateText (GetOutputFilename ())) {
code_provider.GenerateCodeFromCompileUnit (ccu, w, null);
}
}
MetadataSet ResolveWithDisco (string url)
{
DiscoveryClientProtocol prot = null;
Console.WriteLine ("\nAttempting to download metadata from '{0}' using DISCO..", url);
try {
prot = new DiscoveryClientProtocol ();
prot.DiscoverAny (url);
prot.ResolveAll ();
} catch (Exception e) {
Console.WriteLine ("Disco failed for the url '{0}' with exception :\n {1}", url, e.Message);
return null;
}
if (prot.References.Count > 0)
{
Console.WriteLine ("Disco found documents at the following URLs:");
foreach (DiscoveryReference refe in prot.References.Values)
{
if (refe is ContractReference) Console.Write ("- WSDL document at ");
else if (refe is DiscoveryDocumentReference) Console.Write ("- DISCO document at ");
else Console.Write ("- Xml Schema at ");
Console.WriteLine (refe.Url);
}
} else {
Console.WriteLine ("Disco didn't find any document at the specified URL");
return null;
}
MetadataSet metadata = new MetadataSet ();
foreach (object o in prot.Documents.Values) {
if (o is WSServiceDescrition) {
metadata.MetadataSections.Add (
new MetadataSection (MetadataSection.ServiceDescriptionDialect, "", (WSServiceDescrition) o));
}
if (o is XmlSchema) {
metadata.MetadataSections.Add (
new MetadataSection (MetadataSection.XmlSchemaDialect, "", (XmlSchema) o));
}
}
return metadata;
}
MetadataSet ResolveWithWSMex (string url)
{
MetadataSet metadata = null;
try {
MetadataExchangeClient client = new MetadataExchangeClient (new EndpointAddress (url));
Console.WriteLine ("\nAttempting to download metadata from {0} using WS-MetadataExchange..", url);
metadata = client.GetMetadata ();
} catch (InvalidOperationException e) {
//MetadataExchangeClient wraps exceptions, thrown while
//fetching the metadata, in an InvalidOperationException
string msg;
if (e.InnerException == null)
msg = e.Message;
else
msg = e.InnerException.ToString ();
Console.WriteLine ("WS-MetadataExchange query failed for the url '{0}' with exception :\n {1}",
url, msg);
}
return metadata;
}
CodeDomProvider GetCodeProvider ()
{
switch (co.Language) {
case "csharp":
case "cs":
return new Microsoft.CSharp.CSharpCodeProvider ();
case "vb":
return new Microsoft.VisualBasic.VBCodeProvider ();
default:
throw new NotSupportedException ();
}
}
void GenerateContractType (string file)
{
Assembly ass = Assembly.LoadFile (file);
foreach (Module m in ass.GetModules ())
foreach (Type t in m.GetTypes ())
ProcessType (t);
}
void ProcessType (Type type)
{
object [] a = type.GetCustomAttributes (
typeof (ServiceContractAttribute), true);
if (a.Length > 0)
generator.GenerateServiceContractType (
ContractDescription.GetContract (type));
}
ServiceContractGenerationOptions GetGenerationOption ()
{
ServiceContractGenerationOptions go =
ServiceContractGenerationOptions.ClientClass;
if (co.GenerateAsync)
go |= ServiceContractGenerationOptions.AsynchronousMethods;
if (co.ChannelInterface)
go |= ServiceContractGenerationOptions.ChannelInterface;
if (co.GenerateTypesAsInternal)
go |= ServiceContractGenerationOptions.InternalTypes;
if (co.GenerateProxy)
go |= ServiceContractGenerationOptions.ClientClass;
if (co.GenerateTypedMessages)
go |= ServiceContractGenerationOptions.TypedMessages;
if ((co.TargetClientVersion35 && co.GenerateAsync) || co.GenerateMoonlightProxy)
go |= ServiceContractGenerationOptions.EventBasedAsynchronousMethods;
return go;
}
string GetOutputFilename ()
{
if (co.OutputFilename != null)
return co.OutputFilename;
return "output." + code_provider.FileExtension;
}
}
}

View File

@@ -0,0 +1,13 @@
thisdir = tools/svcutil
SUBDIRS =
include ../../build/rules.make
LOCAL_MCS_FLAGS = \
-r:System.Core.dll \
-r:System.Runtime.Serialization.dll \
-r:System.ServiceModel.dll \
-r:System.Web.Services.dll \
-r:System.Configuration.dll
PROGRAM = svcutil.exe
include ../../build/executable.make

View File

@@ -0,0 +1,443 @@
//
// MoonlightChannelBaseExtension.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2009 Novell, Inc. http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Threading;
namespace Mono.ServiceContractTool
{
class MoonlightChannelBaseContext
{
public MoonlightChannelBaseContractExtension Contract;
public List<MoonlightChannelBaseOperationExtension> Operations = new List<MoonlightChannelBaseOperationExtension> ();
public CodeTypeDeclaration ClientType { get; set; }
public CodeTypeDeclaration ChannelType { get; set; }
public void FindClientType (ServiceContractGenerationContext context)
{
var cd = context.Contract;
string name = cd.Name + "Client";
if (name [0] == 'I')
name = name.Substring (1);
foreach (CodeNamespace cns in context.ServiceContractGenerator.TargetCompileUnit.Namespaces)
foreach (CodeTypeDeclaration ct in cns.Types)
if (ct == context.ContractType)
foreach (CodeTypeDeclaration ct2 in cns.Types)
if (ct2.Name == name) {
ClientType = ct2;
return;
}
throw new Exception (String.Format ("Contract '{0}' not found", name));
}
public void Fixup ()
{
Contract.Fixup ();
foreach (var op in Operations)
op.Fixup ();
}
}
class MoonlightChannelBaseContractExtension : IContractBehavior, IServiceContractGenerationExtension
{
public MoonlightChannelBaseContractExtension (MoonlightChannelBaseContext mlContext, bool generateSync)
{
ml_context = mlContext;
generate_sync = generateSync;
}
MoonlightChannelBaseContext ml_context;
bool generate_sync;
// IContractBehavior
public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
throw new NotSupportedException ();
}
public void ApplyClientBehavior (
ContractDescription description,
ServiceEndpoint endpoint,
ClientRuntime proxy)
{
throw new NotSupportedException ();
}
public void ApplyDispatchBehavior (
ContractDescription description,
ServiceEndpoint endpoint,
DispatchRuntime dispatch)
{
throw new NotSupportedException ();
}
public void Validate (
ContractDescription description,
ServiceEndpoint endpoint)
{
throw new NotSupportedException ();
}
// IServiceContractGenerationExtensions
public void GenerateContract (
ServiceContractGenerationContext context)
{
this.context = context;
ml_context.Contract = this;
}
ServiceContractGenerationContext context;
public void Fixup ()
{
ContractDescription cd = context.Contract;
ml_context.FindClientType (context);
var parentClass = ml_context.ClientType;
if (!generate_sync)
EliminateSync ();
string name = cd.Name + "Channel";
if (name [0] == 'I')
name = name.Substring (1);
var gt = new CodeTypeReference (cd.Name);
var clientBaseType = new CodeTypeReference ("System.ServiceModel.ClientBase", gt);
// this omits namespace, but should compile
var channelBase = new CodeTypeReference ("ChannelBase", gt);
var type = new CodeTypeDeclaration (name);
parentClass.Members.Add (type);
type.BaseTypes.Add (channelBase);
type.BaseTypes.Add (new CodeTypeReference (cd.Name));
type.TypeAttributes |= TypeAttributes.NestedPrivate;
ml_context.ChannelType = type;
// .ctor(ClientBase<T> client)
var ctor = new CodeConstructor ();
ctor.Attributes = MemberAttributes.Public;
ctor.Parameters.Add (
new CodeParameterDeclarationExpression (
clientBaseType, "client"));
ctor.BaseConstructorArgs.Add (
new CodeArgumentReferenceExpression ("client"));
type.Members.Add (ctor);
// In Client type:
// protected override TChannel CreateChannel()
var creator = new CodeMemberMethod ();
creator.Name = "CreateChannel";
creator.Attributes = MemberAttributes.Family | MemberAttributes.Override;
creator.ReturnType = gt;
creator.Statements.Add (
new CodeMethodReturnStatement (
new CodeCastExpression (
gt,
new CodeObjectCreateExpression (
new CodeTypeReference (name),
new CodeThisReferenceExpression ()))));
parentClass.Members.Add (creator);
// clear IExtensibleDataObject. Since there is *no* way
// to identify the type of a TypeReference, I cannot do
// anything but this brutal removal.
// Also clear ExtensionDataObject members.
foreach (CodeNamespace cns in context.ServiceContractGenerator.TargetCompileUnit.Namespaces) {
foreach (CodeTypeDeclaration ct in cns.Types) {
if (!ShouldPreserveBaseTypes (ct))
ct.BaseTypes.Clear ();
CodeTypeMember cp = null, cf = null;
foreach (CodeTypeMember cm in ct.Members) {
if (cm is CodeMemberProperty && cm.Name == "ExtensionData")
cp = cm;
else if (cm is CodeMemberField && cm.Name == "extensionDataField")
cf = cm;
}
if (cf != null)
ct.Members.Remove (cf);
if (cp != null)
ct.Members.Remove (cp);
}
}
}
bool ShouldPreserveBaseTypes (CodeTypeDeclaration ct)
{
foreach (CodeTypeReference cr in ct.BaseTypes) {
if (cr.BaseType == "System.ServiceModel.ClientBase`1")
return true;
if (cr.BaseType == "System.ComponentModel.AsyncCompletedEventArgs")
return true;
}
return false;
}
void EliminateSync ()
{
var type = context.ContractType;
// remove such OperationContract methods that do not have AsyncPattern parameter. It is sort of hack as it does not check the value (it might be "false").
var l = new List<CodeMemberMethod> ();
foreach (CodeMemberMethod cm in type.Members) {
bool isOperation = false, isAsync = false;
foreach (CodeAttributeDeclaration att in cm.CustomAttributes) {
if (att.Name == "System.ServiceModel.OperationContractAttribute")
isOperation = true;
else
continue;
foreach (CodeAttributeArgument aa in att.Arguments) {
if (aa.Name == "AsyncPattern") {
isAsync = true;
break;
}
}
if (isAsync)
break;
}
if (isOperation && !isAsync)
l.Add (cm);
}
foreach (var cm in l)
type.Members.Remove (cm);
// remove corresponding client implementation methods.
// It is sort of hack as it only checks method and
// parameter names (ideally we want to check parameter
// types, but there is no way to compare
// CodeTypeReferences).
var lc = new List<CodeMemberMethod> ();
foreach (var cm_ in ml_context.ClientType.Members) {
var cm = cm_ as CodeMemberMethod;
if (cm == null)
continue;
foreach (var sm in l) {
if (cm.Name != sm.Name || cm.Parameters.Count != sm.Parameters.Count)
continue;
bool diff = false;
for (int i = 0; i < cm.Parameters.Count; i++) {
var cp = cm.Parameters [i];
var sp = sm.Parameters [i];
if (cp.Direction != sp.Direction || cp.Name != sp.Name) {
diff = true;
break;
}
}
if (diff)
continue;
lc.Add (cm);
break;
}
}
foreach (var cm in lc)
ml_context.ClientType.Members.Remove (cm);
}
}
class MoonlightChannelBaseOperationExtension : IOperationBehavior, IOperationContractGenerationExtension
{
public MoonlightChannelBaseOperationExtension (MoonlightChannelBaseContext mlContext, bool generateSync)
{
ml_context = mlContext;
generate_sync = generateSync;
}
MoonlightChannelBaseContext ml_context;
bool generate_sync;
// IOperationBehavior
public void AddBindingParameters (
OperationDescription description,
BindingParameterCollection parameters)
{
throw new NotSupportedException ();
}
public void ApplyDispatchBehavior (
OperationDescription description,
DispatchOperation dispatch)
{
throw new NotSupportedException ();
}
public void ApplyClientBehavior (
OperationDescription description,
ClientOperation proxy)
{
throw new NotSupportedException ();
}
public void Validate (
OperationDescription description)
{
throw new NotSupportedException ();
}
// IOperationContractGenerationContext
public void GenerateOperation (OperationContractGenerationContext context)
{
this.context = context;
ml_context.Operations.Add (this);
}
OperationContractGenerationContext context;
public void Fixup ()
{
if (generate_sync)
FixupSync ();
FixupAsync ();
}
void FixupSync ()
{
var type = ml_context.ChannelType;
var od = context.Operation;
// sync method implementation
CodeMemberMethod cm = new CodeMemberMethod ();
type.Members.Add (cm);
cm.Name = od.Name;
cm.Attributes = MemberAttributes.Public
| MemberAttributes.Final;
var inArgs = new List<CodeParameterDeclarationExpression > ();
var outArgs = new List<CodeParameterDeclarationExpression > ();
foreach (CodeParameterDeclarationExpression p in context.SyncMethod.Parameters) {
inArgs.Add (p);
cm.Parameters.Add (p);
}
cm.ReturnType = context.SyncMethod.ReturnType;
var argsDecl = new CodeVariableDeclarationStatement (
typeof (object []),
"args",
new CodeArrayCreateExpression (typeof (object), inArgs.ConvertAll<CodeExpression> (decl => new CodeArgumentReferenceExpression (decl.Name)).ToArray ()));
cm.Statements.Add (argsDecl);
var args = new List<CodeExpression> ();
args.Add (new CodePrimitiveExpression (od.Name));
args.Add (new CodeVariableReferenceExpression ("args"));
CodeExpression call = new CodeMethodInvokeExpression (
new CodeBaseReferenceExpression (),
"Invoke",
args.ToArray ());
if (cm.ReturnType.BaseType == "System.Void")
cm.Statements.Add (new CodeExpressionStatement (call));
else
cm.Statements.Add (new CodeMethodReturnStatement (new CodeCastExpression (context.SyncMethod.ReturnType, call)));
}
public void FixupAsync ()
{
var type = ml_context.ChannelType;
var od = context.Operation;
var baseExpr = new CodeBaseReferenceExpression ();
var asyncResultType = new CodeTypeReference (typeof (IAsyncResult));
// BeginXxx() implementation
CodeMemberMethod cm = new CodeMemberMethod () {
Name = "Begin" + od.Name,
Attributes = MemberAttributes.Public | MemberAttributes.Final,
ReturnType = asyncResultType
};
type.Members.Add (cm);
var inArgs = new List<CodeParameterDeclarationExpression > ();
foreach (CodeParameterDeclarationExpression p in context.BeginMethod.Parameters) {
inArgs.Add (p);
cm.Parameters.Add (p);
}
inArgs.RemoveAt (inArgs.Count - 1);
inArgs.RemoveAt (inArgs.Count - 1);
var call = new CodeMethodInvokeExpression (
baseExpr,
"BeginInvoke",
new CodePrimitiveExpression (od.Name),
new CodeArrayCreateExpression (typeof (object), inArgs.ConvertAll<CodeExpression> (decl => new CodeArgumentReferenceExpression (decl.Name)).ToArray ()),
new CodeArgumentReferenceExpression ("asyncCallback"),
new CodeArgumentReferenceExpression ("userState"));
cm.Statements.Add (new CodeMethodReturnStatement (call));
// EndXxx() implementation
cm = new CodeMemberMethod () {
Name = "End" + od.Name,
Attributes = MemberAttributes.Public | MemberAttributes.Final,
ReturnType = context.EndMethod.ReturnType };
type.Members.Add (cm);
AddMethodParam (cm, typeof (IAsyncResult), "result");
var outArgs = new List<CodeParameterDeclarationExpression > ();
string resultArgName = "result";
var argsDecl = new CodeVariableDeclarationStatement (
typeof (object []),
"args",
new CodeArrayCreateExpression (typeof (object), new CodePrimitiveExpression (outArgs.Count)));
cm.Statements.Add (argsDecl);
var ret = new CodeMethodInvokeExpression (
baseExpr,
"EndInvoke",
new CodePrimitiveExpression (od.Name),
new CodeVariableReferenceExpression ("args"),
new CodeArgumentReferenceExpression (resultArgName));
if (cm.ReturnType.BaseType == "System.Void")
cm.Statements.Add (new CodeExpressionStatement (ret));
else
cm.Statements.Add (new CodeMethodReturnStatement (new CodeCastExpression (context.EndMethod.ReturnType, ret)));
}
void AddMethodParam (CodeMemberMethod cm, Type type, string name)
{
cm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (type), name));
}
}
}

View File

@@ -0,0 +1,5 @@
../../class/Mono.Options/Mono.Options/Options.cs
Driver.cs
CommandLineOptions.cs
MoonlightChannelBaseExtension.cs