public override AstNode Visit(UsingObjectStatement node) { // Push the scope. PushScope(node.GetScope()); // Visit the declarations. LocalVariablesDeclaration decls = node.GetLocals(); decls.Accept(this); // Visit the children. VisitList(node.GetChildren()); // Pop the scope. PopScope(); return node; }
public override AstNode Visit(UsingObjectStatement node) { // Create the using lexical scope. LexicalScope blockScope = CreateLexicalScope(node); node.SetScope(blockScope); // Push the scope. PushScope(blockScope); // Get the local declarations. LocalVariablesDeclaration decls = node.GetLocals(); decls.Accept(this); // Check if disposing or deleting. IChelaType varType = decls.GetNodeType(); bool pointer = varType.IsPointer(); if(!pointer) { // Make sure it could implement IDisposable. varType = DeReferenceType(varType); if(!varType.IsStructure() && !varType.IsClass() && !varType.IsReference()) Error(node, "cannot dispose object that isn't a structure, class or interface."); // Make sure it does implement IDisposable. Structure building = (Structure) varType; Structure idisposable = currentModule.GetLangMember("IDisposable") as Interface; if(idisposable == null) Error(node, "couldn't find IDisposable"); if(building != idisposable && !building.Implements(idisposable)) Error(node, "object doesn't implement IDisposable."); } // Build the finally clause. TokenPosition position = node.GetPosition(); AstNode finallyChildren = null; AstNode lastChild = null; AstNode decl = decls.GetDeclarations(); while(decl != null) { AstNode disposeStmnt = null; if(pointer) { // Delete the variable Expression variable = new VariableReference(decl.GetName(), position); disposeStmnt = new DeleteStatement(variable, position); } else { // Call the variable dispose. Expression functionExpr = new MemberAccess(new VariableReference(decl.GetName(), position), "Dispose", position); Expression callExpr = new CallExpression(functionExpr, null, position); disposeStmnt = new ExpressionStatement(callExpr, position); } // If not null. Expression notNull = new BinaryOperation(BinaryOperation.OpNEQ, new VariableReference(decl.GetName(), position), new NullConstant(position), position); IfStatement ifStmnt = new IfStatement(notNull, disposeStmnt, null, position); // Link the call. if(lastChild == null) { finallyChildren = lastChild = ifStmnt; } else { lastChild.SetNext(ifStmnt); lastChild = ifStmnt; } // Dispose the next declaration. decl = decl.GetNext(); } // Build the try-finally. FinallyStatement finallyClause = new FinallyStatement(finallyChildren, position); TryStatement tryStatement = new TryStatement(node.GetChildren(), null, finallyClause, position); // Substitute the children with the try. node.SetChildren(tryStatement); // Visit the block children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); return node; }