X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Feval.cs;h=766bb05696b6f9e815d0b80ee621c3e1c54194f7;hb=c39718bbb394fe97281e6e64945b4572bef29121;hp=b1ac4dd3eee7a3f6be968bd0ccd4f6d4a77a2e5f;hpb=c018aea7e9161343160b78f46d3afba81ce54bd0;p=mono.git diff --git a/mcs/mcs/eval.cs b/mcs/mcs/eval.cs index b1ac4dd3eee..766bb05696b 100644 --- a/mcs/mcs/eval.cs +++ b/mcs/mcs/eval.cs @@ -131,6 +131,12 @@ namespace Mono.CSharp Location.Initialize (ctx.SourceFiles); } + /// + /// When set evaluator will automatically wait on Task of async methods. When not + /// set it's called responsibility to handle Task execution + /// + public bool WaitOnTask { get; set; } + /// /// If true, turns type expressions into valid expressions /// and calls the describe method on it @@ -364,8 +370,14 @@ namespace Mono.CSharp if (parser == null){ return null; } - - Class parser_result = parser.InteractiveResult; + + Class host = parser.InteractiveResult; + + var base_class_imported = importer.ImportType (base_class); + var baseclass_list = new List (1) { + new TypeExpression (base_class_imported, host.Location) + }; + host.SetBaseTypes (baseclass_list); #if NET_4_0 var access = AssemblyBuilderAccess.RunAndCollect; @@ -377,13 +389,15 @@ namespace Mono.CSharp module.SetDeclaringAssembly (a); // Need to setup MemberCache - parser_result.CreateContainer (); + host.CreateContainer (); + // Need to setup base type + host.DefineContainer (); - var method = parser_result.Members[0] as Method; + var method = host.Members[0] as Method; BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void); try { - method.Block.Resolve (null, bc, method); + method.Block.Resolve (bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; @@ -429,7 +443,7 @@ namespace Mono.CSharp throw new ArgumentException ("Syntax error on input: partial input"); if (result_set == false) - throw new ArgumentException ("The expression did not set a result"); + throw new ArgumentException ("The expression failed to resolve"); return result; } @@ -453,7 +467,7 @@ namespace Mono.CSharp // InputKind ToplevelOrStatement (SeekableStreamReader seekable) { - Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession ()); + Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession (), ctx.Report); // Prefer contextual block keywords over identifiers tokenizer.parsing_block++; @@ -655,13 +669,49 @@ namespace Mono.CSharp new TypeExpression (base_class_imported, host.Location) }; - host.AddBasesForPart (baseclass_list); - - host.CreateContainer (); - host.DefineContainer (); - host.Define (); + host.SetBaseTypes (baseclass_list); expression_method = (Method) host.Members[0]; + + if ((expression_method.ModFlags & Modifiers.ASYNC) != 0) { + // + // Host method is async. When WaitOnTask is set we wrap it with wait + // + // void AsyncWait (ref object $retval) { + // $retval = Host(); + // ((Task)$retval).Wait(); // When WaitOnTask is set + // } + // + var p = new ParametersCompiled ( + new Parameter (new TypeExpression (module.Compiler.BuiltinTypes.Object, Location.Null), "$retval", Parameter.Modifier.REF, null, Location.Null) + ); + + var method = new Method(host, new TypeExpression(module.Compiler.BuiltinTypes.Void, Location.Null), + Modifiers.PUBLIC | Modifiers.STATIC, new MemberName("AsyncWait"), p, null); + + method.Block = new ToplevelBlock(method.Compiler, p, Location.Null); + method.Block.AddStatement(new StatementExpression (new SimpleAssign( + new SimpleName(p [0].Name, Location.Null), + new Invocation(new SimpleName(expression_method.MemberName.Name, Location.Null), new Arguments(0)), + Location.Null), Location.Null)); + + if (WaitOnTask) { + var task = new Cast (expression_method.TypeExpression, new SimpleName (p [0].Name, Location.Null), Location.Null); + + method.Block.AddStatement (new StatementExpression (new Invocation ( + new MemberAccess (task, "Wait", Location.Null), + new Arguments (0)), Location.Null)); + } + + host.AddMember(method); + + expression_method = method; + } + + host.CreateContainer(); + host.DefineContainer(); + host.Define(); + } else { expression_method = null; } @@ -996,9 +1046,7 @@ namespace Mono.CSharp static public string help { get { return "Static methods:\n" + -#if !NET_2_1 " Describe (object); - Describes the object's type\n" + -#endif " LoadPackage (package); - Loads the given Package (like -pkg:FILE)\n" + " LoadAssembly (assembly); - Loads the given assembly (like -r:ASSEMBLY)\n" + " ShowVars (); - Shows defined local variables.\n" + @@ -1056,6 +1104,27 @@ namespace Mono.CSharp #endif } + class InteractiveMethod : Method + { + public InteractiveMethod(TypeDefinition parent, FullNamedExpression returnType, Modifiers mod, ParametersCompiled parameters) + : base(parent, returnType, mod, new MemberName("Host"), parameters, null) + { + } + + public void ChangeToAsync () + { + ModFlags |= Modifiers.ASYNC; + ModFlags &= ~Modifiers.UNSAFE; + type_expr = new TypeExpression(Module.PredefinedTypes.Task.TypeSpec, Location); + parameters = ParametersCompiled.EmptyReadOnlyParameters; + } + + public override string GetSignatureForError() + { + return "InteractiveHost"; + } + } + class HoistedEvaluatorVariable : HoistedVariable { public HoistedEvaluatorVariable (Field field) @@ -1076,11 +1145,17 @@ namespace Mono.CSharp /// the return value for an invocation. /// class OptionalAssign : SimpleAssign { - public OptionalAssign (Expression t, Expression s, Location loc) - : base (t, s, loc) + public OptionalAssign (Expression s, Location loc) + : base (null, s, loc) { } + public override Location StartLocation { + get { + return Location.Null; + } + } + protected override Expression DoResolve (ResolveContext ec) { Expression clone = source.Clone (new CloneContext ()); @@ -1093,7 +1168,7 @@ namespace Mono.CSharp // A useful feature for the REPL: if we can resolve the expression // as a type, Describe the type; // - if (ec.Module.Evaluator.DescribeTypeExpressions){ + if (ec.Module.Evaluator.DescribeTypeExpressions && !(ec.CurrentAnonymousMethod is AsyncInitializer)) { var old_printer = ec.Report.SetPrinter (new SessionReportPrinter ()); Expression tclone; try { @@ -1119,17 +1194,34 @@ namespace Mono.CSharp } source = clone; + + var host = (Method) ec.MemberContext.CurrentMemberDefinition; + + if (host.ParameterInfo.IsEmpty) { + eclass = ExprClass.Value; + type = InternalType.FakeInternalType; + return this; + } + + target = new SimpleName (host.ParameterInfo[0].Name, Location); + return base.DoResolve (ec); } + + public override void EmitStatement(EmitContext ec) + { + if (target == null) { + source.Emit (ec); + return; + } + + base.EmitStatement(ec); + } } public class Undo { List undo_actions; - - public Undo () - { - } public void AddTypeContainer (TypeContainer current_container, TypeDefinition tc) {