private static bool CheckBounds(RewriteDesign design, ref RewrittenValueBridge skippedValue) { if (design.ResultSize == null) { return(true); } if (TryGetInt(skippedValue, out var skippedInt)) { if (skippedInt <= 0) { return(false); } if (TryGetInt(design.ResultSize, out var resultSizeInt) && skippedInt > resultSizeInt) { skippedValue = new RewrittenValueBridge(design.ResultSize); } else if (!design.Unchecked) { var skippedVariable = CreateGlobalVariable(design, Int); design.InitialAdd(skippedVariable.Assign(ConditionalExpression(skippedValue > design.ResultSize, design.ResultSize, skippedValue))); skippedValue = new RewrittenValueBridge(skippedVariable); } } else if (!design.Unchecked && !design.ModifiedEnumeration) { var skippedVariable = CreateGlobalVariable(design, Int); design.InitialAdd(If(skippedValue < 0, skippedVariable.Assign(0), If(skippedValue > design.ResultSize, skippedVariable.Assign(design.ResultSize), skippedVariable.Assign(skippedValue)))); skippedValue = new RewrittenValueBridge(skippedVariable); } return(true); }
public static LocalVariable CreateSuperGlobalVariable(RewriteDesign design, TypeSyntax type, ValueBridge initial) { string variable = "v" + VariableIndex++ % Constants.VariablesPeek; var created = new LocalVariable(variable, type) { IsGlobal = true, IsUsed = true }; design.Variables.Add(created); design.InitialAdd(LocalVariableCreation(variable, type)); design.InitialAdd(((ValueBridge)variable).Assign(initial)); design.SimpleEnumeration = false; return(created); }
public static void Rewrite(RewriteDesign design, RewrittenValueBridge[] args) { var collectionValue = args[0]; if (!AssertNotNull(design, collectionValue)) { return; } var methodValue = args[1]; design.WrapWithTry = true; var itemType = collectionValue.ItemType(design); var enumeratorVariable = CreateGlobalVariable(design, ParseTypeName($"System.Collections.Generic.IEnumerator<{itemType}>")); design.InitialAdd(enumeratorVariable.Assign(Parenthesize(collectionValue.Cast(ParseTypeName($"IEnumerable<{itemType}>"))) .Access("GetEnumerator").Invoke())); design.ForAdd(If(Not(enumeratorVariable.Access("MoveNext").Invoke()), Break())); design.LastValue = methodValue.Inline(design, design.LastValue, new TypedValueBridge(collectionValue.ItemType(design), enumeratorVariable.Access("Current"))); design.FinalAdd(enumeratorVariable.Access("Dispose").Invoke()); design.ListEnumeration = false; design.ModifiedEnumeration = true; }
public static LocalVariable CreateLocalVariable(RewriteDesign design, TypeBridge type) { var stringType = type.ToString(); var foundVariable = design.Variables.FirstOrDefault(x => stringType == x.Type.ToString() && !x.IsGlobal && !x.IsUsed); if (foundVariable != null) { foundVariable.IsUsed = true; return(foundVariable); } string variable = "v" + VariableIndex++ % Constants.VariablesPeek; var created = new LocalVariable(variable, type); design.Variables.Add(created); design.InitialAdd(LocalVariableCreation(variable, type)); design.SimpleEnumeration = false; return(created); }
public static void Rewrite(RewriteDesign design, RewrittenValueBridge[] args) { var collectionValue = args[0]; if (!AssertNotNull(design, collectionValue)) { return; } if (ExpressionSimplifier.TryGetInt(design.ResultSize, out var resultSizeInt)) { if (resultSizeInt == 0) { InitialErrorAdd(design, Return((collectionValue.Access("Count").Invoke()).IsEqual(0))); return; } } design.WrapWithTry = true; var itemType = collectionValue.ItemType(design); var enumeratorVariable = CreateGlobalVariable(design, ParseTypeName($"System.Collections.Generic.IEnumerator<{itemType}>")); design.InitialAdd(enumeratorVariable.Assign(Parenthesize(collectionValue.Cast(ParseTypeName($"IEnumerable<{itemType}>"))) .Access("GetEnumerator").Invoke())); var equalityTestValue = args.Length switch { 1 => enumeratorVariable.Access("Current", "Equals").Invoke(design.LastValue), 2 => args[1].ReusableConst(design).Access("Equals").Invoke(design.LastValue, enumeratorVariable.Access("Current")) }; design.ForAdd(If(Not(enumeratorVariable.Access("MoveNext").Invoke().And(equalityTestValue)), Return(false))); design.ResultAdd(If(enumeratorVariable.Access("MoveNext").Invoke(), Return(false))); design.FinalAdd(enumeratorVariable.Access("Dispose").Invoke()); design.ResultAdd(Return(true)); } }