| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- //
- // FlowControl.cs
- //
- // Author:
- // Chris J Breisch ([email protected])
- // Dennis Hayes ([email protected])
- //
- // (C) 2002 Chris J Breisch
- //
- /*
- * Copyright (c) 2002-2003 Mainsoft Corporation.
- * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- /**
- * This class allows to execute loop statement of VisualBasic .NET
- */
- using System;
- using System.Collections;
- using System.ComponentModel;
- namespace Microsoft.VisualBasic.CompilerServices
- {
- [StandardModule, EditorBrowsable(EditorBrowsableState.Never)]
- sealed public class FlowControl {
- private FlowControl () {}
- private sealed /*static (final)in mainsoft java code*/ class ObjectFor {
- public object Counter;
- public object Limit;
- public object StepValue;
- public bool PositiveStep;
- public Type EnumType;
- }
-
- /**
- * This method check if the loop can continued.
- * if the StepValue is positive it check that count is smaller than the limit.
- * if the StepValue is negative it check that count is bigger than the limit.
- * @param count
- * @param limit
- * @param StepValue
- * @return boolean True of the for next loop can continue and false otherwise.
- */
- public static bool ForNextCheckR4(float count, float limit, float StepValue) {
- bool positiveStep = StepValue > 0.0F;
- if (positiveStep)
- return count <= limit;
- else
- return count >= limit;
- }
-
- /**
- * This method check if the loop can continued.
- * if the StepValue is positive it check that count is smaller than the limit.
- * if the StepValue is negative it check that count is bigger than the limit.
- * @param count
- * @param limit
- * @param StepValue
- * @return boolean True of the for next loop can continue and false otherwise.
- */
- public static bool ForNextCheckR8(double count, double limit, double StepValue) {
- bool positiveStep = StepValue > 0.0;
- if (positiveStep)
- return count <= limit;
- else
- return count >= limit;
- }
- /**
- * This method check if the loop can continued.
- * if the StepValue is positive it check that count is smaller than the limit.
- * if the StepValue is negative it check that count is bigger than the limit.
- * @param count
- * @param limit
- * @param StepValue
- * @return boolean True of the for next loop can continue and false otherwise.
- */
- public static bool ForNextCheckDec(Decimal count, Decimal limit, Decimal StepValue) {
- bool positiveStep = StepValue.CompareTo(Decimal.Zero) > 0;
- if (positiveStep)
- return (count.CompareTo(limit) <= 0);
- else
- return (limit.CompareTo(count) <= 0);
- }
-
- /**
- * This method method updates the LoopFor reference and the Counter reference
- * object according to the given params and returns if this loop can continue.
- * @param Counter this loop counter value
- * @param Start this loop start value
- * @param Limit this loop limitation value
- * @param StepValue this loop step value
- * @param lfr the LoopFor reference object
- * @param cr the Counter object reference
- * @return boolean is the returned LoopFor object can continue.
- */
- public static bool ForLoopInitObj(
- object Counter,
- object Start,
- object Limit,
- object StepValue,
- ref System.Object lfr,
- ref System.Object cr) {
- if (Start == null) {
- throw new ArgumentException("Argument_InvalidNullValue1 " + " Start");
- }
- if (Limit == null) {
- throw new ArgumentException("Argument_InvalidNullValue1 " + " Limit");
- }
- if (StepValue == null) {
- throw new ArgumentException("Argument_InvalidNullValue1 " + " Step");
- }
- //gets the type of all the given parameters
- Type startType = Start.GetType();
- Type limitType = Limit.GetType();
- Type stepType = StepValue.GetType();
- //gets the widest common type code
-
- TypeCode commonTypeCode = ObjectType.GetWidestType(Start, Limit, false);
- commonTypeCode = ObjectType.GetWidestType(StepValue, commonTypeCode);
- if (commonTypeCode == TypeCode.String) {
- commonTypeCode = TypeCode.Double;
- }
- if (commonTypeCode == TypeCode.Object) {
- //TODO:
- //throw new ArgumentException(
- // Utils.GetResourceString(
- // "ForLoop_CommonType3",
- // Utils.VBFriendlyName(startType),
- // Utils.VBFriendlyName(limitType),
- // Utils.VBFriendlyName(StepValue)));
- throw new ArgumentException("ForLoop_CommonType3 startType limitType StepValue");
- }
- ObjectFor objectFor = new ObjectFor();
- TypeCode startTypeCode = Type.GetTypeCode(startType);
- TypeCode limitTypeCode = Type.GetTypeCode(limitType);
- TypeCode stepTypeCode = Type.GetTypeCode(stepType);
- Type enumType = null;
- bool isStartTypeValidEnum = (startTypeCode == commonTypeCode) && (startType.IsEnum);
- bool isLimitTypeValidEnum = (limitTypeCode == commonTypeCode) && (limitType.IsEnum);
- bool isStepTypeValidEnum = (stepTypeCode == commonTypeCode) && (stepType.IsEnum);
-
- bool isStartAndStepTypeEqual = (startType == stepType);
- bool isStartAndLimitTypeEqual = (startType == limitType);
- // bool isStepAndLimitTypeEqual = (stepType == limitType);
- //the For loop has enum type in the following case
- //1. step is enum and it's type code equal to commonTypeCode and start and
- // limit don't meet this condition.
- //2. step and start are enum and their type code equal to commonTypeCode and
- // their types are equal. limit doesn't meet this condition about been enum
- // or about been equal to commonTypeCode.
- //3. step and limit are enum and their type code equal to commonTypeCode and
- // their types are equal. start doesn't meet this condition about been enum
- // or about been equal to commonTypeCode.
- //4. step and limit and start are enum and their type code equal to commonTypeCode and
- // their types are equal.
- //5. start is enum and it's type code equal to commonTypeCode .step and
- // limit don't meet this condition.
- //6. limit is enum and it's type code equal to commonTypeCode .step and
- // start don't meet this condition.
- //7.start and limit are enum and their type code equal to commonTypeCode and
- // their types are equal. step doesn't meet this condition about been enum
- // or about been equal to commonTypeCode.
- //
-
- if (isStartTypeValidEnum && isLimitTypeValidEnum && isStepTypeValidEnum
- && isStartAndStepTypeEqual && isStartAndLimitTypeEqual)
- enumType = startType;
- else if (isStartTypeValidEnum && isStepTypeValidEnum && isStartAndStepTypeEqual)
- enumType = startType;
- else if (isStartTypeValidEnum && isStepTypeValidEnum && isStartAndStepTypeEqual)
- enumType = startType;
- else if (isStartTypeValidEnum && isLimitTypeValidEnum && isStartAndLimitTypeEqual)
- enumType = startType;
- else if (isStartTypeValidEnum && !isLimitTypeValidEnum && !isStepTypeValidEnum)
- enumType = startType;
- else if (!isStartTypeValidEnum && isLimitTypeValidEnum && !isStepTypeValidEnum)
- enumType = limitType;
- else if (!isStartTypeValidEnum && !isLimitTypeValidEnum && isStepTypeValidEnum)
- enumType = stepType;
-
- objectFor.EnumType = enumType;
-
- //set the counter field of objectFor with Start value transleted to
- // the widest common type code
- objectFor.Counter = convertType(Start, commonTypeCode,"Start");
- //set the Limit field of objectFor with Limit value transleted to
- // the widest common type code
- objectFor.Limit = convertType(Limit, commonTypeCode,"Limit");
- //set the StepValue field of objectFor with StepValue value transleted to
- // the widest common type code
- objectFor.StepValue = convertType(StepValue, commonTypeCode,"Step");
- //local is the value of zero in the widest common type code
- object local = ObjectType.CTypeHelper(0, commonTypeCode);
-
- IComparable iComparable = (IComparable)objectFor.StepValue;
- objectFor.PositiveStep = iComparable.CompareTo(local) >= 0;
- // sets the loop for reference
- lfr = objectFor;
-
- //sets the counter reference
- if (objectFor.EnumType != null) {
- cr = Enum.ToObject(objectFor.EnumType, objectFor.Counter);
- }
- else {
- cr = objectFor.Counter;
- }
- return CheckContinueLoop(objectFor);
- }
-
- private static object convertType(object original, TypeCode typeCode, string fieldName) {
- try {
- return ObjectType.CTypeHelper(original, typeCode);
- }
- catch /*(Exception e)*/ {
- throw new ArgumentException("ForLoop_ConvertToType3 " + fieldName);
- }
- }
- public static bool ForNextCheckObj(object Counter, object LoopObj,
- ref System.Object CounterResult) {// throws java.lang.Exception
- TypeCode generalTypeCode = 0;
- if (LoopObj == null) {
- //TODO: use resource for the correct execption.
- throw new Exception("VB error message #92 ForNextCheckObj LoopObj cannot be null");
- //throw ExceptionUtils.VbMakeException(92);//correct java version
- }
- if (Counter == null) {
- throw new NullReferenceException("Argument_InvalidNullValue1 " + " Counter");
- //TODO:
- //throw new NullReferenceException(
- // Utils.GetResourceString(
- // "Argument_InvalidNullValue1",
- // "Counter"));
- }
- ObjectFor objectFor = (ObjectFor) LoopObj;
- IConvertible iConvertible_counter = (IConvertible)Counter;
- IConvertible iConvertible_step = (IConvertible) objectFor.StepValue;
- TypeCode counterTypeCode = iConvertible_counter.GetTypeCode();
- TypeCode stepTypeCode = iConvertible_step.GetTypeCode();
-
- if (counterTypeCode == stepTypeCode && counterTypeCode != TypeCode.String) {
- generalTypeCode = counterTypeCode;
- }
- else {
- generalTypeCode = ObjectType.GetWidestType(counterTypeCode, stepTypeCode);
- if (generalTypeCode == TypeCode.String) {
- generalTypeCode = TypeCode.Double;
- }
- Counter = convertType(Counter, generalTypeCode,"Start");
- objectFor.Limit = convertType(objectFor.Limit, generalTypeCode,"Limit");
- objectFor.StepValue = convertType(objectFor.StepValue, generalTypeCode,"Step");
- }
- //changes the counter field to be the sum of step and counter
- objectFor.Counter = ObjectType.AddObj(Counter, objectFor.StepValue);
- IConvertible iConvertible_objectCounter = (IConvertible)objectFor.Counter;
- TypeCode objectCounterTypeCode = iConvertible_objectCounter.GetTypeCode();
- //setting the counter in counter reference.
- //if the for is enum type change counter to enum.
- if (objectFor.EnumType != null) {
- CounterResult = Enum.ToObject(objectFor.EnumType, objectFor.Counter);
- }
- else {
- CounterResult = objectFor.Counter;
- }
-
- //if the counter after the change didn't change it's type return true if
- // the for object can continue loop and false otherwise.
- //if the counter changed it's type change all for object fields to counter
- //current type and return false.
- if (objectCounterTypeCode == generalTypeCode) {
- return CheckContinueLoop(objectFor);
- }
- else {
- objectFor.Limit = ObjectType.CTypeHelper(objectFor.Limit, objectCounterTypeCode);
-
- objectFor.StepValue =
- ObjectType.CTypeHelper(objectFor.StepValue, objectCounterTypeCode);
- return false;
- }
- }
-
- /**
- * This method returns IEnumertator for a given array
- * @param ary the given array
- * @return IEnumerator the array's Enumerator
- */
- public static IEnumerator ForEachInArr(Array ary) {// throws java.lang.Exception
- IEnumerator iEnumerator = (IEnumerator)ary;//is ArrayStaticWrapper.GetEnumerator(ary); in java code.
- if (iEnumerator != null)
- return iEnumerator;
- throw ExceptionUtils.VbMakeException(92);
- }
-
- /**
- * This method gets IEnumerator for a given object that implements IEnumerable
- * @param obj the object that implements IEnumerable
- * @return IEnumerator the object's IEnumerator.
- */
- public static IEnumerator ForEachInObj(object obj) {// throws java.lang.Exception
- if (obj == null)
- throw ExceptionUtils.VbMakeException(91);
- IEnumerable iEnumerable = (IEnumerable)obj;
- if (iEnumerable != null) {
- IEnumerator iEnumerator = iEnumerable.GetEnumerator();
- if (iEnumerator != null)
- return iEnumerator;
- }
- string s = obj.GetType().ToString();
- ExceptionUtils.ThrowException1(100, s);
- return null;
- }
-
- /**
- * This method set the next value of teh Enumerator in the reference.
- * if there isn't next value , null is been set in the referece.
- * @param obj
- * @param enumerator
- * @return boolean returns the value of enumerator.MoveNext().
- */
- public static bool ForEachNextObj(ref System.Object obj, IEnumerator enumerator) {
- if (enumerator.MoveNext()) {
- obj = enumerator.Current;
- return true;
- }
- obj = null;
- return false;
- }
-
- /**
- * This method check if the loop can continued.
- * if the step is positive it check that the counter is smaller than the limit.
- * if the step is negative it check that the counter is bigger than the limit.
- * @param LoopFor
- * @return boolean
- */
- private static bool CheckContinueLoop(ObjectFor LoopFor) {
- //TODO:
- //throw new NotImplementedException("MSVB.Compilerservices.flowcontrol needs help");
- IComparable iComparable = (IComparable)LoopFor.Counter;
-
- if (iComparable != null) {
- int i = iComparable.CompareTo(LoopFor.Limit);
- if (LoopFor.PositiveStep)
- return i <= 0;
- else
- return i >= 0;
- }
- throw new ArgumentException("Argument_IComparable2 loop control variable"); // + Utils.VBFriendlyName(LoopFor.Counter)));
- //TODO: verify this and the above are the same and remove.
- //throw new ArgumentException(Utils.GetResourceString(
- // "Argument_IComparable2", "loop control variable",
- // Utils.VBFriendlyName(LoopFor.Counter)));
- }
-
- /**
- * This method throws exception if the input is Valuetype
- * @param obj the object that need to be checked
- */
- public static void CheckForSyncLockOnValueType(object obj) {
- //TODO:
- //throw new NotImplementedException("MSVB.Compilerservices.flowcontrol needs help");
- if (obj != null && obj.GetType().IsValueType)
- throw new ArgumentException(Utils.GetResourceString("SyncLockRequiresReferenceType1 "));
- //TODO: verify this and the above are the same and remove.
- //if (obj != null && ObjectStaticWrapper.GetType(obj).get_IsValueType())
- // throw new ArgumentException(Utils.GetResourceString(
- // "SyncLockRequiresReferenceType1",Utils.VBFriendlyName(obj)));
- }
- }
- }
|