⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 foreachstatement.vb

📁 大名鼎鼎的mono是.NET平台的跨平台(支持linux
💻 VB
字号:
' ' Visual Basic.Net Compiler' Copyright (C) 2004 - 2007 Rolf Bjarne Kvinge, RKvinge@novell.com' ' This library is free software; you can redistribute it and/or' modify it under the terms of the GNU Lesser General Public' License as published by the Free Software Foundation; either' version 2.1 of the License, or (at your option) any later version.' ' This library is distributed in the hope that it will be useful,' but WITHOUT ANY WARRANTY; without even the implied warranty of' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU' Lesser General Public License for more details.' ' You should have received a copy of the GNU Lesser General Public' License along with this library; if not, write to the Free Software' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA' ''' <summary>''' ForEachStatement  ::='''	   "For" "Each" LoopControlVariable "In" Expression  StatementTerminator'''	         [  Block  ]'''	   "Next" [Expression  ]  StatementTerminator''' </summary>''' <remarks></remarks>Public Class ForEachStatement    Inherits BlockStatement    Private m_LoopControlVariable As LoopControlVariable    Private m_InExpression As Expression    Private m_NextExpression As Expression    Private m_NextIteration As Label    Private m_Enumerator As LocalBuilder    ReadOnly Property NextExpression() As Expression        Get            Return m_NextExpression        End Get    End Property    ReadOnly Property InExpression() As Expression        Get            Return m_InExpression        End Get    End Property    ReadOnly Property LoopControlVariable() As LoopControlVariable        Get            Return m_loopcontrolvariable        End Get    End Property    Sub New(ByVal Parent As ParsedObject)        MyBase.New(Parent)    End Sub    Shadows Sub Init(ByVal LoopControlVariable As LoopControlVariable, ByVal InExpression As Expression, ByVal NextExpression As Expression, ByVal Block As CodeBlock)        MyBase.Init(Block)        m_LoopControlVariable = LoopControlVariable        m_InExpression = InExpression        m_NextExpression = NextExpression    End Sub    ReadOnly Property Enumerator() As LocalBuilder        Get            Return m_Enumerator        End Get    End Property    ReadOnly Property NextIteration() As Label        Get            Return m_NextIteration        End Get    End Property    Function GenerateCode_LoadCurrentLoopVariable(ByVal Info As EmitInfo) As Boolean        Dim varType As Type = m_LoopControlVariable.VariableType        Dim isGenericParameter As Boolean = varType.IsGenericParameter        Dim isValueType As Boolean = isGenericParameter = False AndAlso varType.IsValueType        Dim isClass As Boolean = isgenericparameter = False AndAlso varType.IsClass        Emitter.EmitLoadVariable(Info, m_Enumerator)        Emitter.EmitCallVirt(Info, Compiler.TypeCache.System_Collections_IEnumerator__get_Current)        Dim valueTPLoad As Label        Dim valueTPLoaded As Label        If isValueType Then            Dim tmpStructureVariable As LocalBuilder            valueTPLoad = Emitter.DefineLabel(Info)            valueTPLoaded = Emitter.DefineLabel(Info)            tmpStructureVariable = Emitter.DeclareLocal(Info, varType)            Emitter.EmitDup(Info)            Emitter.EmitBranchIfTrue(Info, valueTPLoad)            Emitter.EmitPop(Info, Compiler.TypeCache.System_Object)            Emitter.EmitLoadVariable(Info, tmpStructureVariable)            Emitter.EmitBranch(Info, valueTPLoaded)            Emitter.FreeLocal(tmpStructureVariable)        Else            Emitter.EmitCallOrCallVirt(Info, Compiler.TypeCache.System_Runtime_CompilerServices_RuntimeHelpers__GetObjectValue_Object)        End If        If isGenericParameter Then            Emitter.EmitUnbox_Any(Info, varType)        ElseIf isClass Then            Emitter.EmitCastClass(Info, Compiler.TypeCache.System_Object, varType)        ElseIf isValueType Then            Emitter.MarkLabel(Info, valueTPLoad)            Emitter.EmitUnbox(Info, varType)            Emitter.EmitLoadObject(Info, varType)            Emitter.MarkLabel(Info, valueTPLoaded)        Else            Emitter.EmitConversion(Compiler.TypeCache.System_Object, varType, Info.Clone(True, True, varType))        End If        Return True    End Function    Friend Overrides Function GenerateCode(ByVal Info As EmitInfo) As Boolean        Dim result As Boolean = True        Dim beginEx As Label        Dim startIteration As Label        result = m_LoopControlVariable.GenerateCode(Info) AndAlso result 'Creates the localbuilder if necessary        m_Enumerator = Info.ILGen.DeclareLocal(Compiler.TypeCache.System_Collections_IEnumerator)        EndLabel = Info.ILGen.DefineLabel        m_NextIteration = Info.ILGen.DefineLabel        startIteration = Info.ILGen.DefineLabel        beginEx = Info.ILGen.BeginExceptionBlock()        Compiler.Helper.AddCheck("Check correct type of foreach loop container.")        Helper.Assert(Helper.CompareType(Compiler.TypeCache.System_Object, m_InExpression.ExpressionType) OrElse Helper.IsAssignable(Compiler, m_InExpression.ExpressionType, Compiler.TypeCache.System_Collections_IEnumerable))        'Load the container variable and get the enumerator        result = m_InExpression.GenerateCode(Info.Clone(True, False, m_InExpression.ExpressionType)) AndAlso result        Emitter.EmitCastClass(Info, m_InExpression.ExpressionType, Compiler.TypeCache.System_Collections_IEnumerable)        Emitter.EmitCallVirt(Info, Compiler.TypeCache.System_Collections_IEnumerable__GetEnumerator)        Emitter.EmitStoreVariable(Info, m_Enumerator)        'Jump to the next iteration        Emitter.EmitBranch(Info, m_NextIteration)        'Mark the beginning of the code        Info.ILGen.MarkLabel(startIteration)        Emitter.EmitNop(Info)        Dim cge As New CompilerGeneratedExpression(Me, New CompilerGeneratedExpression.GenerateCodeDelegate(AddressOf GenerateCode_LoadCurrentLoopVariable), m_LoopControlVariable.VariableType)        result = m_LoopControlVariable.EmitStoreVariable(Info.Clone(cge)) AndAlso result        result = CodeBlock.GenerateCode(Info) AndAlso result        'Move to the next element        Emitter.MarkLabel(Info, m_NextIteration)        Emitter.EmitNop(Info)        Emitter.EmitLoadVariable(Info, m_Enumerator)        Emitter.EmitCallVirt(Info, Compiler.TypeCache.System_Collections_IEnumerator__MoveNext)        'Jump to the code for the next element        Emitter.EmitBranchIfTrue(Info, startIteration)        'End of try code.        'Emitter.EmitLeave(Info, beginEx)        'Dispose of the enumerator if it is disposable.        Emitter.EmitBeginFinallyBlock(Info)        Dim EndFinally As Label = Emitter.DefineLabel(info)        Emitter.EmitLoadVariable(Info, m_Enumerator)        Emitter.EmitIsInst(Info, Compiler.TypeCache.System_Collections_IEnumerator, Compiler.TypeCache.System_IDisposable)        Emitter.EmitBranchIfFalse(Info, EndFinally)        Emitter.EmitLoadVariable(Info, m_Enumerator)        Emitter.EmitIsInst(Info, Compiler.TypeCache.System_Collections_IEnumerator, Compiler.TypeCache.System_IDisposable)        Emitter.EmitCallVirt(Info, Compiler.TypeCache.System_IDisposable__Dispose)        Emitter.MarkLabel(info, EndFinally)        Emitter.EmitEndExceptionBlock(Info)        Emitter.MarkLabel(Info, EndLabel)        Return result    End Function    Public Overrides Function ResolveTypeReferences() As Boolean        Dim result As Boolean = True        If m_LoopControlVariable IsNot Nothing Then result = m_LoopControlVariable.ResolveTypeReferences AndAlso result        If m_InExpression IsNot Nothing Then result = m_InExpression.ResolveTypeReferences AndAlso result        If m_NextExpression IsNot Nothing Then result = m_NextExpression.ResolveTypeReferences AndAlso result        result = MyBase.ResolveTypeReferences AndAlso result        Return result    End Function    Public Overrides Function ResolveStatement(ByVal Info As ResolveInfo) As Boolean        Dim result As Boolean = True        result = m_LoopControlVariable.ResolveCode(Info) AndAlso result        If m_LoopControlVariable.GetVariableDeclaration IsNot Nothing Then            MyBase.CodeBlock.AddVariable(m_LoopControlVariable.GetVariableDeclaration)        End If        result = m_InExpression.ResolveExpression(Info) AndAlso result        result = Helper.VerifyValueClassification(m_InExpression, Info) AndAlso result        result = CodeBlock.ResolveCode(Info) AndAlso result        If m_NextExpression IsNot Nothing Then            result = m_NextExpression.ResolveExpression(Info) AndAlso result            result = Helper.VerifyValueClassification(m_NextExpression, Info) AndAlso result        End If        Compiler.Helper.AddCheck("It is not valid to branch into a For Each statement block from outside the block.")        Compiler.Helper.AddCheck("The loop control variable is specified either through an identifier followed by an As clause or an expression. (...) In the case of an expression, the expression must be classified as a variable. ")        Compiler.Helper.AddCheck("The enumerator expression must be classified as a value and its type must be a collection type or Object. ")        Compiler.Helper.AddCheck("If the type of the enumerator expression is Object, then all processing is deferred until run-time. Otherwise, a conversion must exist from the element type of the collection to the type of the loop control variable")        Compiler.Helper.AddCheck("The loop control variable cannot be used by another enclosing For Each statement. ")        Return result    End FunctionEnd Class

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -