Equals() public méthode

public Equals ( object obj ) : bool
obj object
Résultat bool
        protected void EliminateVariable (JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) {
            {
                var replacer = new VariableEliminator(
                    variable,
                    JSChangeTypeExpression.New(replaceWith, variable.GetActualType(TypeSystem), TypeSystem)
                );
                replacer.Visit(context);
            }

            {
                var replacer = new VariableEliminator(variable, replaceWith);
                var assignments = (from a in FirstPass.Assignments where 
                                       variable.Equals(a.NewValue) ||
                                       a.NewValue.SelfAndChildrenRecursive.Any(variable.Equals)
                                       select a).ToArray();

                foreach (var a in assignments) {
                    if (!variable.Equals(a.NewValue))
                        replacer.Visit(a.NewValue);
                }
            }

            Variables.Remove(variable.Identifier);
            FunctionSource.InvalidateFirstPass(method);
        }
        protected bool IsEffectivelyConstant(JSVariable target, JSExpression source)
        {
            if ((source == null) || (source.IsNull))
                return false;

            // Can't eliminate struct temporaries, since that might eliminate some implied copies.
            if (TypeUtil.IsStruct(target.IdentifierType))
                return false;

            // Handle special cases where our interpretation of 'constant' needs to be more flexible
            {
                var ie = source as JSIndexerExpression;
                if (ie != null) {
                    if (
                        IsEffectivelyConstant(target, ie.Target) &&
                        IsEffectivelyConstant(target, ie.Index)
                    )
                        return true;
                }
            }

            {
                var ae = source as JSArrayExpression;
                if (
                    (ae != null) &&
                    (from av in ae.Values select IsEffectivelyConstant(target, av)).All((b) => b)
                )
                    return true;
            }

            {
                var de = source as JSDotExpressionBase;
                if (
                    (de != null) &&
                    IsEffectivelyConstant(target, de.Target) &&
                    IsEffectivelyConstant(target, de.Member)
                )
                    return true;
            }

            {
                var ie = source as JSInvocationExpression;
                if (
                    (ie != null) && ie.ConstantIfArgumentsAre &&
                    IsEffectivelyConstant(target, ie.ThisReference) &&
                    ie.Arguments.All((a) => IsEffectivelyConstant(target, a))
                )
                    return true;

                if ((ie != null) && (ie.JSMethod != null)) {
                    var sa = GetSecondPass(ie.JSMethod);
                    if (sa != null) {
                        if (sa.IsPure) {
                            if (ie.Arguments.All((a) => IsEffectivelyConstant(target, a)))
                                return true;
                            else
                                return false;
                        }
                    }
                }
            }

            if ((source is JSUnaryOperatorExpression) || (source is JSBinaryOperatorExpression)) {
                if (source.Children.OfType<JSExpression>().All((_v) => IsEffectivelyConstant(target, _v)))
                    return true;
            }

            if (source.IsConstant)
                return true;

            // Try to find a spot between the source variable's assignments where all of our
            //  copies and accesses can fit. If we find one, our variable is effectively constant.
            // FIXME: I think this section might be fundamentally flawed. Do let me know if you agree. :)
            var v = source as JSVariable;
            if (v != null) {
                // Ensure that we never treat a local variable as constant if functions we call allow it to escape
                //  or modify it, because that can completely invalidate our purity analysis.
                if (VariablesExemptedFromEffectivelyConstantStatus.Contains(v.Identifier))
                    return false;

                var sourceAssignments = (from a in FirstPass.Assignments where v.Equals(a.Target) select a).ToArray();
                if (sourceAssignments.Length < 1)
                    return v.IsParameter;

                var sourceAccesses = (from a in FirstPass.Accesses where v.Equals(a.Source) select a).ToArray();
                if (sourceAccesses.Length < 1)
                    return false;

                var targetAssignmentIndices = (from a in FirstPass.Assignments where target.Equals(a.Target) select a.StatementIndex);
                var targetAccessIndices = (from a in FirstPass.Accesses where target.Equals(a.Source) select a.StatementIndex).ToArray();
                var targetUseIndices = targetAccessIndices.Concat(targetAssignmentIndices).ToArray();

                if (sourceAssignments.Length == 1) {
                    if (targetAccessIndices.All((tai) => tai > sourceAssignments[0].StatementIndex))
                        return true;
                }

                var sourceFirstAssigned = sourceAssignments.First();
                var sourceLastAssigned = sourceAssignments.Last();

                var sourceFirstAccessed = sourceAccesses.First();
                var sourceLastAccessed = sourceAccesses.Last();

                bool foundAssignmentSlot = false;

                for (int i = 0, c = targetUseIndices.Length; i < c; i++) {
                    int assignment = targetUseIndices[i], nextAssignment = int.MaxValue;
                    if (i < c - 1)
                        nextAssignment = targetUseIndices[i + 1];

                    if (
                        (sourceFirstAssigned.StatementIndex >= assignment) &&
                        (sourceLastAssigned.StatementIndex < nextAssignment) &&
                        (sourceFirstAccessed.StatementIndex >= assignment) &&
                        (sourceLastAccessed.StatementIndex <= nextAssignment)
                    ) {
                        if (TraceLevel >= 5)
                            Debug.WriteLine("Found assignment slot for {0} <- {1} between {2} and {3}", target, source, assignment, nextAssignment);

                        foundAssignmentSlot = true;
                        break;
                    }
                }

                if (!foundAssignmentSlot)
                    return false;

                return true;
            }

            return false;
        }
        protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith)
        {
            {
                var replacer = new VariableEliminator(
                    variable,
                    JSChangeTypeExpression.New(replaceWith, TypeSystem, variable.GetExpectedType(TypeSystem))
                );
                replacer.Visit(context);
            }

            {
                var replacer = new VariableEliminator(variable, replaceWith);
                var assignments = (from a in FirstPass.Assignments where
                                       variable.Equals(a.NewValue) ||
                                       a.NewValue.AllChildrenRecursive.Any((_n) => variable.Equals(_n))
                                       select a).ToArray();

                foreach (var a in assignments) {
                    if (variable.Equals(a.NewValue)) {
                        FirstPass.Assignments.Remove(a);
                        FirstPass.Assignments.Add(
                            new FunctionAnalysis1stPass.Assignment(
                                a.StatementIndex, a.NodeIndex,
                                a.Target, replaceWith, a.Operator,
                                a.TargetType, a.SourceType
                            )
                        );
                    } else {
                        replacer.Visit(a.NewValue);
                    }
                }
            }

            Variables.Remove(variable.Identifier);
        }
        protected bool IsEffectivelyConstant(JSVariable target, JSExpression source)
        {
            if ((source == null) || (source.IsNull))
                return false;

            // Handle special cases where our interpretation of 'constant' needs to be more flexible
            {
                var ie = source as JSIndexerExpression;
                if (ie != null) {
                    if (
                        IsEffectivelyConstant(target, ie.Target) &&
                        IsEffectivelyConstant(target, ie.Index)
                    )
                        return true;
                }
            }

            {
                var ae = source as JSArrayExpression;
                if (
                    (ae != null) &&
                    (from av in ae.Values select IsEffectivelyConstant(target, av)).All((b) => b)
                )
                    return true;
            }

            {
                var de = source as JSDotExpression;
                if (
                    (de != null) &&
                    IsEffectivelyConstant(target, de.Target) &&
                    IsEffectivelyConstant(target, de.Member)
                )
                    return true;
            }

            {
                var ie = source as JSInvocationExpression;
                if (
                    (ie != null) && ie.ConstantIfArgumentsAre &&
                    IsEffectivelyConstant(target, ie.ThisReference) &&
                    ie.Arguments.All((a) => IsEffectivelyConstant(target, a))
                )
                    return true;
            }

            if ((source is JSUnaryOperatorExpression) || (source is JSBinaryOperatorExpression)) {
                if (source.Children.OfType<JSExpression>().All((_v) => IsEffectivelyConstant(target, _v)))
                    return true;
            }

            if (source.IsConstant)
                return true;

            // Try to find a spot between the source variable's assignments where all of our
            //  copies and accesses can fit. If we find one, our variable is effectively constant.
            var v = source as JSVariable;
            if (v != null) {
                var assignments = (from a in FirstPass.Assignments where v.Equals(a.Target) select a).ToArray();
                if (assignments.Length < 1)
                    return v.IsParameter;

                var targetAssignments = (from a in FirstPass.Assignments where v.Equals(a.Target) select a).ToArray();
                if (targetAssignments.Length < 1)
                    return false;

                var targetAccesses = (from a in FirstPass.Accesses where target.Equals(a.Source) select a).ToArray();
                if (targetAccesses.Length < 1)
                    return false;

                var targetFirstAssigned = targetAssignments.FirstOrDefault();
                var targetLastAssigned = targetAssignments.LastOrDefault();

                var targetFirstAccessed = targetAccesses.FirstOrDefault();
                var targetLastAccessed = targetAccesses.LastOrDefault();

                bool foundAssignmentSlot = false;

                for (int i = 0, c = assignments.Length; i < c; i++) {
                    int assignment = assignments[i].StatementIndex, nextAssignment = int.MaxValue;
                    if (i < c - 1)
                        nextAssignment = assignments[i + 1].StatementIndex;

                    if (
                        (targetFirstAssigned.StatementIndex >= assignment) &&
                        (targetFirstAssigned.StatementIndex < nextAssignment) &&
                        (targetFirstAccessed.StatementIndex >= assignment) &&
                        (targetLastAccessed.StatementIndex <= nextAssignment)
                    ) {
                        foundAssignmentSlot = true;
                        break;
                    }
                }

                if (!foundAssignmentSlot)
                    return false;

                return true;
            }

            // TODO
            /*
            var accesses = (from a in FirstPass.Accesses where v.Equals(a.Source) select a).ToArray();
            if (accesses.Length < 1)
                return false;

            var firstAccess = accesses.FirstOrDefault();
            var lastAccess = accesses.LastOrDefault();

            if (firstAccess == firstAssignment + 1)
                return true;
             */

            return false;
        }
        protected bool IsEffectivelyConstant(JSVariable target, JSExpression source)
        {
            if ((source == null) || (source.IsNull))
                return false;

            // Can't eliminate struct temporaries, since that might eliminate some implied copies.
            if (TypeUtil.IsStruct(target.IdentifierType))
                return false;

            // Handle special cases where our interpretation of 'constant' needs to be more flexible
            {
                var ie = source as JSIndexerExpression;
                if (ie != null) {
                    if (
                        IsEffectivelyConstant(target, ie.Target) &&
                        IsEffectivelyConstant(target, ie.Index)
                    )
                        return true;
                }
            }

            {
                var ae = source as JSArrayExpression;
                if (
                    (ae != null) &&
                    (from av in ae.Values select IsEffectivelyConstant(target, av)).All((b) => b)
                )
                    return true;
            }

            {
                var de = source as JSDotExpressionBase;
                if (
                    (de != null) &&
                    IsEffectivelyConstant(target, de.Target) &&
                    IsEffectivelyConstant(target, de.Member)
                )
                    return true;
            }

            {
                var ie = source as JSInvocationExpression;
                if (
                    (ie != null) && ie.ConstantIfArgumentsAre &&
                    IsEffectivelyConstant(target, ie.ThisReference) &&
                    ie.Arguments.All((a) => IsEffectivelyConstant(target, a))
                )
                    return true;

                if ((ie != null) && (ie.JSMethod != null)) {
                    var sa = GetSecondPass(ie.JSMethod);
                    if (sa != null) {
                        if (sa.IsPure) {
                            if (ie.Arguments.All((a) => IsEffectivelyConstant(target, a)))
                                return true;
                            else
                                return false;
                        }
                    }
                }
            }

            if ((source is JSUnaryOperatorExpression) || (source is JSBinaryOperatorExpression)) {
                if (source.Children.OfType<JSExpression>().All((_v) => IsEffectivelyConstant(target, _v)))
                    return true;
            }

            if (source.IsConstant)
                return true;

            // Try to find a spot between the source variable's assignments where all of our
            //  copies and accesses can fit. If we find one, our variable is effectively constant.
            var v = source as JSVariable;
            if (v != null) {
                var assignments = (from a in FirstPass.Assignments where v.Equals(a.Target) select a).ToArray();
                if (assignments.Length < 1)
                    return v.IsParameter;

                var targetAssignments = (from a in FirstPass.Assignments where v.Equals(a.Target) select a).ToArray();
                if (targetAssignments.Length < 1)
                    return false;

                var targetAccesses = (from a in FirstPass.Accesses where target.Equals(a.Source) select a).ToArray();
                if (targetAccesses.Length < 1)
                    return false;

                var targetFirstAssigned = targetAssignments.FirstOrDefault();
                var targetLastAssigned = targetAssignments.LastOrDefault();

                var targetFirstAccessed = targetAccesses.FirstOrDefault();
                var targetLastAccessed = targetAccesses.LastOrDefault();

                bool foundAssignmentSlot = false;

                for (int i = 0, c = assignments.Length; i < c; i++) {
                    int assignment = assignments[i].StatementIndex, nextAssignment = int.MaxValue;
                    if (i < c - 1)
                        nextAssignment = assignments[i + 1].StatementIndex;

                    if (
                        (targetFirstAssigned.StatementIndex >= assignment) &&
                        (targetFirstAssigned.StatementIndex < nextAssignment) &&
                        (targetFirstAccessed.StatementIndex >= assignment) &&
                        (targetLastAccessed.StatementIndex <= nextAssignment)
                    ) {
                        foundAssignmentSlot = true;
                        break;
                    }
                }

                // If we didn't find a slot, check to see if all the assignments come before all the accesses.
                if (!foundAssignmentSlot) {
                    var minAccessIndex = targetAccesses.Min((a) => a.StatementIndex);

                    if (assignments.All((a) => a.StatementIndex < minAccessIndex))
                        foundAssignmentSlot = true;
                }

                if (!foundAssignmentSlot)
                    return false;

                return true;
            }

            return false;
        }