本文整理汇总了C#中ForeachStatement.GetRegion方法的典型用法代码示例。如果您正苦于以下问题:C# ForeachStatement.GetRegion方法的具体用法?C# ForeachStatement.GetRegion怎么用?C# ForeachStatement.GetRegion使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ForeachStatement
的用法示例。
在下文中一共展示了ForeachStatement.GetRegion方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: VisitForeachStatement
public override void VisitForeachStatement(ForeachStatement foreachStatement) {
var ferr = (ForEachResolveResult)_resolver.Resolve(foreachStatement);
var iterator = (LocalResolveResult)_resolver.Resolve(foreachStatement.VariableNameToken);
var getEnumeratorMethod = (ferr.GetEnumeratorCall is InvocationResolveResult ? ((InvocationResolveResult)ferr.GetEnumeratorCall).Member as IMethod : null);
var systemArray = _compilation.FindType(KnownTypeCode.Array);
var inExpression = ResolveWithConversion(foreachStatement.InExpression);
if (Equals(inExpression.Type, systemArray) || inExpression.Type.DirectBaseTypes.Contains(systemArray) || (getEnumeratorMethod != null && _metadataImporter.GetMethodSemantics(getEnumeratorMethod).EnumerateAsArray)) {
var arrayResult = CompileExpression(foreachStatement.InExpression, CompileExpressionFlags.ReturnValueIsImportant);
_result.AddRange(arrayResult.AdditionalStatements);
var array = arrayResult.Expression;
if (IsJsExpressionComplexEnoughToGetATemporaryVariable.Analyze(array)) {
var tmpArray = CreateTemporaryVariable(ferr.CollectionType, foreachStatement.GetRegion());
_result.Add(JsStatement.Var(_variables[tmpArray].Name, array));
array = JsExpression.Identifier(_variables[tmpArray].Name);
}
var length = systemArray.GetProperties().SingleOrDefault(p => p.Name == "Length");
if (length == null) {
_errorReporter.InternalError("Property Array.Length not found.");
return;
}
var lengthSem = _metadataImporter.GetPropertySemantics(length);
if (lengthSem.Type != PropertyScriptSemantics.ImplType.Field) {
_errorReporter.InternalError("Property Array.Length is not implemented as a field.");
return;
}
var index = CreateTemporaryVariable(_compilation.FindType(KnownTypeCode.Int32), foreachStatement.GetRegion());
var jsIndex = JsExpression.Identifier(_variables[index].Name);
JsExpression iteratorValue = MaybeCloneValueType(JsExpression.Index(array, jsIndex), null, ferr.ElementType);
if (_variables[iterator.Variable].UseByRefSemantics)
iteratorValue = JsExpression.ObjectLiteral(new JsObjectLiteralProperty("$", iteratorValue));
var body = new[] { JsStatement.Var(_variables[iterator.Variable].Name, iteratorValue) }
.Concat(CreateInnerCompiler().Compile(foreachStatement.EmbeddedStatement).Statements);
_result.Add(JsStatement.For(JsStatement.Var(_variables[index].Name, JsExpression.Number(0)),
JsExpression.Lesser(jsIndex, JsExpression.Member(array, lengthSem.FieldName)),
JsExpression.PostfixPlusPlus(jsIndex),
JsStatement.Block(body)));
}
else {
var getEnumeratorCall = _expressionCompiler.Compile(ferr.GetEnumeratorCall, true);
_result.AddRange(getEnumeratorCall.AdditionalStatements);
var enumerator = CreateTemporaryVariable(ferr.EnumeratorType, foreachStatement.GetRegion());
_result.Add(JsStatement.Var(_variables[enumerator].Name, getEnumeratorCall.Expression));
var moveNextInvocation = _expressionCompiler.Compile(new CSharpInvocationResolveResult(new LocalResolveResult(enumerator), ferr.MoveNextMethod, new ResolveResult[0]), true);
if (moveNextInvocation.AdditionalStatements.Count > 0)
_errorReporter.InternalError("MoveNext() invocation is not allowed to require additional statements.");
var getCurrent = _expressionCompiler.Compile(new MemberResolveResult(new LocalResolveResult(enumerator), ferr.CurrentProperty), true);
JsExpression getCurrentValue = MaybeCloneValueType(getCurrent.Expression, null, ferr.ElementType);
if (_variables[iterator.Variable].UseByRefSemantics)
getCurrentValue = JsExpression.ObjectLiteral(new JsObjectLiteralProperty("$", getCurrentValue));
var preBody = getCurrent.AdditionalStatements.Concat(new[] { JsStatement.Var(_variables[iterator.Variable].Name, getCurrentValue) }).ToList();
var body = CreateInnerCompiler().Compile(foreachStatement.EmbeddedStatement);
body = JsStatement.Block(preBody.Concat(body.Statements));
JsStatement disposer;
var systemIDisposable = _compilation.FindType(KnownTypeCode.IDisposable);
var disposeMethod = systemIDisposable.GetMethods().Single(m => m.Name == "Dispose");
var conversions = CSharpConversions.Get(_compilation);
var disposableConversion = conversions.ImplicitConversion(enumerator.Type, systemIDisposable);
if (disposableConversion.IsValid) {
// If the enumerator is implicitly convertible to IDisposable, we should dispose it.
var compileResult = _expressionCompiler.Compile(new CSharpInvocationResolveResult(new ConversionResolveResult(systemIDisposable, new LocalResolveResult(enumerator), disposableConversion), disposeMethod, new ResolveResult[0]), false);
if (compileResult.AdditionalStatements.Count != 0)
_errorReporter.InternalError("Call to IDisposable.Dispose must not return additional statements.");
disposer = compileResult.Expression;
}
else if (enumerator.Type.GetDefinition().IsSealed) {
// If the enumerator is sealed and not implicitly convertible to IDisposable, we need not dispose it.
disposer = null;
}
else {
// We don't know whether the enumerator is convertible to IDisposable, so we need to conditionally dispose it.
var test = _expressionCompiler.Compile(new TypeIsResolveResult(new LocalResolveResult(enumerator), systemIDisposable, _compilation.FindType(KnownTypeCode.Boolean)), true);
if (test.AdditionalStatements.Count > 0)
_errorReporter.InternalError("\"is\" test must not return additional statements.");
var innerStatements = _expressionCompiler.Compile(new CSharpInvocationResolveResult(new ConversionResolveResult(systemIDisposable, new LocalResolveResult(enumerator), conversions.ExplicitConversion(enumerator.Type, systemIDisposable)), disposeMethod, new ResolveResult[0]), false);
disposer = JsStatement.If(test.Expression, JsStatement.Block(innerStatements.AdditionalStatements.Concat(new JsStatement[] { innerStatements.Expression })), null);
}
JsStatement stmt = JsStatement.While(moveNextInvocation.Expression, body);
if (disposer != null)
stmt = JsStatement.Try(stmt, null, disposer);
_result.Add(stmt);
}
}