コード例 #1
0
ファイル: LoopStatement.cs プロジェクト: Kevnz/JS360
        /// <summary>
        /// Finds variables that were assigned to and determines their types.
        /// </summary>
        /// <param name="root"> The root of the abstract syntax tree to search. </param>
        /// <param name="variableTypes"> A dictionary containing the variables that were assigned to. </param>
        /// <param name="conditional"> <c>true</c> if execution of the AST node <paramref name="root"/>
        /// is conditional (i.e. the node is inside an if statement or a conditional expression. </param>
        /// <param name="continueEncountered"> Keeps track of whether a continue statement has been
        /// encountered. </param>
        private static void FindTypedVariables(AstNode root, Dictionary <Scope.DeclaredVariable, InferredTypeInfo> variableTypes, bool conditional, ref bool continueEncountered)
        {
            if (root is AssignmentExpression)
            {
                // Found an assignment.
                var assignment = (AssignmentExpression)root;
                if (assignment.Target is NameExpression)
                {
                    // Found an assignment to a variable.
                    var name = (NameExpression)assignment.Target;
                    if (name.Scope is DeclarativeScope)
                    {
                        var variable = name.Scope.GetDeclaredVariable(name.Name);
                        if (variable != null)
                        {
                            // The variable is in the top-most scope.
                            // Check if the variable has been seen before.
                            InferredTypeInfo existingTypeInfo;
                            if (variableTypes.TryGetValue(variable, out existingTypeInfo) == false)
                            {
                                // This is the first time the variable has been encountered.
                                variableTypes.Add(variable, new InferredTypeInfo()
                                {
                                    Type = assignment.ResultType, Conditional = conditional
                                });
                            }
                            else
                            {
                                // The variable has been seen before.
                                variableTypes[variable] = new InferredTypeInfo()
                                {
                                    Type        = PrimitiveTypeUtilities.GetCommonType(existingTypeInfo.Type, assignment.ResultType),
                                    Conditional = existingTypeInfo.Conditional == true && conditional == true
                                };
                            }
                        }
                    }
                }
            }

            // Determine whether the child nodes are conditional.
            conditional = conditional == true ||
                          continueEncountered == true ||
                          root is IfStatement ||
                          root is TernaryExpression ||
                          root is TryCatchFinallyStatement ||
                          (root is BinaryExpression && ((BinaryExpression)root).OperatorType == OperatorType.LogicalAnd) ||
                          (root is BinaryExpression && ((BinaryExpression)root).OperatorType == OperatorType.LogicalOr);

            // If the AST node is a continue statement, all further assignments are conditional.
            if (root is ContinueStatement)
            {
                continueEncountered = true;
            }

            // Search child nodes for assignment statements.
            foreach (var node in root.ChildNodes)
            {
                FindTypedVariables(node, variableTypes, conditional: conditional, continueEncountered: ref continueEncountered);
            }
        }