Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support F#ish object expression or Java#ish anonymous clases #120

Open
dadhi opened this issue Jul 21, 2020 · 2 comments
Open

Support F#ish object expression or Java#ish anonymous clases #120

dadhi opened this issue Jul 21, 2020 · 2 comments

Comments

@dadhi
Copy link

dadhi commented Jul 21, 2020

Basically I always wanted this for the in-place IDisposable implementation, but other things could be useful too, e.g. quick Stub implementations in tests:

bool disposed = false;
using var x = new IDisposable { public void Dispose() => disposed = true; };
var depCalled = false;
new Tested(new IDependency { public CalledByTested() => depCalled = true; });
@dadhi dadhi changed the title Support F#ish object expression or Java#ish anonimous Support F#ish object expression or Java#ish anonymous clases Jul 21, 2020
@qwertie
Copy link
Owner

qwertie commented Jan 9, 2021

Hmm, this is the sort of thing that requires non-local transformation (as the usual in-place macro transformations are useless), and I have done these in the past with top-of-file macros like #useSymbols and #ecs that preprocess the entire file and then postprocesses it to make the requested transformation(s).

Edit: I wrote this response without noticing that it doesn't actually do what you wanted. You wanted to define a class inside a method that would edit a local variable of the same method. That's a tough requirement that I haven't attempted to fulfill.

The problem can be broken down into two independent macros. The first macro is a non-local transformation called outsideCurrentMethod:

    outsideCurrentMethod {
        // gee, this class is useless, but it's just an example
        class MyIDisposable : IDisposable {
            bool disposed = false;
            public void Dispose() => disposed = true;
        };
    }
    using var x = new MyIDisposable();

Its job would be to make move something from inside a method to outside a method (and there could be related macros like atNamespaceScope and atOuterScope).

The second macro would be a local transformation giving you what you actually want, an anonymous object. The syntax you suggested is not viable in EC#, but you could use a syntax like this:

    // Note 1: I changed your example to use conventional `using` syntax
    // Note 2: you should really just use on_finally for this sort of thing
    using (var x = anon_object(IDisposable) {
        // I'm assuming we'll make a reference the outer class available
        public void Dispose() => outer.disposed = true;
    }) {
        DoStuffWith(x);
    }

I'd like to see outsideCurrentMethod, atNamespaceScope, atOuterScope included as part of #ecs, but the second macro is something someone could implement themselves with help from outsideCurrentMethod:

#ecs;

define anon_object($(..bases), { $(..content); }) {
	#runSequence {
		outsideCurrentMethod {
			class InnerClassunique# : $bases {
				#outerTypeName outer;
				public InnerClassunique#(#outerTypeName outer) => this.outer = outer; //
								
				$content;
			}
		}
		new InnerClassunique#(this);
	}
}

using (var x = anon_object(IDisposable) { public void Dispose() => outer.disposed = true; }) 
	DoSomethingWith(x);

While trying this macro I ran into more bugs in #useSequenceExpressions, which I fixed. I also realized that it is necessary to know the name of the outer class - above I've pretended that there is another macro called #outerTypeName which reports this piece of information, but a simpler approach is to add another argument to anon_object to explicitly tell it the name of the outer class.

And of course one also needs a macro to transform outsideCurrentMethod.

Might you care to help out by attempting to write the latter macro? If so I can give you tips.

@dadhi
Copy link
Author

dadhi commented Jan 10, 2021

@qwertie I need some time to process it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants