protected override bool DoResolve(BlockContext ec) { // // When delegate returns void, only expression statements can be used // if (ec.ReturnType == TypeManager.void_type) { Expr = Expr.Resolve (ec); if (Expr == null) return false; statement = Expr as ExpressionStatement; if (statement == null) Expr.Error_InvalidExpressionStatement (ec); return true; } return base.DoResolve (ec); }
public IEnumerable<CodeAction> GetActions(RefactoringContext context) { //TODO: implement variable assignment & ctor param var varInit = context.GetNode<VariableInitializer>(); if (varInit != null) { AstType type = varInit.GetPrevNode() as AstType; if (type == null) yield break; if (varInit.Parent is FieldDeclaration) yield break; if (CannotExtractField(varInit)) yield break; yield return new CodeAction("Extract field", s=>{ var name = varInit.Name; FieldDeclaration field = new FieldDeclaration(){ ReturnType = type.Clone(), Variables = { new VariableInitializer(name) } }; AstNode nodeToRemove = RemoveDeclaration(varInit) ? varInit.Parent : type; s.Remove(nodeToRemove, true); s.InsertWithCursor(context.TranslateString("Extract field"),Script.InsertPosition.Before,field); s.FormatText(varInit.Parent); }); } var idntf = context.GetNode<Identifier>(); if (idntf == null) yield break; var paramDec = idntf.Parent as ParameterDeclaration; if (paramDec != null) { var ctor = paramDec.Parent as ConstructorDeclaration; if (ctor == null) yield break; MemberReferenceExpression thisField = new MemberReferenceExpression(new ThisReferenceExpression(), idntf.Name, new AstType[]{}); var assign = new AssignmentExpression(thisField, AssignmentOperatorType.Assign, new IdentifierExpression(idntf.Name)); var statement = new ExpressionStatement(assign); var type = (idntf.GetPrevNode() as AstType).Clone(); FieldDeclaration field = new FieldDeclaration(){ ReturnType = type.Clone(), Variables = { new VariableInitializer(idntf.Name) } }; yield return new CodeAction("Extract field", s=>{ s.InsertWithCursor(context.TranslateString("Extract field"),Script.InsertPosition.Before,field); s.AddTo(ctor.Body, statement); }); } }
public void EmitPrologue(EmitContext ec) { var fe_awaiter = new FieldExpr(awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); // // awaiter = expr.GetAwaiter (); // fe_awaiter.EmitAssign(ec, expr, false, false); Label skip_continuation = ec.DefineLabel(); Expression completed_expr; if (IsDynamic) { var rc = new ResolveContext(ec.MemberContext); Arguments dargs = new Arguments(1); dargs.Add(new Argument(fe_awaiter)); completed_expr = new DynamicMemberBinder("IsCompleted", dargs, loc).Resolve(rc); } else { var pe = PropertyExpr.CreatePredefined(is_completed, loc); pe.InstanceExpression = fe_awaiter; completed_expr = pe; } completed_expr.EmitBranchable(ec, skip_continuation, true); base.DoEmit(ec); // // The stack has to be empty before calling await continuation. We handle this // by lifting values which would be left on stack into class fields. The process // is quite complicated and quite hard to test because any expression can possibly // leave a value on the stack. // // Following assert fails when some of expression called before is missing EmitToField // or parent expression fails to find await in children expressions // ec.AssertEmptyStack(); var args = new Arguments(1); var storey = (AsyncTaskStorey)machine_initializer.Storey; var fe_cont = new FieldExpr(storey.Continuation, loc); fe_cont.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); args.Add(new Argument(fe_cont)); if (IsDynamic) { var rc = new ResolveContext(ec.MemberContext); var mg_expr = new Invocation(new MemberAccess(fe_awaiter, "OnCompleted"), args).Resolve(rc); ExpressionStatement es = (ExpressionStatement)mg_expr; es.EmitStatement(ec); } else { var mg_completed = MethodGroupExpr.CreatePredefined(on_completed, fe_awaiter.Type, loc); mg_completed.InstanceExpression = fe_awaiter; // // awaiter.OnCompleted (continuation); // mg_completed.EmitCall(ec, args); } // Return ok machine_initializer.EmitLeave(ec, unwind_protect); ec.MarkLabel(resume_point); ec.MarkLabel(skip_continuation); }
public void ResolveFieldInitializers (BlockContext ec) { Debug.Assert (!IsPartialPart); if (ec.IsStatic) { if (initialized_static_fields == null) return; bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize; int i; ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count]; for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = initialized_static_fields [i]; ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) { s = EmptyExpressionStatement.Instance; } else if (!fi.IsSideEffectFree) { has_complex_initializer = true; } init [i] = s; } for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = initialized_static_fields [i]; // // Need special check to not optimize code like this // static int a = b = 5; // static int b = 0; // if (!has_complex_initializer && fi.IsDefaultInitializer) continue; ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i])); } return; } if (initialized_fields == null) return; for (int i = 0; i < initialized_fields.Count; ++i) { FieldInitializer fi = initialized_fields [i]; // // Clone before resolving otherwise when field initializer is needed // in more than 1 constructor any resolve after the initial one would // only took the resolved expression which is problem for expressions // that generate extra expressions or code during Resolve phase // var cloned = fi.Clone (new CloneContext ()); ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) { initialized_fields [i] = new FieldInitializer (fi.Field, ErrorExpression.Instance, Location.Null); continue; } // // Field is re-initialized to its default value => removed // if (fi.IsDefaultInitializer && Kind != MemberKind.Struct && ec.Module.Compiler.Settings.Optimize) continue; ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (s)); initialized_fields [i] = (FieldInitializer) cloned; } }
public DynamicEventCompoundAssign(string name, Arguments args, ExpressionStatement assignment, ExpressionStatement invoke, Location loc) : base(null, args, loc) { this.name = name; base.binder = this; // Used by += or -= only type = TypeManager.bool_type; condition = new If ( new Binary (Binary.Operator.Equality, this, new BoolLiteral (true, loc), loc), new StatementExpression (invoke), new StatementExpression (assignment), loc); }
protected override Expression DoResolve (ResolveContext ec) { // Field initializer can be resolved (fail) many times if (source == null) return null; if (resolved == null) { var ctx = new FieldInitializerContext (mc, ec); resolved = base.DoResolve (ctx) as ExpressionStatement; } return resolved; }
public override object Visit (StatementErrorExpression statementErrorExpression) { var result = new ExpressionStatement (); var expr = statementErrorExpression.Expression.Accept (this) as Expression; if (expr != null) result.AddChild ((Expression)expr, ExpressionStatement.Roles.Expression); return result; }
public DynamicEventCompoundAssign (string name, Arguments args, ExpressionStatement assignment, ExpressionStatement invoke, Location loc) : base (null, args, loc) { this.name = name; this.assignment = assignment; this.invoke = invoke; base.binder = this; // Used by += or -= only type = TypeManager.bool_type; }
public StatementExpression (ExpressionStatement expr) { this.expr = expr; loc = expr.Location; }
public override IEnumerable<CodeAction> GetActions(RefactoringContext context) { //TODO: implement variable assignment & ctor param var varInit = context.GetNode<VariableInitializer>(); if (varInit != null) { var selectedNode = varInit.GetNodeAt(context.Location); if (selectedNode != varInit.NameToken) yield break; AstType type = varInit.GetPrevNode() as AstType; if (type == null) yield break; if (varInit.Parent is FieldDeclaration) yield break; if (CannotExtractField(context, varInit)) yield break; yield return new CodeAction(context.TranslateString("Assign to new field"), s=>{ var name = varInit.Name; AstType extractedType; if (type.IsVar()) { IType resolvedType = context.Resolve(varInit.Initializer).Type; extractedType = context.CreateShortType(resolvedType); } else { extractedType = (AstType) type.Clone(); } AstNode entityDeclarationNode = varInit.Parent; while (!(entityDeclarationNode is EntityDeclaration) || (entityDeclarationNode is Accessor)) { entityDeclarationNode = entityDeclarationNode.Parent; } var entity = (EntityDeclaration) entityDeclarationNode; bool isStatic = entity.HasModifier(Modifiers.Static); FieldDeclaration field = new FieldDeclaration(){ Modifiers = isStatic ? Modifiers.Static : Modifiers.None, ReturnType = extractedType, Variables = { new VariableInitializer(name) } }; AstNode nodeToRemove = RemoveDeclaration(varInit) ? varInit.Parent : type; s.Remove(nodeToRemove, true); s.InsertWithCursor(context.TranslateString("Insert new field"),Script.InsertPosition.Before,field); s.FormatText(varInit.Parent); }, varInit); } var idntf = context.GetNode<Identifier>(); if (idntf == null) yield break; var paramDec = idntf.Parent as ParameterDeclaration; if (paramDec != null) { var ctor = paramDec.Parent as ConstructorDeclaration; if (ctor == null) yield break; MemberReferenceExpression thisField = new MemberReferenceExpression(new ThisReferenceExpression(), idntf.Name, new AstType[]{}); var assign = new AssignmentExpression(thisField, AssignmentOperatorType.Assign, new IdentifierExpression(idntf.Name)); var statement = new ExpressionStatement(assign); var type = (idntf.GetPrevNode() as AstType).Clone(); FieldDeclaration field = new FieldDeclaration(){ ReturnType = type.Clone(), Variables = { new VariableInitializer(idntf.Name) } }; yield return new CodeAction(context.TranslateString("Assign to new field"), s=>{ s.InsertWithCursor(context.TranslateString("Insert new field"),Script.InsertPosition.Before,field); s.AddTo(ctor.Body, statement); }, paramDec); } }
public override bool Resolve (EmitContext ec) { if (expr != null) expr = expr.ResolveStatement (ec); return expr != null; }
bool ResolveVariable (EmitContext ec) { ExpressionStatement a = new SimpleAssign (var, init, loc); a = a.ResolveStatement (ec); if (a == null) return false; assign = a; if (TypeManager.ImplementsInterface (a.Type, TypeManager.idisposable_type)) { converted_var = var; return true; } Expression e = Convert.ImplicitConversionStandard (ec, a, TypeManager.idisposable_type, var.Location); if (e == null) { Error_IsNotConvertibleToIDisposable (var); return false; } converted_var = e; return true; }
void ResolveStringSwitchMap (EmitContext ec) { FullNamedExpression string_dictionary_type; #if GMCS_SOURCE MemberAccess system_collections_generic = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc), "Generic", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Dictionary", new TypeArguments ( new TypeExpression (TypeManager.string_type, loc), new TypeExpression (TypeManager.int32_type, loc)), loc); #else MemberAccess system_collections_generic = new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc); #endif Field field = new Field (ec.TypeContainer, string_dictionary_type, Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null); if (!field.Define ()) return; ec.TypeContainer.PartialContainer.AddField (field); ArrayList init = new ArrayList (); int counter = 0; Elements.Clear (); string value = null; foreach (SwitchSection section in Sections) { foreach (SwitchLabel sl in section.Labels) { if (sl.Label == null || sl.Converted == SwitchLabel.NullStringCase) { value = null; continue; } value = (string) sl.Converted; ArrayList init_args = new ArrayList (2); init_args.Add (new StringLiteral (value, sl.Location)); init_args.Add (new IntConstant (counter, loc)); init.Add (new CollectionElementInitializer (init_args, loc)); } if (value == null) continue; Elements.Add (counter, section.Labels [0]); ++counter; } ArrayList args = new ArrayList (1); args.Add (new Argument (new IntConstant (Sections.Count, loc))); Expression initializer = new NewInitialize (string_dictionary_type, args, new CollectionOrObjectInitializers (init, loc), loc); switch_cache_field = new FieldExpr (field.FieldBuilder, loc); string_dictionary = new SimpleAssign (switch_cache_field, initializer.Resolve (ec)); }
public override bool Resolve (BlockContext ec) { if (expr != null && expr.eclass == ExprClass.Invalid) expr = expr.ResolveStatement (ec); return expr != null; }
void DoResolveFieldInitializers (BlockContext ec) { if (ec.IsStatic) { if (initialized_static_fields == null) return; bool has_complex_initializer = !RootContext.Optimize; int i; ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count]; for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = (FieldInitializer) initialized_static_fields [i]; ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) { s = EmptyExpressionStatement.Instance; } else if (fi.IsComplexInitializer) { has_complex_initializer |= true; } init [i] = s; } for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = (FieldInitializer) initialized_static_fields [i]; // // Need special check to not optimize code like this // static int a = b = 5; // static int b = 0; // if (!has_complex_initializer && fi.IsDefaultInitializer) continue; ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i])); } return; } if (initialized_fields == null) return; for (int i = 0; i < initialized_fields.Count; ++i) { FieldInitializer fi = (FieldInitializer) initialized_fields [i]; ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) continue; // // Field is re-initialized to its default value => removed // if (fi.IsDefaultInitializer && RootContext.Optimize) continue; ec.CurrentBlock.AddScopeStatement (new StatementExpression (s)); } }
void ResolveStringSwitchMap (ResolveContext ec) { FullNamedExpression string_dictionary_type; if (TypeManager.generic_ienumerable_type != null) { MemberAccess system_collections_generic = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc), "Generic", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Dictionary", new TypeArguments ( new TypeExpression (TypeManager.string_type, loc), new TypeExpression (TypeManager.int32_type, loc)), loc); } else { MemberAccess system_collections_generic = new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc); } var ctype = ec.CurrentMemberDefinition.Parent.PartialContainer; Field field = new Field (ctype, string_dictionary_type, Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null); if (!field.Define ()) return; ctype.AddField (field); var init = new List<Expression> (); int counter = 0; Elements.Clear (); string value = null; foreach (SwitchSection section in Sections) { int last_count = init.Count; foreach (SwitchLabel sl in section.Labels) { if (sl.Label == null || sl.Converted == SwitchLabel.NullStringCase) continue; value = (string) sl.Converted; var init_args = new List<Expression> (2); init_args.Add (new StringLiteral (value, sl.Location)); init_args.Add (new IntConstant (counter, loc)); init.Add (new CollectionElementInitializer (init_args, loc)); } // // Don't add empty sections // if (last_count == init.Count) continue; Elements.Add (counter, section.Labels [0]); ++counter; } Arguments args = new Arguments (1); args.Add (new Argument (new IntConstant (init.Count, loc))); Expression initializer = new NewInitialize (string_dictionary_type, args, new CollectionOrObjectInitializers (init, loc), loc); switch_cache_field = new FieldExpr (field, loc); string_dictionary = new SimpleAssign (switch_cache_field, initializer.Resolve (ec)); }
public override bool Resolve (BlockContext ec) { bool is_dynamic = expr.Type == InternalType.Dynamic; if (is_dynamic) { expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc); } else if (TypeManager.IsNullableType (expr.Type)) { expr = new Nullable.UnwrapCall (expr).Resolve (ec); } var get_enumerator_mg = ResolveGetEnumerator (ec); if (get_enumerator_mg == null) { return false; } var get_enumerator = get_enumerator_mg.BestCandidate; enumerator_variable = TemporaryVariableReference.Create (get_enumerator.ReturnType, variable.Block, loc); enumerator_variable.Resolve (ec); // Prepare bool MoveNext () var move_next_mg = ResolveMoveNext (ec, get_enumerator); if (move_next_mg == null) { return false; } move_next_mg.InstanceExpression = enumerator_variable; // Prepare ~T~ Current { get; } var current_prop = ResolveCurrent (ec, get_enumerator); if (current_prop == null) { return false; } var current_pe = new PropertyExpr (current_prop, loc) { InstanceExpression = enumerator_variable }.Resolve (ec); if (current_pe == null) return false; VarExpr ve = var_type as VarExpr; if (ve != null) { if (is_dynamic) { // Source type is dynamic, set element type to dynamic too var_type = new TypeExpression (InternalType.Dynamic, var_type.Location); } else { // Infer implicitly typed local variable from foreach enumerable type var_type = new TypeExpression (current_pe.Type, var_type.Location); } } else if (is_dynamic) { // Explicit cast of dynamic collection elements has to be done at runtime current_pe = EmptyCast.Create (current_pe, InternalType.Dynamic); } var_type = var_type.ResolveAsTypeTerminal (ec, false); if (var_type == null) return false; variable.Type = var_type.Type; var init = new Invocation (get_enumerator_mg, null); statement = new While (new BooleanExpression (new Invocation (move_next_mg, null)), new Body (var_type.Type, variable, current_pe, statement, loc), loc); var enum_type = enumerator_variable.Type; // // Add Dispose method call when enumerator can be IDisposable // if (!enum_type.ImplementsInterface (TypeManager.idisposable_type, false)) { if (!enum_type.IsSealed && !TypeManager.IsValueType (enum_type)) { // // Runtime Dispose check // var vd = new RuntimeDispose (enumerator_variable.LocalInfo, loc); vd.Initializer = init; statement = new Using (vd, statement, loc); } else { // // No Dispose call needed // this.init = new SimpleAssign (enumerator_variable, init); this.init.Resolve (ec); } } else { // // Static Dispose check // var vd = new Using.VariableDeclaration (enumerator_variable.LocalInfo, loc); vd.Initializer = init; statement = new Using (vd, statement, loc); } return statement.Resolve (ec); }
protected override bool DoResolve (BlockContext ec) { // // When delegate returns void, only expression statements can be used // if (ec.ReturnType.Kind == MemberKind.Void) { Expr = Expr.Resolve (ec); if (Expr == null) return false; statement = Expr as ExpressionStatement; if (statement == null) { var reduced = Expr as IReducedExpressionStatement; if (reduced != null) { statement = EmptyExpressionStatement.Instance; } else { Expr.Error_InvalidExpressionStatement (ec); } } return true; } return base.DoResolve (ec); }
public override bool Resolve (BlockContext ec) { expr = expr.ResolveStatement (ec); return expr != null; }
public static ExpressionStatement Create(ExpressionStatement s, Expression orig) { return new ReducedExpressionStatement (s, orig); }
public override object Visit (StatementExpression statementExpression) { var result = new ExpressionStatement (); var expr = statementExpression.Expr.Accept (this) as Expression; if (expr != null) result.AddChild ((Expression)expr, ExpressionStatement.Roles.Expression); var location = LocationsBag.GetLocations (statementExpression); if (location != null) result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), ExpressionStatement.Roles.Semicolon); return result; }
public ReducedExpressionStatement(ExpressionStatement stm, Expression orig) { this.orig_expr = orig; this.stm = stm; this.loc = orig.Location; }
public DynamicEventCompoundAssign (string name, Arguments args, ExpressionStatement assignment, ExpressionStatement invoke, Location loc) { condition = new IsEvent (name, args, loc); this.invoke = invoke; this.assign = assignment; this.loc = loc; }
protected override Expression DoResolve (ResolveContext ec) { // Field initializer can be resolved (fail) many times if (source == null) return null; if (resolved == null) { // // Field initializers are tricky for partial classes. They have to // share same constructor (block) but they have they own resolve scope. // IMemberContext old = ec.MemberContext; ec.MemberContext = rc; using (ec.Set (ResolveContext.Options.FieldInitializerScope)) { resolved = base.DoResolve (ec) as ExpressionStatement; } ec.MemberContext = old; } return resolved; }
public override object Visit(InvalidStatementExpression invalidStatementExpression) { var result = new ExpressionStatement(); if (invalidStatementExpression.Expression == null) return result; var expr = invalidStatementExpression.Expression.Accept(this) as Expression; if (expr != null) result.AddChild(expr, Roles.Expression); var location = LocationsBag.GetLocations(invalidStatementExpression); if (location != null) result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon); return result; }
bool ResolveVariable (BlockContext ec) { assign = new SimpleAssign (var, init, loc); assign = assign.ResolveStatement (ec); if (assign == null) return false; if (assign.Type == TypeManager.idisposable_type || assign.Type.ImplementsInterface (TypeManager.idisposable_type)) { return true; } Expression e = Convert.ImplicitConversionStandard (ec, assign, TypeManager.idisposable_type, var.Location); if (e == null) { if (assign.Type == InternalType.Dynamic) { e = Convert.ImplicitConversionRequired (ec, assign, TypeManager.idisposable_type, loc); var = new TemporaryVariable (e.Type, loc); assign = new SimpleAssign (var, e, loc).ResolveStatement (ec); return true; } Error_IsNotConvertibleToIDisposable (ec, var); return false; } throw new NotImplementedException ("covariance?"); }
protected override Expression DoResolve (ResolveContext rc) { // Field initializer can be resolved (fail) many times if (source == null) return null; var bc = (BlockContext) rc; if (resolved == null) { var ctx = new FieldInitializerContext (mc, bc); resolved = base.DoResolve (ctx) as ExpressionStatement; AssignmentOffset = ctx.AssignmentInfoOffset - bc.AssignmentInfoOffset; } return resolved; }
public override bool Resolve (BlockContext ec) { bool is_dynamic = expr.Type == InternalType.Dynamic; if (is_dynamic) expr = Convert.ImplicitConversionRequired (ec, expr, TypeManager.ienumerable_type, loc); var get_enumerator_mg = ResolveGetEnumerator (ec); if (get_enumerator_mg == null) { return false; } var get_enumerator = get_enumerator_mg.BestCandidate; var enumerator = new TemporaryVariable (get_enumerator.ReturnType, loc); enumerator.Resolve (ec); // Prepare bool MoveNext () var move_next_mg = ResolveMoveNext (ec, get_enumerator); if (move_next_mg == null) { return false; } move_next_mg.InstanceExpression = enumerator; // Prepare ~T~ Current { get; } var current_prop = ResolveCurrent (ec, get_enumerator); if (current_prop == null) { return false; } var current_pe = new PropertyExpr (current_prop, loc) { InstanceExpression = enumerator }.Resolve (ec); if (current_pe == null) return false; VarExpr ve = var_type as VarExpr; if (ve != null) { // Infer implicitly typed local variable from foreach enumerable type var_type = new TypeExpression (current_pe.Type, var_type.Location); } var_type = var_type.ResolveAsTypeTerminal (ec, false); if (var_type == null) return false; var init = new Invocation (get_enumerator_mg, null); init.Resolve (ec); statement = new While (new BooleanExpression (new Invocation (move_next_mg, null)), new Body (var_type.Type, variable, current_pe, statement, loc), loc); var enum_type = enumerator.Type; // // Add Dispose method call when enumerator can be IDisposable // if (!enumerator.Type.ImplementsInterface (TypeManager.idisposable_type)) { if (!enum_type.IsSealed && !TypeManager.IsValueType (enum_type)) { // // Runtime Dispose check // var tv = new LocalTemporary (TypeManager.idisposable_type); statement = new Dispose (enumerator, tv, init, statement, loc); } else { // // No Dispose call needed // this.init = new SimpleAssign (enumerator, init); this.init.Resolve (ec); } } else { // // Static Dispose check // statement = new Dispose (enumerator, null, init, statement, loc); } return statement.Resolve (ec); }
public void ResolveFieldInitializers (BlockContext ec) { Debug.Assert (!IsPartialPart); if (ec.IsStatic) { if (initialized_static_fields == null) return; bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize; int i; ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count]; for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = initialized_static_fields [i]; ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) { s = EmptyExpressionStatement.Instance; } else if (!fi.IsSideEffectFree) { has_complex_initializer |= true; } init [i] = s; } for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = initialized_static_fields [i]; // // Need special check to not optimize code like this // static int a = b = 5; // static int b = 0; // if (!has_complex_initializer && fi.IsDefaultInitializer) continue; ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i])); } return; } if (initialized_fields == null) return; for (int i = 0; i < initialized_fields.Count; ++i) { FieldInitializer fi = initialized_fields [i]; ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) continue; // // Field is re-initialized to its default value => removed // if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize) continue; ec.CurrentBlock.AddScopeStatement (new StatementExpression (s)); } }
public DynamicEventCompoundAssign(string name, Arguments args, ExpressionStatement assignment, ExpressionStatement invoke, Location loc) { condition = new IsEvent(name, args, loc); this.invoke = invoke; this.assign = assignment; this.loc = loc; }