CallSignature.cs :  » Script » IronRuby » Microsoft » Scripting » Actions » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Script » IronRuby 
IronRuby » Microsoft » Scripting » Actions » CallSignature.cs
/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/

#if !CLR2
using System.Linq.Expressions;
#else
using Microsoft.Scripting.Ast;
#endif

using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Scripting.Utils;
using Microsoft.Contracts;
using Microsoft.Scripting.Generation;
using AstUtilsMicrosoft.Scripting.Ast.Utils;

namespace Microsoft.Scripting.Actions{
    /// <summary>
    /// Richly represents the signature of a callsite.
    /// </summary>
    public struct CallSignature : IEquatable<CallSignature> {
        // TODO: invariant _infos != null ==> _argumentCount == _infos.Length
        
        /// <summary>
        /// Array of additional meta information about the arguments, such as named arguments.
        /// Null for a simple signature that's just an expression list. eg: foo(a*b,c,d)
        /// </summary>
        private readonly Argument[] _infos;

        /// <summary>
        /// Number of arguments in the signature.
        /// </summary>
        private readonly int _argumentCount;

        /// <summary>
        /// All arguments are unnamed and matched by position. 
        /// </summary>
        public bool IsSimple {
            get { return _infos == null; }
        }

        public int ArgumentCount {
            get {
                Debug.Assert(_infos == null || _infos.Length == _argumentCount);
                return _argumentCount; 
            }
        }

        #region Construction

        public CallSignature(CallSignature signature) {
            _infos = signature.GetArgumentInfos();
            _argumentCount = signature._argumentCount;
        }
        
        public CallSignature(int argumentCount) {
            ContractUtils.Requires(argumentCount >= 0, "argumentCount");
            _argumentCount = argumentCount;
            _infos = null;
        }

        public CallSignature(params Argument[] infos) {
            bool simple = true;

            if (infos != null) {
                _argumentCount = infos.Length;
                for (int i = 0; i < infos.Length; i++) {
                    if (infos[i].Kind != ArgumentType.Simple) {
                        simple = false;
                        break;
                    }
                }
            } else {
                _argumentCount = 0;
            }

            _infos = (!simple) ? infos : null;
        }

        public CallSignature(params ArgumentType[] kinds) {
            bool simple = true;

            if (kinds != null) {
                _argumentCount = kinds.Length;
                for (int i = 0; i < kinds.Length; i++) {
                    if (kinds[i] != ArgumentType.Simple) {
                        simple = false;
                        break;
                    }
                }
            } else {
                _argumentCount = 0;
            }

            if (!simple) {
                _infos = new Argument[kinds.Length];
                for (int i = 0; i < kinds.Length; i++) {
                    _infos[i] = new Argument(kinds[i]);
                }
            } else {
                _infos = null;
            }
        }

        #endregion

        #region IEquatable<CallSignature> Members

        [StateIndependent]
        public bool Equals(CallSignature other) {
            if (_infos == null) {
                return other._infos == null && other._argumentCount == _argumentCount;
            } else if (other._infos == null) {
                return false;
            }

            if (_infos.Length != other._infos.Length) return false;

            for (int i = 0; i < _infos.Length; i++) {
                if (!_infos[i].Equals(other._infos[i])) return false;
            }

            return true;
        }

        #endregion

        #region Overrides

        public override bool Equals(object obj) {
            return obj is CallSignature && Equals((CallSignature)obj);
        }

        public static bool operator ==(CallSignature left, CallSignature right) {
            return left.Equals(right);
        }

        public static bool operator !=(CallSignature left, CallSignature right) {
            return !left.Equals(right);
        }

        public override string ToString() {
            if (_infos == null) {
                return "Simple";
            }
            
            StringBuilder sb = new StringBuilder("(");
            for (int i = 0; i < _infos.Length; i++) {
                if (i > 0) {
                    sb.Append(", ");
                }
                sb.Append(_infos[i].ToString());
            }
            sb.Append(")");
            return sb.ToString();
        }

        public override int GetHashCode() {
            int h = 6551;
            if (_infos != null) {
                foreach (Argument info in _infos) {
                    h ^= (h << 5) ^ info.GetHashCode();
                }
            }
            return h;
        }

