public override void Visit(IVectorLength length)
 {
     if (NameTable.ContainsKey(length.Vector))
     {
         TryAdd(length, NameTable[length.Vector] + ".Length");
         Parent.Add(length, length.Vector);
     }
 }
 public IEnumerable <string> Names(IEnumerable <IExpression> exprs)
 {
     Contract.Requires(exprs != null);
     Contract.Ensures(Contract.ForAll(Contract.Result <IEnumerable <string> >(), n => NameTable.ContainsValue(n)));
     foreach (var e in exprs)
     {
         if (NameTable.ContainsKey(e))
         {
             yield return(NameTable[e]);
         }
     }
 }
        public override void Visit(IArrayIndexer arrayIndexer)
        {
            if (arrayIndexer.Indices.Count() == 1 && NameTable.ContainsKey(arrayIndexer.IndexedObject))
            {
                var arrayName = NameTable[arrayIndexer.IndexedObject];
                TryAdd(arrayIndexer, FormElementsExpression(arrayName));

                // propogate instance expression information
                if (InstanceExpressionsReferredTypes.ContainsKey(arrayIndexer.IndexedObject))
                {
                    AddInstanceExpr(InstanceExpressionsReferredTypes[arrayIndexer.IndexedObject], arrayIndexer);
                }
            }
        }
        private void ObjectInvariants()
        {
            Contract.Invariant(methodCallCnt >= 0);
            Contract.Invariant(Host != null);
            Contract.Invariant(Type != null);
            Contract.Invariant(NamedChildren != null);
            Contract.Invariant(NameTable != null);
            Contract.Invariant(StaticNames != null);
            Contract.Invariant(Parent != null);
            Contract.Invariant(AnonymousDelegateReturns != null);
            Contract.Invariant(InstanceExpressionsReferredTypes != null);
            Contract.Invariant(InstanceExpressions != null);

            Contract.Invariant(Contract.ForAll(StaticNames, n => NameTable.ContainsKey(n)));
        }
        /// <summary>
        /// Associate <code>name</code> with <code>expression</code>.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        private void TryAdd(IExpression expression, string name)
        {
            Contract.Requires(expression != null);
            Contract.Requires(!string.IsNullOrWhiteSpace(name));
            Contract.Ensures(NameTable.ContainsKey(expression));
            Contract.Ensures(NameTable[expression].Equals(name));

            if (NameTable.ContainsKey(expression))
            {
                Contract.Assume(name.Equals(NameTable[expression]),
                                "Expression already exists in table with different name. Table: " + NameTable[expression] + " New: " + name);
            }
            else
            {
                NameTable.Add(expression, name);
            }
        }
        private void AddChildren(IExpression parent, params IExpression[] exprs)
        {
            Contract.Requires(parent != null);
            Contract.Requires(exprs != null);

            var children = exprs.Where(x => NameTable.ContainsKey(x));

            if (children.Any())
            {
                if (!NamedChildren.ContainsKey(parent))
                {
                    NamedChildren.Add(parent, new HashSet <IExpression>(children));
                }
                else
                {
                    NamedChildren[parent].UnionWith(children);
                }
            }
        }
        private bool GenerateAvoidList(HashSet <string> table, string name)
        {
            // our reference flag is based on what was passed to us
            bool isReferenced = false;

            // depth first, so walk all the children
            foreach (ActivationObject childScope in ChildScopes)
            {
                // if any child returns true, then it or one of its descendents
                // reference this variable. So we reference it, too
                if (childScope.GenerateAvoidList(table, name))
                {
                    // we'll return true because we reference it
                    isReferenced = true;
                }
            }

            if (!isReferenced)
            {
                // none of our children reference the scope, so see if we do
                isReferenced = NameTable.ContainsKey(name);
            }

            if (isReferenced)
            {
                // if we reference the name or are in line to reference the name,
                // we need to add all the variables we reference to the list
                foreach (var variableField in NameTable.Values)
                {
                    table.Add(variableField.ToString());
                }
            }

            // return whether or not we are in the reference chain
            return(isReferenced);
        }
        public override void Visit(IMethodCall call)
        {
            var receiver = call.ThisArgument;
            var callee   = call.MethodToCall.ResolvedMethod;

            if (callee is Dummy || callee.Name is Dummy)
            {
                return;
            }
            else if (NameTable.ContainsKey(call))
            {
                // TODO ##: can call occur more than once / be referentially equal?
                return;
            }

            var calleeName = callee.Name.Value;

            Contract.Assume(!string.IsNullOrWhiteSpace(calleeName));

            string name = null;

            if (!call.IsStaticCall && NameTable.ContainsKey(receiver))
            {
                if (callee.ParameterCount == 0)
                {
                    name = NameTable[call.ThisArgument] + "." +
                           (IsGetter(callee) ? calleeName.Substring("get_".Length) : calleeName + "()");
                }
                else if (IsSetter(callee))
                {
                    name = NameTable[call.ThisArgument] + "." + calleeName.Substring("set_".Length);
                }

                Parent.Add(call, call.ThisArgument);
                // propogate the instance information
                if (InstanceExpressionsReferredTypes.ContainsKey(receiver))
                {
                    AddInstanceExpr(InstanceExpressionsReferredTypes[receiver], call);
                }
            }

            // Check for indexes into a List
            if (!call.IsStaticCall && NameTable.ContainsKey(receiver))
            {
                foreach (var m in MemberHelper.GetImplicitlyImplementedInterfaceMethods(call.MethodToCall.ResolvedMethod))
                {
                    var genericDef = TypeHelper.UninstantiateAndUnspecialize(m.ContainingTypeDefinition);
                    if (TypeHelper.TypesAreEquivalent(genericDef, Host.PlatformType.SystemCollectionsGenericIList, true))
                    {
                        if (m.Name.Value.OneOf("get_Item"))
                        {
                            name = FormElementsExpression(NameTable[call.ThisArgument]);
                        }
                    }
                }
            }

            // Check for indexes into a Dictionary
            if (!call.IsStaticCall && NameTable.ContainsKey(receiver))
            {
                var genericDef = TypeHelper.UninstantiateAndUnspecialize(receiver.Type);

                if (TypeHelper.TypesAreEquivalent(genericDef, Host.PlatformType.SystemCollectionsGenericDictionary, true))
                {
                    if (callee.Name.Value.OneOf("get_Item"))
                    {
                        // ISSUE #91: this supports the dictionary[..].Value collection; does not support dictionary.Values
                        name = FormElementsExpression(NameTable[call.ThisArgument]) + ".Value";
                    }
                }
            }

            if (name == null)
            {
                // Assign a unique generated name (required for return value comparability)
                name = "<method>" + calleeName + "__" + methodCallCnt;
                methodCallCnt++;
            }

            TryAdd(call, name);
        }
        private void HandleBundle(IExpression outer, object definition, IExpression instance)
        {
            Contract.Requires(outer != null);
            Contract.Requires(definition != null);

            if (definition is IParameterDefinition)
            {
                var name = ((IParameterDefinition)definition).Name.Value;

                if (!string.IsNullOrEmpty(name))
                {
                    TryAdd(outer, name);
                }
                else
                {
                    // NO OP: implicit this of superclass is not named (e.g., for default ctor of subclass)
                }
            }
            else if (definition is IPropertyDefinition)
            {
                var name = ((IPropertyDefinition)definition).Name.Value;
                Contract.Assume(!string.IsNullOrWhiteSpace(name), Context());
                TryAdd(outer, name);
            }
            else if (definition is IFieldReference)
            {
                var field = ((IFieldReference)definition).ResolvedField;

                if (!(field is Dummy) && !field.Attributes.Any(a => TypeManager.IsCompilerGenerated(field)))
                {
                    if (field.IsStatic)
                    {
                        var container = field.ContainingType.ResolvedType;
                        // Celeriac uses reflection-style names for inner types, need to be consistent here
                        var name = string.Join(".", TypeHelper.GetTypeName(container, NameFormattingOptions.UseReflectionStyleForNestedTypeNames), field.Name.Value);
                        TryAdd(outer, name);
                        AddInstanceExpr(container, outer);
                        StaticNames.Add(outer);
                    }
                    else
                    {
                        Contract.Assume(instance != null, "Non-static field reference '" + field.Name + "' has no provided instance; " + Context());
                        if (instance != null && NameTable.ContainsKey(instance))
                        {
                            var name = NameTable[instance] + "." + field.Name;
                            TryAdd(outer, name);
                            AddInstanceExpr(Type, outer);
                        }
                        else
                        {
                            // NO OP (we aren't tracking the name of the instance)
                        }
                    }
                }
            }
            else if (definition is IArrayIndexer)
            {
                var def = (IArrayIndexer)definition;
                if (NameTable.ContainsKey(def.IndexedObject))
                {
                    TryAdd(outer, FormElementsExpression(NameTable[def.IndexedObject]));

                    // propogate instance expression information
                    if (InstanceExpressionsReferredTypes.ContainsKey(def.IndexedObject))
                    {
                        AddInstanceExpr(InstanceExpressionsReferredTypes[def.IndexedObject], outer);
                    }
                }
                else
                {
                    // NO OP (we aren't tracking the name of the instance)
                }
            }
            else if (definition is ILocalDefinition)
            {
                var def = (ILocalDefinition)definition;
                TryAdd(outer, "<local>" + def.Name.Value);
            }
            else if (definition is IAddressDereference)
            {
                // NO OP
            }
            else
            {
                throw new NotSupportedException("Comparability: Unexpected bundled type " + definition.GetType().Name);
            }
        }