(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Microsoft.VisualBasic / Microsoft.VisualBasic / Microsoft.VisualBasic.CompilerServices / FlowControl.cs
blob0e6ac6b45ee5c09263dbe2529af431a518350b4d
1 //
2 // FlowControl.cs
3 //
4 // Author:
5 // Chris J Breisch (cjbreisch@altavista.net)
6 // Dennis Hayes (dennish@raytek.com)
7 //
8 // (C) 2002 Chris J Breisch
9 //
11 * Copyright (c) 2002-2003 Mainsoft Corporation.
12 * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 * DEALINGS IN THE SOFTWARE.
32 /**
33 * This class allows to execute loop statement of VisualBasic .NET
36 using System;
37 using System.Collections;
38 using System.ComponentModel;
40 namespace Microsoft.VisualBasic.CompilerServices
42 [StandardModule, EditorBrowsable(EditorBrowsableState.Never)]
43 sealed public class FlowControl {
44 private FlowControl () {}
46 private sealed /*static (final)in mainsoft java code*/ class ObjectFor {
47 public object Counter;
49 public object Limit;
51 public object StepValue;
53 public bool PositiveStep;
55 public Type EnumType;
58 /**
59 * This method check if the loop can continued.
60 * if the StepValue is positive it check that count is smaller than the limit.
61 * if the StepValue is negative it check that count is bigger than the limit.
62 * @param count
63 * @param limit
64 * @param StepValue
65 * @return boolean True of the for next loop can continue and false otherwise.
67 public static bool ForNextCheckR4(float count, float limit, float StepValue) {
68 bool positiveStep = StepValue > 0.0F;
69 bool isCountSmallThenLimit = count <= limit;
70 return positiveStep? isCountSmallThenLimit : !isCountSmallThenLimit;
73 /**
74 * This method check if the loop can continued.
75 * if the StepValue is positive it check that count is smaller than the limit.
76 * if the StepValue is negative it check that count is bigger than the limit.
77 * @param count
78 * @param limit
79 * @param StepValue
80 * @return boolean True of the for next loop can continue and false otherwise.
82 public static bool ForNextCheckR8(double count, double limit, double StepValue) {
83 bool positiveStep = StepValue > 0.0;
84 bool isCountSmallThenLimit = count <= limit;
85 return positiveStep? isCountSmallThenLimit : !isCountSmallThenLimit;
88 /**
89 * This method check if the loop can continued.
90 * if the StepValue is positive it check that count is smaller than the limit.
91 * if the StepValue is negative it check that count is bigger than the limit.
92 * @param count
93 * @param limit
94 * @param StepValue
95 * @return boolean True of the for next loop can continue and false otherwise.
97 public static bool ForNextCheckDec(Decimal count, Decimal limit, Decimal StepValue) {
98 bool positiveStep = StepValue.CompareTo(Decimal.Zero) < 0;
99 bool isCountSmallThenLimit = count.CompareTo(limit) >= 0;
100 return positiveStep? isCountSmallThenLimit : !isCountSmallThenLimit;
104 * This method method updates the LoopFor reference and the Counter reference
105 * object according to the given params and returns if this loop can continue.
106 * @param Counter this loop counter value
107 * @param Start this loop start value
108 * @param Limit this loop limitation value
109 * @param StepValue this loop step value
110 * @param lfr the LoopFor reference object
111 * @param cr the Counter object reference
112 * @return boolean is the returned LoopFor object can continue.
114 public static bool ForLoopInitObj(
115 object Counter,
116 object Start,
117 object Limit,
118 object StepValue,
119 ref System.Object lfr,
120 ref System.Object cr) {
122 object CounterResult = cr;
124 if (Start == null) {
125 throw new ArgumentException("Argument_InvalidNullValue1 " + " Start");
127 if (Limit == null) {
128 throw new ArgumentException("Argument_InvalidNullValue1 " + " Limit");
130 if (StepValue == null) {
131 throw new ArgumentException("Argument_InvalidNullValue1 " + " Step");
133 //gets the type of all the given parameters
134 Type startType = Start.GetType();
135 Type limitType = Limit.GetType();
136 Type stepType = StepValue.GetType();
138 //gets the widest common type code
140 TypeCode commonTypeCode = ObjectType.GetWidestType(Start, Limit, false);
141 commonTypeCode = ObjectType.GetWidestType(StepValue, commonTypeCode);
142 if (commonTypeCode == TypeCode.String) {
143 commonTypeCode = TypeCode.Double;
145 if (commonTypeCode == TypeCode.Object) {
146 //TODO:
147 //throw new ArgumentException(
148 // Utils.GetResourceString(
149 // "ForLoop_CommonType3",
150 // Utils.VBFriendlyName(startType),
151 // Utils.VBFriendlyName(limitType),
152 // Utils.VBFriendlyName(StepValue)));
153 throw new ArgumentException("ForLoop_CommonType3 startType limitType StepValue");
156 ObjectFor objectFor = new ObjectFor();
157 TypeCode startTypeCode = Type.GetTypeCode(startType);
158 TypeCode limitTypeCode = Type.GetTypeCode(limitType);
159 TypeCode stepTypeCode = Type.GetTypeCode(stepType);
160 Type enumType = null;
162 bool isStartTypeValidEnum = (startTypeCode == commonTypeCode) && (startType.IsEnum);
163 bool isLimitTypeValidEnum = (limitTypeCode == commonTypeCode) && (limitType.IsEnum);
164 bool isStepTypeValidEnum = (stepTypeCode == commonTypeCode) && (stepType.IsEnum);
166 bool isStartAndStepTypeEqual = (startType == stepType);
167 bool isStartAndLimitTypeEqual = (startType == limitType);
168 bool isStepAndLimitTypeEqual = (stepType == limitType);
170 //the For loop has enum type in the following case
171 //1. step is enum and it's type code equal to commonTypeCode and start and
172 // limit don't meet this condition.
173 //2. step and start are enum and their type code equal to commonTypeCode and
174 // their types are equal. limit doesn't meet this condition about been enum
175 // or about been equal to commonTypeCode.
176 //3. step and limit are enum and their type code equal to commonTypeCode and
177 // their types are equal. start doesn't meet this condition about been enum
178 // or about been equal to commonTypeCode.
179 //4. step and limit and start are enum and their type code equal to commonTypeCode and
180 // their types are equal.
181 //5. start is enum and it's type code equal to commonTypeCode .step and
182 // limit don't meet this condition.
183 //6. limit is enum and it's type code equal to commonTypeCode .step and
184 // start don't meet this condition.
185 //7.start and limit are enum and their type code equal to commonTypeCode and
186 // their types are equal. step doesn't meet this condition about been enum
187 // or about been equal to commonTypeCode.
190 if (isStartTypeValidEnum && isLimitTypeValidEnum && isStepTypeValidEnum
191 && isStartAndStepTypeEqual && isStartAndLimitTypeEqual)
192 enumType = startType;
193 else if (isStartTypeValidEnum && isStepTypeValidEnum && isStartAndStepTypeEqual)
194 enumType = startType;
195 else if (isStartTypeValidEnum && isStepTypeValidEnum && isStartAndStepTypeEqual)
196 enumType = startType;
197 else if (isStartTypeValidEnum && isLimitTypeValidEnum && isStartAndLimitTypeEqual)
198 enumType = startType;
199 else if (isStartTypeValidEnum && !isLimitTypeValidEnum && !isStepTypeValidEnum)
200 enumType = startType;
201 else if (!isStartTypeValidEnum && isLimitTypeValidEnum && !isStepTypeValidEnum)
202 enumType = limitType;
203 else if (!isStartTypeValidEnum && !isLimitTypeValidEnum && isStepTypeValidEnum)
204 enumType = stepType;
206 objectFor.EnumType = enumType;
208 //set the counter field of objectFor with Start value transleted to
209 // the widest common type code
210 objectFor.Counter = convertType(Start, commonTypeCode,"Start");
211 //set the Limit field of objectFor with Limit value transleted to
212 // the widest common type code
213 objectFor.Limit = convertType(Limit, commonTypeCode,"Limit");
214 //set the StepValue field of objectFor with StepValue value transleted to
215 // the widest common type code
216 objectFor.StepValue = convertType(StepValue, commonTypeCode,"Step");
217 //local is the value of zero in the widest common type code
219 object local = ObjectType.CTypeHelper(0, commonTypeCode);
221 IComparable iComparable = (IComparable)objectFor.StepValue;
222 objectFor.PositiveStep = iComparable.CompareTo(local) >= 0;
224 // sets the loop for reference
225 lfr = objectFor;
227 //sets the counter reference
228 if (objectFor.EnumType != null) {
229 cr = Enum.ToObject(objectFor.EnumType, objectFor.Counter);
231 else {
232 cr = objectFor.Counter;
234 return CheckContinueLoop(objectFor);
237 private static object convertType(object original, TypeCode typeCode, string fieldName) {
238 try {
239 return ObjectType.CTypeHelper(original, typeCode);
241 catch /*(Exception e)*/ {
242 throw new ArgumentException("ForLoop_ConvertToType3 " + fieldName);
246 public static bool ForNextCheckObj(object Counter, object LoopObj,
247 ref System.Object CounterResult) {// throws java.lang.Exception
248 TypeCode generalTypeCode = 0;
250 if (LoopObj == null) {
251 //TODO: use resource for the correct execption.
252 throw new Exception("VB error message #92 ForNextCheckObj LoopObj cannot be null");
253 //throw ExceptionUtils.VbMakeException(92);//correct java version
255 if (Counter == null) {
256 throw new NullReferenceException("Argument_InvalidNullValue1 " + " Counter");
257 //TODO:
258 //throw new NullReferenceException(
259 // Utils.GetResourceString(
260 // "Argument_InvalidNullValue1",
261 // "Counter"));
263 ObjectFor objectFor = (ObjectFor) LoopObj;
265 IConvertible iConvertible_counter = (IConvertible)Counter;
266 IConvertible iConvertible_step = (IConvertible) objectFor.StepValue;
268 TypeCode counterTypeCode = iConvertible_counter.GetTypeCode();
269 TypeCode stepTypeCode = iConvertible_step.GetTypeCode();
271 if (counterTypeCode == stepTypeCode && counterTypeCode != TypeCode.String) {
272 generalTypeCode = counterTypeCode;
274 else {
275 generalTypeCode = ObjectType.GetWidestType(counterTypeCode, stepTypeCode);
276 if (generalTypeCode == TypeCode.String) {
277 generalTypeCode = TypeCode.Double;
279 Counter = convertType(Counter, generalTypeCode,"Start");
280 objectFor.Limit = convertType(objectFor.Limit, generalTypeCode,"Limit");
281 objectFor.StepValue = convertType(objectFor.StepValue, generalTypeCode,"Step");
283 //changes the counter field to be the sum of step and counter
284 objectFor.Counter = ObjectType.AddObj(Counter, objectFor.StepValue);
285 IConvertible iConvertible_objectCounter = (IConvertible)objectFor.Counter;
286 TypeCode objectCounterTypeCode = iConvertible_objectCounter.GetTypeCode();
288 //setting the counter in counter reference.
289 //if the for is enum type change counter to enum.
290 if (objectFor.EnumType != null) {
291 CounterResult = Enum.ToObject(objectFor.EnumType, objectFor.Counter);
293 else {
294 CounterResult = objectFor.Counter;
297 //if the counter after the change didn't change it's type return true if
298 // the for object can continue loop and false otherwise.
299 //if the counter changed it's type change all for object fields to counter
300 //current type and return false.
301 if (objectCounterTypeCode == generalTypeCode) {
302 return CheckContinueLoop(objectFor);
304 else {
305 objectFor.Limit = ObjectType.CTypeHelper(objectFor.Limit, objectCounterTypeCode);
307 objectFor.StepValue =
308 ObjectType.CTypeHelper(objectFor.StepValue, objectCounterTypeCode);
309 return false;
314 * This method returns IEnumertator for a given array
315 * @param ary the given array
316 * @return IEnumerator the array's Enumerator
318 public static IEnumerator ForEachInArr(Array ary) {// throws java.lang.Exception
319 IEnumerator iEnumerator = (IEnumerator)ary;//is ArrayStaticWrapper.GetEnumerator(ary); in java code.
320 if (iEnumerator != null)
321 return iEnumerator;
322 throw ExceptionUtils.VbMakeException(92);
326 * This method gets IEnumerator for a given object that implements IEnumerable
327 * @param obj the object that implements IEnumerable
328 * @return IEnumerator the object's IEnumerator.
330 public static IEnumerator ForEachInObj(object obj) {// throws java.lang.Exception
331 if (obj == null)
332 throw ExceptionUtils.VbMakeException(91);
334 IEnumerable iEnumerable = (IEnumerable)obj;
335 if (iEnumerable != null) {
336 IEnumerator iEnumerator = iEnumerable.GetEnumerator();
337 if (iEnumerator != null)
338 return iEnumerator;
340 string s = obj.GetType().ToString();
341 ExceptionUtils.ThrowException1(100, s);
342 return null;
346 * This method set the next value of teh Enumerator in the reference.
347 * if there isn't next value , null is been set in the referece.
348 * @param obj
349 * @param enumerator
350 * @return boolean returns the value of enumerator.MoveNext().
352 public static bool ForEachNextObj(ref System.Object obj, IEnumerator enumerator) {
353 if (enumerator.MoveNext()) {
354 obj = enumerator.Current;
355 return true;
357 obj = null;
358 return false;
362 * This method check if the loop can continued.
363 * if the step is positive it check that the counter is smaller than the limit.
364 * if the step is negative it check that the counter is bigger than the limit.
365 * @param LoopFor
366 * @return boolean
368 private static bool CheckContinueLoop(ObjectFor LoopFor) {
369 //TODO:
370 //throw new NotImplementedException("MSVB.Compilerservices.flowcontrol needs help");
371 IComparable iComparable = (IComparable)LoopFor.Counter;
373 if (iComparable != null) {
374 int i = iComparable.CompareTo(LoopFor.Limit);
375 bool isCountSmallThenLimit = i<=0;
376 return LoopFor.PositiveStep ? isCountSmallThenLimit : !isCountSmallThenLimit;
378 throw new ArgumentException("Argument_IComparable2 loop control variable"); // + Utils.VBFriendlyName(LoopFor.Counter)));
379 //TODO: verify this and the above are the same and remove.
380 //throw new ArgumentException(Utils.GetResourceString(
381 // "Argument_IComparable2", "loop control variable",
382 // Utils.VBFriendlyName(LoopFor.Counter)));
386 * This method throws exception if the input is Valuetype
387 * @param obj the object that need to be checked
389 public static void CheckForSyncLockOnValueType(object obj) {
390 //TODO:
391 //throw new NotImplementedException("MSVB.Compilerservices.flowcontrol needs help");
392 if (obj != null && obj.GetType().IsValueType)
393 throw new ArgumentException(Utils.GetResourceString("SyncLockRequiresReferenceType1 "));
394 //TODO: verify this and the above are the same and remove.
395 //if (obj != null && ObjectStaticWrapper.GetType(obj).get_IsValueType())
396 // throw new ArgumentException(Utils.GetResourceString(
397 // "SyncLockRequiresReferenceType1",Utils.VBFriendlyName(obj)));