        #endregion

        #region Helpers

        public Argument[] GetArgumentInfos() {
            return (_infos != null) ? ArrayUtils.Copy(_infos) : CompilerHelpers.MakeRepeatedArray(Argument.Simple, _argumentCount);
        }

        public CallSignature InsertArgument(Argument info) {
            return InsertArgumentAt(0, info);
        }

        public CallSignature InsertArgumentAt(int index, Argument info) {
            if (this.IsSimple) {
                if (info.IsSimple) {
                    return new CallSignature(_argumentCount + 1);
                }
                
                return new CallSignature(ArrayUtils.InsertAt(GetArgumentInfos(), index, info));
            }

            return new CallSignature(ArrayUtils.InsertAt(_infos, index, info));
        }

        public CallSignature RemoveFirstArgument() {
            return RemoveArgumentAt(0);
        }

        public CallSignature RemoveArgumentAt(int index) {
            if (_argumentCount == 0) {
                throw new InvalidOperationException();
            }

            if (IsSimple) {
                return new CallSignature(_argumentCount - 1);
            }

            return new CallSignature(ArrayUtils.RemoveAt(_infos, index));
        }

        public int IndexOf(ArgumentType kind) {
            if (_infos == null) {
                return (kind == ArgumentType.Simple && _argumentCount > 0) ? 0 : -1;
            }

            for (int i = 0; i < _infos.Length; i++) {
                if (_infos[i].Kind == kind) {
                    return i;
                }
            }
            return -1;
        }

        public bool HasDictionaryArgument() {
            return IndexOf(ArgumentType.Dictionary) > -1;
        }

        public bool HasInstanceArgument() {
            return IndexOf(ArgumentType.Instance) > -1;
        }

        public bool HasListArgument() {
            return IndexOf(ArgumentType.List) > -1;
        }

        internal bool HasNamedArgument() {
            return IndexOf(ArgumentType.Named) > -1;
        }

        /// <summary>
        /// True if the OldCallAction includes an ArgumentInfo of ArgumentKind.Dictionary or ArgumentKind.Named.
        /// </summary>
        public bool HasKeywordArgument() {
            if (_infos != null) {
                foreach (Argument info in _infos) {
                    if (info.Kind == ArgumentType.Dictionary || info.Kind == ArgumentType.Named) {
                        return true;
                    }
                }
            }
            return false;
        }
        
        public ArgumentType GetArgumentKind(int index) {
            // TODO: Contract.Requires(index >= 0 && index < _argumentCount, "index");
            return _infos != null ? _infos[index].Kind : ArgumentType.Simple;
        }

        public string GetArgumentName(int index) {
            ContractUtils.Requires(index >= 0 && index < _argumentCount);
            return _infos != null ? _infos[index].Name : null;
        }

        /// <summary>
        /// Gets the number of positional arguments the user provided at the call site.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        public int GetProvidedPositionalArgumentCount() {
            int result = _argumentCount;

            if (_infos != null) {
                for (int i = 0; i < _infos.Length; i++) {
                    ArgumentType kind = _infos[i].Kind;

                    if (kind == ArgumentType.Dictionary || kind == ArgumentType.List || kind == ArgumentType.Named) {
                        result--;
                    }
                }
            }

            return result;
        }

        public string[] GetArgumentNames() {
            if (_infos == null) {
                return ArrayUtils.EmptyStrings;
            }

            List<string> result = new List<string>();
            foreach (Argument info in _infos) {
                if (info.Name != null) {
                    result.Add(info.Name);
                }
            }

            return result.ToArray();
        }

        public Expression CreateExpression() {            
            if (_infos == null) {
                return Expression.New(
                    typeof(CallSignature).GetConstructor(new Type[] { typeof(int) }),
                    AstUtils.Constant(ArgumentCount)
                );
            } else {
                Expression[] args = new Expression[_infos.Length];
                for (int i = 0; i < args.Length; i++) {
                    args[i] = _infos[i].CreateExpression();
                }
                return Expression.New(
                    typeof(CallSignature).GetConstructor(new Type[] { typeof(Argument[]) }), 
                    Expression.NewArrayInit(typeof(Argument), args)
                );
            }
        }

        #endregion
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.