Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

863 lines
28 KiB
C#

//
// System.Web.Services.Description.ProtocolImporter.cs
//
// Author:
// Tim Coleman (tim@timcoleman.com)
// Lluis Sanchez Gual (lluis@ximian.com)
//
// Copyright (C) Tim Coleman, 2002
//
//
// 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.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Collections;
using System.Configuration;
namespace System.Web.Services.Description {
public abstract class ProtocolImporter {
#region Fields
Binding binding;
string className;
CodeIdentifiers classNames;
CodeNamespace codeNamespace;
CodeTypeDeclaration codeTypeDeclaration;
Message inputMessage;
string methodName;
Operation operation;
OperationBinding operationBinding;
Message outputMessage;
Port port;
PortType portType;
Service service;
ServiceDescriptionImportWarnings warnings = (ServiceDescriptionImportWarnings)0;
ServiceDescriptionImporter descriptionImporter;
ImportInfo iinfo;
XmlSchemas xmlSchemas;
XmlSchemas soapSchemas;
#if NET_2_0
ArrayList asyncTypes = new ArrayList ();
#endif
#endregion // Fields
#region Constructors
protected ProtocolImporter ()
{
}
#endregion // Constructors
#region Properties
[MonoTODO]
public XmlSchemas AbstractSchemas {
get { return descriptionImporter.Schemas; }
}
public Binding Binding {
get { return binding; }
}
public string ClassName {
get { return className; }
}
public CodeIdentifiers ClassNames {
get { return classNames; }
}
public CodeNamespace CodeNamespace {
get { return codeNamespace; }
}
public CodeTypeDeclaration CodeTypeDeclaration {
get { return codeTypeDeclaration; }
}
[MonoTODO]
public XmlSchemas ConcreteSchemas {
get { return descriptionImporter.Schemas; }
}
public Message InputMessage {
get { return inputMessage; }
}
public string MethodName {
get { return methodName; }
}
public Operation Operation {
get { return operation; }
}
public OperationBinding OperationBinding {
get { return operationBinding; }
}
public Message OutputMessage {
get { return outputMessage; }
}
public Port Port {
get { return port; }
}
public PortType PortType {
get { return portType; }
}
public abstract string ProtocolName {
get;
}
public XmlSchemas Schemas {
get { return descriptionImporter.Schemas; }
}
public Service Service {
get { return service; }
}
public ServiceDescriptionCollection ServiceDescriptions {
get { return descriptionImporter.ServiceDescriptions; }
}
public ServiceDescriptionImportStyle Style {
get { return descriptionImporter.Style; }
}
public ServiceDescriptionImportWarnings Warnings {
get { return warnings; }
set { warnings = value; }
}
internal ImportInfo ImportInfo
{
get { return iinfo; }
}
internal XmlSchemas LiteralSchemas
{
get { return xmlSchemas; }
}
internal XmlSchemas EncodedSchemas
{
get { return soapSchemas; }
}
#if NET_2_0
internal CodeGenerationOptions CodeGenerationOptions {
get { return descriptionImporter.CodeGenerationOptions; }
}
internal CodeDomProvider CodeGenerator {
get { return descriptionImporter.CodeGenerator; }
}
internal ImportContext ImportContext {
get { return descriptionImporter.Context; }
}
#endif
#endregion // Properties
#region Methods
internal bool Import (ServiceDescriptionImporter descriptionImporter, CodeNamespace codeNamespace, ArrayList importInfo)
{
this.descriptionImporter = descriptionImporter;
this.classNames = new CodeIdentifiers();;
this.codeNamespace = codeNamespace;
warnings = (ServiceDescriptionImportWarnings) 0;
bool found = false;
ClasifySchemas (importInfo);
BeginNamespace ();
foreach (ImportInfo info in importInfo)
{
foreach (Service service in info.ServiceDescription.Services)
{
this.service = service;
int bindingCount = 0;
foreach (Port port in service.Ports)
{
binding = ServiceDescriptions.GetBinding (port.Binding);
if (IsBindingSupported ()) bindingCount ++;
}
foreach (Port port in service.Ports)
{
this.iinfo = info;
this.port = port;
binding = ServiceDescriptions.GetBinding (port.Binding);
if (!IsBindingSupported ()) continue;
found = true;
ImportPortBinding (bindingCount > 1);
}
}
}
if (!found)
{
// Looks like MS.NET generates classes for all bindings if
// no services are present
foreach (ImportInfo info in importInfo)
{
this.iinfo = info;
foreach (Binding b in info.ServiceDescription.Bindings)
{
this.binding = b;
this.service = null;
this.port = null;
if (!IsBindingSupported ()) continue;
found = true;
ImportPortBinding (true);
}
}
}
EndNamespace ();
if (!found) warnings = ServiceDescriptionImportWarnings.NoCodeGenerated;
return found;
}
void ImportPortBinding (bool multipleBindings)
{
if (port != null) {
if (multipleBindings) className = binding.Name;
else className = service.Name;
}
else
className = binding.Name;
className = classNames.AddUnique (CodeIdentifier.MakeValid (className), port);
className = className.Replace ("_x0020_", ""); // MS.NET seems to do this
try
{
portType = ServiceDescriptions.GetPortType (binding.Type);
if (portType == null) throw new Exception ("Port type not found: " + binding.Type);
CodeTypeDeclaration codeClass = BeginClass ();
codeTypeDeclaration = codeClass;
AddCodeType (codeClass, port != null ? port.Documentation : null);
codeClass.Attributes = MemberAttributes.Public;
if (service != null && service.Documentation != null && service.Documentation != "")
AddComments (codeClass, service.Documentation);
if (Style == ServiceDescriptionImportStyle.Client) {
CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Diagnostics.DebuggerStepThroughAttribute");
AddCustomAttribute (codeClass, att, true);
att = new CodeAttributeDeclaration ("System.ComponentModel.DesignerCategoryAttribute");
att.Arguments.Add (GetArg ("code"));
AddCustomAttribute (codeClass, att, true);
}
else
codeClass.TypeAttributes = System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.Public;
if (binding.Operations.Count == 0) {
warnings |= ServiceDescriptionImportWarnings.NoMethodsGenerated;
return;
}
foreach (OperationBinding oper in binding.Operations)
{
operationBinding = oper;
operation = FindPortOperation ();
if (operation == null)
throw new Exception ("Operation " + operationBinding.Name + " not found in portType " + PortType.Name);
inputMessage = null;
outputMessage = null;
foreach (OperationMessage omsg in operation.Messages)
{
Message msg = ServiceDescriptions.GetMessage (omsg.Message);
if (msg == null) throw new Exception ("Message not found: " + omsg.Message);
if (omsg is OperationInput)
inputMessage = msg;
else
outputMessage = msg;
}
CodeMemberMethod method = GenerateMethod ();
if (method != null)
{
methodName = method.Name;
if (operation.Documentation != null && operation.Documentation != "")
AddComments (method, operation.Documentation);
#if NET_2_0
if (Style == ServiceDescriptionImportStyle.Client)
AddAsyncMembers (method.Name, method);
#endif
}
}
#if NET_2_0
if (Style == ServiceDescriptionImportStyle.Client)
AddAsyncTypes ();
#endif
EndClass ();
}
catch (InvalidOperationException ex)
{
warnings |= ServiceDescriptionImportWarnings.NoCodeGenerated;
UnsupportedBindingWarning (ex.Message);
}
}
Operation FindPortOperation ()
{
string inMessage = null;
string outMessage = null;
int numMsg = 1;
if (operationBinding.Input == null) throw new InvalidOperationException ("Input operation binding not found");
inMessage = (operationBinding.Input.Name != null) ? operationBinding.Input.Name : operationBinding.Name;
if (operationBinding.Output != null) {
outMessage = (operationBinding.Output.Name != null) ? operationBinding.Output.Name : operationBinding.Name;
numMsg++;
}
string operName = operationBinding.Name;
Operation foundOper = null;
foreach (Operation oper in PortType.Operations)
{
if (oper.Name == operName)
{
int hits = 0;
foreach (OperationMessage omsg in oper.Messages)
{
if (omsg is OperationInput && GetOperMessageName (omsg, operName) == inMessage) hits++;
if (omsg is OperationOutput && GetOperMessageName (omsg, operName) == outMessage) hits++;
}
if (hits == numMsg) return oper;
foundOper = oper;
}
}
return foundOper;
}
string GetOperMessageName (OperationMessage msg, string operName)
{
if (msg.Name == null) return operName;
else return msg.Name;
}
internal void GenerateServiceUrl (string location, CodeStatementCollection stms)
{
if (ImportInfo.AppSettingUrlKey == null || ImportInfo.AppSettingUrlKey == string.Empty) {
if (location != null) {
CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
CodeAssignStatement cas = new CodeAssignStatement (ce, new CodePrimitiveExpression (location));
stms.Add (cas);
}
}
else
{
CodeExpression prop = new CodePropertyReferenceExpression (new CodeTypeReferenceExpression ("System.Configuration.ConfigurationSettings"), "AppSettings");
prop = new CodeIndexerExpression (prop, new CodePrimitiveExpression (ImportInfo.AppSettingUrlKey));
stms.Add (new CodeVariableDeclarationStatement (typeof(string), "urlSetting", prop));
CodeExpression urlSetting = new CodeVariableReferenceExpression ("urlSetting");
CodeExpression thisUrl = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
CodeStatement[] trueStms = new CodeStatement [1];
CodeExpression ce = urlSetting;
CodeExpression cond = new CodeBinaryOperatorExpression (urlSetting, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression (null));
if (ImportInfo.AppSettingBaseUrl != null)
ce = new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof(string)), "Concat", ce, new CodePrimitiveExpression (ImportInfo.AppSettingBaseUrl));
trueStms [0] = new CodeAssignStatement (thisUrl, ce);
if (location != null) {
CodeStatement[] falseStms = new CodeStatement [1];
falseStms [0] = new CodeAssignStatement (thisUrl, new CodePrimitiveExpression (location));
stms.Add (new CodeConditionStatement (cond, trueStms, falseStms));
}
else
stms.Add (new CodeConditionStatement (cond, trueStms));
}
}
void ClasifySchemas (ArrayList importInfo)
{
// I don't like this, but I could not find any other way of clasifying
// schemas between encoded and literal.
xmlSchemas = new XmlSchemas ();
soapSchemas = new XmlSchemas ();
foreach (ImportInfo info in importInfo)
{
foreach (Service service in info.ServiceDescription.Services)
{
foreach (Port port in service.Ports)
{
this.iinfo = info;
this.port = port;
binding = ServiceDescriptions.GetBinding (port.Binding);
if (binding == null) continue;
portType = ServiceDescriptions.GetPortType (binding.Type);
if (portType == null) continue;
foreach (OperationBinding oper in binding.Operations)
{
operationBinding = oper;
operation = FindPortOperation ();
if (operation == null) continue;
foreach (OperationMessage omsg in operation.Messages)
{
Message msg = ServiceDescriptions.GetMessage (omsg.Message);
if (msg == null) continue;
if (omsg is OperationInput)
inputMessage = msg;
else
outputMessage = msg;
}
if (GetMessageEncoding (oper.Input) == SoapBindingUse.Encoded)
AddMessageSchema (soapSchemas, oper.Input, inputMessage);
else
AddMessageSchema (xmlSchemas, oper.Input, inputMessage);
if (oper.Output != null) {
if (GetMessageEncoding (oper.Output) == SoapBindingUse.Encoded)
AddMessageSchema (soapSchemas, oper.Output, outputMessage);
else
AddMessageSchema (xmlSchemas, oper.Output, outputMessage);
}
}
}
}
}
XmlSchemas defaultList = xmlSchemas;
if (xmlSchemas.Count == 0 && soapSchemas.Count > 0)
defaultList = soapSchemas;
// Schemas not referenced by any message
foreach (XmlSchema sc in Schemas)
{
if (!soapSchemas.Contains (sc) && !xmlSchemas.Contains (sc)) {
if (ImportsEncodedNamespace (sc))
soapSchemas.Add (sc);
else
defaultList.Add (sc);
}
}
}
void AddMessageSchema (XmlSchemas schemas, MessageBinding mb, Message msg)
{
foreach (MessagePart part in msg.Parts)
{
if (part.Element != XmlQualifiedName.Empty)
AddIncludingSchema (schemas, part.Element.Namespace);
else if (part.Type != XmlQualifiedName.Empty)
AddIncludingSchema (schemas, part.Type.Namespace);
}
SoapBodyBinding sbb = mb.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
if (sbb != null) AddIncludingSchema (schemas, sbb.Namespace);
}
void AddIncludingSchema (XmlSchemas list, string ns)
{
foreach (XmlSchema sc in Schemas) {
if (sc.TargetNamespace == ns && !list.Contains (sc)) {
list.Add (sc);
foreach (XmlSchemaObject ob in sc.Includes) {
XmlSchemaImport import = ob as XmlSchemaImport;
if (import != null) AddIncludingSchema (list, import.Namespace);
}
}
}
}
SoapBindingUse GetMessageEncoding (MessageBinding mb)
{
SoapBodyBinding sbb = mb.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
if (sbb == null)
{
if (mb is InputBinding) return SoapBindingUse.Encoded;
else return SoapBindingUse.Literal;
}
else
if (sbb.Use == SoapBindingUse.Encoded) return SoapBindingUse.Encoded;
else
return SoapBindingUse.Literal;
}
bool ImportsEncodedNamespace (XmlSchema sc)
{
foreach (XmlSchemaObject ob in sc.Includes)
{
XmlSchemaImport import = ob as XmlSchemaImport;
if (import == null)
continue;
#if NET_2_0
if (import.Namespace == Soap11BindingExtensionReflector.EncodingNamespace
|| import.Namespace == Soap12BindingExtensionReflector.EncodingNamespace)
#else
if (import.Namespace == Soap11BindingExtensionReflector.EncodingNamespace)
#endif
return true;
}
return false;
}
#if NET_2_0
void AddAsyncTypes ()
{
foreach (CodeTypeDeclaration type in asyncTypes)
codeNamespace.Types.Add (type);
asyncTypes.Clear ();
}
void AddAsyncMembers (string messageName, CodeMemberMethod method)
{
CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
CodePrimitiveExpression enull = new CodePrimitiveExpression (null);
CodeMemberField codeField = new CodeMemberField (typeof(System.Threading.SendOrPostCallback), messageName + "OperationCompleted");
codeField.Attributes = MemberAttributes.Private;
CodeTypeDeclaration.Members.Add (codeField);
// Event arguments class
string argsClassName = classNames.AddUnique (messageName + "CompletedEventArgs", null);
CodeTypeDeclaration argsClass = new CodeTypeDeclaration (argsClassName);
argsClass.Attributes |= MemberAttributes.Public;
#if NET_2_0
argsClass.IsPartial = true;
#endif
argsClass.BaseTypes.Add (new CodeTypeReference ("System.ComponentModel.AsyncCompletedEventArgs"));
CodeMemberField resultsField = new CodeMemberField (typeof(object[]), "results");
resultsField.Attributes = MemberAttributes.Private;
argsClass.Members.Add (resultsField);
CodeConstructor cc = new CodeConstructor ();
cc.Attributes = MemberAttributes.Assembly;
cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object[]), "results"));
cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(System.Exception), "exception"));
cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(bool), "cancelled"));
cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "userState"));
cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("exception"));
cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("cancelled"));
cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("userState"));
CodeExpression thisResults = new CodeFieldReferenceExpression (ethis, "results");
cc.Statements.Add (new CodeAssignStatement (thisResults, new CodeVariableReferenceExpression ("results")));
argsClass.Members.Add (cc);
int ind = 0;
if (method.ReturnType.BaseType != "System.Void")
argsClass.Members.Add (CreateArgsProperty (method.ReturnType, "Result", ind++));
foreach (CodeParameterDeclarationExpression par in method.Parameters)
{
if (par.Direction == FieldDirection.Out || par.Direction == FieldDirection.Ref)
argsClass.Members.Add (CreateArgsProperty (par.Type, par.Name, ind++));
}
bool needsArgsClass = (ind > 0);
if (needsArgsClass)
asyncTypes.Add (argsClass);
else
argsClassName = "System.ComponentModel.AsyncCompletedEventArgs";
// Event delegate type
CodeTypeDelegate delegateType = new CodeTypeDelegate (messageName + "CompletedEventHandler");
delegateType.Attributes |= MemberAttributes.Public;
delegateType.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
delegateType.Parameters.Add (new CodeParameterDeclarationExpression (argsClassName, "args"));
// Event member
CodeMemberEvent codeEvent = new CodeMemberEvent ();
codeEvent.Attributes = codeEvent.Attributes & ~MemberAttributes.AccessMask | MemberAttributes.Public;
codeEvent.Name = messageName + "Completed";
codeEvent.Type = new CodeTypeReference (delegateType.Name);
CodeTypeDeclaration.Members.Add (codeEvent);
// Async method (without user state param)
CodeMemberMethod am = new CodeMemberMethod ();
am.Attributes = MemberAttributes.Public | MemberAttributes.Final;
am.Name = method.Name + "Async";
am.ReturnType = new CodeTypeReference (typeof(void));
CodeMethodInvokeExpression inv;
inv = new CodeMethodInvokeExpression (ethis, am.Name);
am.Statements.Add (inv);
// On...Completed method
CodeMemberMethod onCompleted = new CodeMemberMethod ();
onCompleted.Name = "On" + messageName + "Completed";
onCompleted.Attributes = MemberAttributes.Private | MemberAttributes.Final;
onCompleted.ReturnType = new CodeTypeReference (typeof(void));
onCompleted.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "arg"));
CodeConditionStatement anIf = new CodeConditionStatement ();
CodeExpression eventField = new CodeEventReferenceExpression (ethis, codeEvent.Name);
anIf.Condition = new CodeBinaryOperatorExpression (eventField, CodeBinaryOperatorType.IdentityInequality, enull);
CodeExpression castedArg = new CodeCastExpression (typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), new CodeVariableReferenceExpression ("arg"));
CodeStatement invokeArgs = new CodeVariableDeclarationStatement (typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), "invokeArgs", castedArg);
anIf.TrueStatements.Add (invokeArgs);
CodeDelegateInvokeExpression delegateInvoke = new CodeDelegateInvokeExpression ();
delegateInvoke.TargetObject = eventField;
delegateInvoke.Parameters.Add (ethis);
CodeObjectCreateExpression argsInstance = new CodeObjectCreateExpression (argsClassName);
CodeExpression invokeArgsVar = new CodeVariableReferenceExpression ("invokeArgs");
if (needsArgsClass) argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Results"));
argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Error"));
argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Cancelled"));
argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "UserState"));
delegateInvoke.Parameters.Add (argsInstance);
anIf.TrueStatements.Add (delegateInvoke);
onCompleted.Statements.Add (anIf);
// Async method
CodeMemberMethod asyncMethod = new CodeMemberMethod ();
asyncMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
asyncMethod.Name = method.Name + "Async";
asyncMethod.ReturnType = new CodeTypeReference (typeof(void));
CodeExpression delegateField = new CodeFieldReferenceExpression (ethis, codeField.Name);
anIf = new CodeConditionStatement ();
anIf.Condition = new CodeBinaryOperatorExpression (delegateField, CodeBinaryOperatorType.IdentityEquality, enull);;
CodeExpression delegateRef = new CodeMethodReferenceExpression (ethis, onCompleted.Name);
CodeExpression newDelegate = new CodeObjectCreateExpression (typeof(System.Threading.SendOrPostCallback), delegateRef);
CodeAssignStatement cas = new CodeAssignStatement (delegateField, newDelegate);
anIf.TrueStatements.Add (cas);
asyncMethod.Statements.Add (anIf);
CodeArrayCreateExpression paramsArray = new CodeArrayCreateExpression (typeof(object));
// Assign parameters
CodeIdentifiers paramsIds = new CodeIdentifiers ();
foreach (CodeParameterDeclarationExpression par in method.Parameters)
{
paramsIds.Add (par.Name, null);
if (par.Direction == FieldDirection.In || par.Direction == FieldDirection.Ref) {
CodeParameterDeclarationExpression inpar = new CodeParameterDeclarationExpression (par.Type, par.Name);
am.Parameters.Add (inpar);
asyncMethod.Parameters.Add (inpar);
inv.Parameters.Add (new CodeVariableReferenceExpression (par.Name));
paramsArray.Initializers.Add (new CodeVariableReferenceExpression (par.Name));
}
}
inv.Parameters.Add (enull);
string userStateName = paramsIds.AddUnique ("userState", null);
asyncMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), userStateName));
CodeExpression userStateVar = new CodeVariableReferenceExpression (userStateName);
asyncMethod.Statements.Add (BuildInvokeAsync (messageName, paramsArray, delegateField, userStateVar));
CodeTypeDeclaration.Members.Add (am);
CodeTypeDeclaration.Members.Add (asyncMethod);
CodeTypeDeclaration.Members.Add (onCompleted);
asyncTypes.Add (delegateType);
}
CodeMemberProperty CreateArgsProperty (CodeTypeReference type, string name, int ind)
{
CodeMemberProperty prop = new CodeMemberProperty ();
prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
prop.HasGet = true;
prop.HasSet = false;
prop.Name = name;
prop.Type = type;
CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
CodeExpression thisResults = new CodeFieldReferenceExpression (ethis, "results");
prop.GetStatements.Add (new CodeMethodInvokeExpression (ethis, "RaiseExceptionIfNecessary"));
CodeArrayIndexerExpression arrValue = new CodeArrayIndexerExpression (thisResults, new CodePrimitiveExpression (ind));
CodeExpression retval = new CodeCastExpression (type, arrValue);
prop.GetStatements.Add (new CodeMethodReturnStatement (retval));
return prop;
}
internal virtual CodeExpression BuildInvokeAsync (string messageName, CodeArrayCreateExpression paramsArray, CodeExpression delegateField, CodeExpression userStateVar)
{
CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
CodeMethodInvokeExpression inv2 = new CodeMethodInvokeExpression (ethis, "InvokeAsync");
inv2.Parameters.Add (new CodePrimitiveExpression (messageName));
inv2.Parameters.Add (paramsArray);
inv2.Parameters.Add (delegateField);
inv2.Parameters.Add (userStateVar);
return inv2;
}
#endif
[MonoTODO]
public void AddExtensionWarningComments (CodeCommentStatementCollection comments, ServiceDescriptionFormatExtensionCollection extensions)
{
throw new NotImplementedException ();
}
protected abstract CodeTypeDeclaration BeginClass ();
protected virtual void BeginNamespace ()
{
}
protected virtual void EndClass ()
{
}
protected virtual void EndNamespace ()
{
}
protected abstract CodeMemberMethod GenerateMethod ();
protected abstract bool IsBindingSupported ();
protected abstract bool IsOperationFlowSupported (OperationFlow flow);
[MonoTODO]
public Exception OperationBindingSyntaxException (string text)
{
throw new NotImplementedException ();
}
[MonoTODO]
public Exception OperationSyntaxException (string text)
{
throw new NotImplementedException ();
}
public void UnsupportedBindingWarning (string text)
{
warnings |= ServiceDescriptionImportWarnings.UnsupportedBindingsIgnored;
AddGlobalComments ("WARNING: Could not generate proxy for binding " + binding.Name + ". " + text);
}
public void UnsupportedOperationBindingWarning (string text)
{
warnings |= ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored;
AddGlobalComments ("WARNING: Could not generate operation binding " + OperationBinding.Name + ". " + text);
}
public void UnsupportedOperationWarning (string text)
{
warnings |= ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored;
AddGlobalComments ("WARNING: Could not generate operation " + Operation.Name + ". " + text);
}
void AddGlobalComments (string comments)
{
codeNamespace.Comments.Add (new CodeCommentStatement (comments, false));
}
void AddComments (CodeTypeMember member, string comments)
{
if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
}
void AddCodeType (CodeTypeDeclaration type, string comments)
{
AddComments (type, comments);
codeNamespace.Types.Add (type);
}
internal void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
{
if (att.Arguments.Count == 0 && !addIfNoParams) return;
if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
ctm.CustomAttributes.Add (att);
}
internal void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
{
if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
}
internal CodeAttributeArgument GetArg (string name, object value)
{
return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
}
internal CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
{
return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
}
internal CodeAttributeArgument GetArg (object value)
{
return new CodeAttributeArgument (new CodePrimitiveExpression(value));
}
internal CodeAttributeArgument GetTypeArg (string name, string typeName)
{
return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));
}
#endregion
}
}