internal void InitializeInterfaces(ITypeReference elementType, bool isEnumerable) { var methodTypeArguments = new List <ITypeReference>(); methodTypeArguments.Add(elementType); ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, methodTypeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, methodTypeArguments, this.host.InternFactory); ITypeReference nongenericEnumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; ITypeReference nongenericEnumerableType = this.host.PlatformType.SystemCollectionsIEnumerable; ITypeReference iDisposable = this.PlatformIDisposable; if (isEnumerable) { this.NonGenericIEnumerableInterface = nongenericEnumerableType; } this.NonGenericIEnumeratorInterface = nongenericEnumeratorType; if (isEnumerable) { this.GenericIEnumerableInterface = genericEnumerableType; } this.GenericIEnumeratorInterface = genericEnumeratorType; this.DisposableInterface = iDisposable; }
public override IStatement Rewrite(IForEachStatement forEachStatement) { ILocalDefinition foreachLocal; var key = forEachStatement.Collection.Type.InternedKey; ITypeReference enumeratorType; IMethodReference getEnumerator; IMethodReference getCurrent; var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference; if (gtir != null) { var typeArguments = gtir.GenericArguments; ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory); enumeratorType = genericEnumeratorType; getEnumerator = new SpecializedMethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = genericEnumerableType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List <IParameterTypeInformation>(), Type = genericEnumeratorType, UnspecializedVersion = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = this.host.PlatformType.SystemCollectionsGenericIEnumerable, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List <IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsGenericIEnumerator, }, }; var getEnumerator2 = (IMethodReference) IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)); getEnumerator = getEnumerator2; getCurrent = (IMethodReference)IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)); } else { enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; getEnumerator = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List <IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsIEnumerable, }; getCurrent = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("get_Current"), Parameters = new List <IParameterTypeInformation>(), Type = this.host.PlatformType.SystemObject, }; } var initializer = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getEnumerator, ThisArgument = forEachStatement.Collection, Type = enumeratorType, }; IStatement initialization; if (!this.foreachLocals.TryGetValue(key, out foreachLocal)) { foreachLocal = new LocalDefinition() { Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count) }; this.foreachLocals.Add(key, foreachLocal); initialization = new LocalDeclarationStatement() { InitialValue = initializer, LocalVariable = foreachLocal, }; } else { initialization = new ExpressionStatement() { Expression = new Assignment() { Source = initializer, Target = new TargetExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, Type = foreachLocal.Type, }, }; } var newStmts = new List <IStatement>(); newStmts.Add(new ExpressionStatement() { Expression = new Assignment() { Source = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getCurrent, ThisArgument = new BoundExpression() { Definition = foreachLocal, Instance = null, }, Type = forEachStatement.Variable.Type, }, Target = new TargetExpression() { Definition = forEachStatement.Variable, Instance = null, }, Type = forEachStatement.Variable.Type, }, }); newStmts.Add(forEachStatement.Body); var newBody = new BlockStatement() { Statements = newStmts, }; var result = new BlockStatement() { Statements = new List <IStatement>() { initialization, new TryCatchFinallyStatement() { TryBody = new BlockStatement() { Statements = new List <IStatement>() { new WhileDoStatement() { Body = newBody, Condition = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = moveNext, ThisArgument = new BoundExpression() { Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemBoolean, }, }, }, }, FinallyBody = new BlockStatement() { Statements = new List <IStatement>() { new ConditionalStatement() { Condition = new Equality() { LeftOperand = new BoundExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, RightOperand = new CompileTimeConstant() { Type = foreachLocal.Type, Value = null, }, Type = this.host.PlatformType.SystemBoolean, }, FalseBranch = new EmptyStatement(), TrueBranch = new ExpressionStatement() { Expression = new MethodCall() { Arguments = new List <IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = this.disposeMethod, ThisArgument = new BoundExpression() { Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemVoid, }, }, }, }, }, }, }, }; return(result); }
internal void InitializeInterfaces(ITypeReference elementType, bool isEnumerable) { var methodTypeArguments = new List<ITypeReference>(); methodTypeArguments.Add(elementType); ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, methodTypeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, methodTypeArguments, this.host.InternFactory); ITypeReference nongenericEnumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; ITypeReference nongenericEnumerableType = this.host.PlatformType.SystemCollectionsIEnumerable; ITypeReference iDisposable = this.PlatformIDisposable; if (isEnumerable) this.NonGenericIEnumerableInterface = nongenericEnumerableType; this.NonGenericIEnumeratorInterface = nongenericEnumeratorType; if (isEnumerable) this.GenericIEnumerableInterface = genericEnumerableType; this.GenericIEnumeratorInterface = genericEnumeratorType; this.DisposableInterface = iDisposable; }
/// <summary /> public override IStatement Rewrite(IForEachStatement forEachStatement) { ILocalDefinition foreachLocal; var key = forEachStatement.Collection.Type.InternedKey; ITypeReference enumeratorType; IMethodReference getEnumerator; IMethodReference getCurrent; var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference; if (gtir != null) { var typeArguments = gtir.GenericArguments; ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory); enumeratorType = genericEnumeratorType; getEnumerator = new SpecializedMethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = genericEnumerableType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = genericEnumeratorType, UnspecializedVersion = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = this.host.PlatformType.SystemCollectionsGenericIEnumerable, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsGenericIEnumerator, }, }; var getEnumerator2 = (IMethodReference) IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)); getEnumerator = getEnumerator2; getCurrent = (IMethodReference) IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)); } else { enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; getEnumerator = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsIEnumerable, }; getCurrent = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("get_Current"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemObject, }; } var initializer = new MethodCall() { Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getEnumerator, ThisArgument = forEachStatement.Collection, Type = enumeratorType, }; IStatement initialization; if (!this.foreachLocals.TryGetValue(key, out foreachLocal)) { foreachLocal = new LocalDefinition() { Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count) }; this.foreachLocals.Add(key, foreachLocal); initialization = new LocalDeclarationStatement() { InitialValue = initializer, LocalVariable = foreachLocal, }; } else { initialization = new ExpressionStatement() { Expression = new Assignment() { Source = initializer, Target = new TargetExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, Type = foreachLocal.Type, }, }; } var newStmts = new List<IStatement>(); newStmts.Add(new ExpressionStatement(){ Expression = new Assignment(){ Source = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getCurrent, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = forEachStatement.Variable.Type, }, Target = new TargetExpression(){ Definition = forEachStatement.Variable, Instance = null, }, Type = forEachStatement.Variable.Type, }, }); newStmts.Add(forEachStatement.Body); var newBody = new BlockStatement(){ Statements = newStmts,}; var result = new BlockStatement() { Statements = new List<IStatement>(){ initialization, new TryCatchFinallyStatement(){ TryBody = new BlockStatement() { Statements = new List<IStatement>(){ new WhileDoStatement(){ Body = newBody, Condition = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = moveNext, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemBoolean, }, }, }, }, FinallyBody = new BlockStatement() { Statements = new List<IStatement>(){ new ConditionalStatement(){ Condition = new Equality(){ LeftOperand = new BoundExpression(){ Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, RightOperand = new CompileTimeConstant(){ Type = foreachLocal.Type, Value = null, }, Type = this.host.PlatformType.SystemBoolean, }, FalseBranch = new EmptyStatement(), TrueBranch = new ExpressionStatement(){ Expression = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = this.disposeMethod, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemVoid, }, }, }, }, }, }, }, }; return result; }