nemerle
                                
                                
                                
                                    nemerle copied to clipboard
                            
                            
                            
                        Type defined in an assembly level macro is not seen by VS integration
...until VS is restarted.
[MacroUsage (MacroPhase.BeforeInheritance, MacroTargets.Assembly)]
public macro Yaml(name: PExpr, text: PExpr)
{
    def typer = Macros.ImplicitCTX();
    YamlImpl.Transform(typer, name, text);
}
module YamlImpl {
    public Transform(typer: Typer, typeName: PExpr, text: PExpr): PExpr {
        match (typeName, text) {
        | (<[ $(PExpr.Ref(typeName)) ]>, <[ $(PExpr.Literal(Literal.String(text))) ]>) => { 
            def builder = typer.Env.Define(<[ decl:
                public class $typeName {
                }
                ]>);
            builder.Compile();
            <[]>
          }
        | _ => Message.FatalError($"Name must be a symbol and text must be a string, but got $(typeName.GetType().ToString()), $(text.ToString())")
        }
    }
}
Look:

Is it a know issue? Maybe there's a key binding to refresh the VS integration without restarting VS?
To force refresh autocomplete press Shift+Alt+R.
Oh, great, it works! :+1:
It's a major usability issue though, so I think it should be not closed.
Try supply correct location to TypeBuilder with locate macro:
Util.locate(typeName.Location,
{
  def builder = typer.Env.Define(<[ decl:
                public class $typeName {
                }
                ]>);
            builder.Compile();
});
                                    
                                    
                                    
                                
@someone-with-default-username I added Util.locate, but nothing's changed. What it's supposed to do?
It fixes naviagation to definition via F12.
In general architecure of custom type definitions should be based on your own file type. Your macro should parse code from such files and create type builders etc.
It fixes naviagation to definition via F12.
Oh, yes, F12 works :) Cool.
In general architecure of custom type definitions should be based on your own file type. Your macro should parse code from such files and create type builders etc.
Mm. Cannot fully understand you. Do you mean that my macro should accept a file name, than read it, parse and generate types from it? Or you are talking about different things?
Do you mean that my macro should accept a file name, than read it, parse and generate types from it?
In a some way. Currently there is no direct and simple way to make custom syntax plugins in compiler, but it has some helper API.
First of all - IParser - handles custom file extensions. Look at this stub implementation: https://github.com/JetBrains/Nitra/blob/master/Nitra/Nitra.Compiler/Integration/NitraParser.n It turns source file into assembly level macro invokation.
NitraSource macro declarations are here (very simple): https://github.com/JetBrains/Nitra/blob/master/Nitra/Nitra.Compiler/Macros/Macros.n
All actual work done in NitraSourceImpl type: https://github.com/JetBrains/Nitra/blob/master/Nitra/Nitra.Compiler/NitraSource.n Important thing is SubscribeSourceChangedWithCounter method - is subscribes on changes from IDE.
Hm. Interesting. But I'm trying to do a quite different thing: generate types from a non structured source, which can be anything: a json/xml/yaml literal or file, DB of some sort, discoverable web service etc. It's called "type provider" in F#. Look:
type MyService = Service<"http://service.org/foo?get=2">
let x = MyService.Operation1.Foo.Bar  // <-- it's already called the service and generate types
or
type MyJson = Json<"foo: { bar: 1 }">
let x = MyJson.Load("c:\\big.json").foo.bar // it's of type int
So the idea is that you give a TP a "sample" of untyped data and it generated types based on it. Then, at runtime, you can load other data of same shape and get typed access to it.
We are doing similar in NemerleWeb. We generate classes from javascript. It is not a technical problem to do the same as in F#.