private GetDeclaredVariable ( string variableName ) : DeclaredVariable | ||
variableName | string | The name of the variable. |
return | DeclaredVariable |
/// <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> private Dictionary <Scope.DeclaredVariable, InferredTypeInfo> FindTypedVariables() { var result = new Dictionary <Scope.DeclaredVariable, InferredTypeInfo>(); // Special case for the common case of an incrementing or decrementing loop variable. // The loop must be one of the following forms: // for (var i = <int>; i < <int>; i ++) // for (var i = <int>; i < <int>; ++ i) // for (var i = <int>; i > <int>; i --) // for (var i = <int>; i > <int>; -- i) // for (i = <int>; i < <int>; i ++) // for (i = <int>; i < <int>; ++ i) // for (i = <int>; i > <int>; i --) // for (i = <int>; i > <int>; -- i) Scope loopVariableScope = null; string loopVariableName = null; // First, check the init statement. bool initIsOkay = false; if (this.InitVarStatement != null && this.InitVarStatement.Declarations.Count == 1 && this.InitVarStatement.Declarations[0].InitExpression != null && this.InitVarStatement.Declarations[0].InitExpression.ResultType == PrimitiveType.Int32) { // for (var i = <int>; ?; ?) loopVariableScope = this.InitVarStatement.Scope; loopVariableName = this.InitVarStatement.Declarations[0].VariableName; initIsOkay = loopVariableScope is DeclarativeScope && loopVariableScope.HasDeclaredVariable(loopVariableName) == true; } else if (this.InitExpression != null && this.InitExpression is AssignmentExpression && ((AssignmentExpression)this.InitExpression).ResultType == PrimitiveType.Int32 && ((AssignmentExpression)this.InitExpression).Target is NameExpression) { // for (i = <int>; ?; ?) loopVariableScope = ((NameExpression)((AssignmentExpression)this.InitExpression).Target).Scope; loopVariableName = ((NameExpression)((AssignmentExpression)this.InitExpression).Target).Name; initIsOkay = loopVariableScope is DeclarativeScope && loopVariableScope.HasDeclaredVariable(loopVariableName) == true; } // Next, check the condition expression. bool conditionAndInitIsOkay = false; bool lessThan = true; if (initIsOkay == true && this.ConditionStatement != null && this.Condition is BinaryExpression && (((BinaryExpression)this.Condition).OperatorType == OperatorType.LessThan || ((BinaryExpression)this.Condition).OperatorType == OperatorType.GreaterThan) && ((BinaryExpression)this.Condition).Left is NameExpression && ((NameExpression)((BinaryExpression)this.Condition).Left).Name == loopVariableName && ((BinaryExpression)this.Condition).Right.ResultType == PrimitiveType.Int32) { // for (?; i < <int>; ?) // for (?; i > <int>; ?) lessThan = ((BinaryExpression)this.Condition).OperatorType == OperatorType.LessThan; conditionAndInitIsOkay = true; } // Next, check the increment expression. bool everythingIsOkay = false; if (conditionAndInitIsOkay == true) { if (lessThan == true && this.IncrementStatement != null && this.Increment is AssignmentExpression && (((AssignmentExpression)this.Increment).OperatorType == OperatorType.PostIncrement || ((AssignmentExpression)this.Increment).OperatorType == OperatorType.PreIncrement) && ((NameExpression)((AssignmentExpression)this.Increment).Target).Name == loopVariableName) { // for (?; i < <int>; i ++) // for (?; i < <int>; ++ i) everythingIsOkay = true; } else if (lessThan == false && this.IncrementStatement != null && this.Increment is AssignmentExpression && (((AssignmentExpression)this.Increment).OperatorType == OperatorType.PostDecrement || ((AssignmentExpression)this.Increment).OperatorType == OperatorType.PreDecrement) && ((NameExpression)((AssignmentExpression)this.Increment).Target).Name == loopVariableName) { // for (?; i > <int>; i --) // for (?; i > <int>; -- i) everythingIsOkay = true; } } bool continueEncountered = false; if (everythingIsOkay == true) { // The loop variable can be optimized to an integer. var variable = loopVariableScope.GetDeclaredVariable(loopVariableName); if (variable != null) { result.Add(variable, new InferredTypeInfo() { Type = PrimitiveType.Int32, Conditional = false }); } FindTypedVariables(this.Body, result, conditional: false, continueEncountered: ref continueEncountered); } else { // Unoptimized. FindTypedVariables(this, result, conditional: false, continueEncountered: ref continueEncountered); } return(result); }