-
Notifications
You must be signed in to change notification settings - Fork 78
Generate record stubs #365
Generate record stubs #365
Conversation
Can you please squash all these merge commits? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not turn deployment in the Release configuration. It breaks our CI build.
First suggestion: don't use Please use known default values for primitive types (those in this table http://stackoverflow.com/questions/17251025/what-where-is-get-zero-in-fs-int/17251353#17251353 plus |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this convention is very good. It's unlikely you'll use any of this ignored values in the future. The following code reads much easier:
| SynMemberDefn.AutoProperty(_, _, _, _, _, _, _, _, expr, _, _) ->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy paste driven development from Anh-Dung :)
I'll clean it up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general I agree.
However, when dealing with ASTs, I prefer to keep available information since it gives the structural view of the ASTs. When you do bug fixing or look at the code after a few months, it's really hard to know what you did miss. We shouldn't rely on intellisense to know about the structural info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @dungpa, dealing with large number of positional wildcards can be difficult - in fact it was one of motivations behind adding named fields for DUs so matching can be performed selectively by name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dungpa Why do we not use 3.1 compiler? Does the CI server not support it? Or VS 2012? I remember I added names to https://github.com/fsprojects/VisualFSharpPowerTools/blob/master/src/FSharpVSPowerTools.Core/XmlDocParser.fs#L4 and the solution compiled OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still keep a VS2012 solution around and use it to diagnose problems in VS2012. For that purpose, the source code only uses the subset supported by F# 3.0. I'm not sure how to deal with versioning issues properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought Visual F# Tools 3.1.1 update supports VS 2012.
@dungpa Isn't that what we want? I did it on purpose, because if you put default values you can easily forget to initialize some fields. To you, what's the difference with interface implementation stubs that raise exceptions? What's your opinion @vasily-kirichenko? |
How do you squash these merge commits when they're older than the moment where the branch was created? Moreover they're interleaved with other commits? |
@OkayX6 Something like this: let r: R = { F1 = <string>; F2 = <DU1>; F3 = <Choice<int option, exn>>; F4 = { FieldOfAnotherRecord1 = <int> }} It's not compilable and has nice type hints. |
That's all nice, but I cannot remember I've ever written let r: R = { ... What about |
We don't do intellisense so autocompletion is probably out of the question. Could we do something like:
It effectively works as intellisense, instead of pressing Ctrl + Space, we use mouse and click on contextual smart tags. What do you think? |
Also consider the name of the record type itself on that list, as you can do |
The simplest thing I can think of is is to inject the currently defined record types (in the source/ project/ reference) into the completion list mechanism. I think that's how I would approach it in XS. Ive not been keeping up with the api changes in FCS is there an efficient typed symbol search mechanism?
|
@vasily-kirichenko Ok, I like your suggestion. @dungpa @ovatsus Yes these are nice options too. We can do all of them, as we don't always remember record field names exactly. @7sharp9 That's what I wanted to do as it appeared to be the best approach to me. But I didn't know how to play with the intellisense mechanism. Do you think http://msdn.microsoft.com/en-us/library/vstudio/ee372314(v=vs.100).aspx is the way to go?
If someone is willing to investigate the completion list mechanism, please do. I might still continue experimenting, because I think we'd still be able to reuse most of the code. |
@dungpa I like your idea about showing the smarttag when user enters a field (or maybe part / start of a field? or even Yes, it's quite a poorer solution compared to proper intellisence, but touching the former is too risky and can end up with endless fighting with Visual F# Tools intellisense. @OkayX6 However, if you feel lucky and full of energy to investigate the intellisence approach, it would bring us a really high quality solution. |
@OkayX6 Yes, it's the right interface for intellisense. It most likely adds another tab to intellisense windows (see http://stackoverflow.com/questions/10460138/custom-intellisense-extension) but we should try to inject current intellisense tab. WebEssentials has many examples of custom intellisense so I don't think it's an issue https://github.com/madskristensen/WebEssentials2013/search?q=ICompletionSource&ref=cmdform @vasily-kirichenko AFAIK we can capture key press and display smart tag at any location. |
I still think stub generation should give compilable and usable values. Something like: let r: R = { F1 = Unchecked.defaultof<string>; F2 = Unchecked.defaultof<DU1>;
F3 = Unchecked.defaultof<Choice<int option, exn>>} When users use this feature, I think they know how to enter appropriate values to customize stub values. The use |
If we master intellisence, we could also fix the places where VFT does not show any (property initializers in class constructors and curried function arguments for instance). It would be cool. |
@dungpa I see your point. But it's also dangerous since it's too easy for the user to forget to initialize some fields with proper values. |
How about the text "nyi"? |
Ok, let's keep the current behaviour. I think we should implement options for code generation similar to those of ReSharper http://www.jetbrains.com/resharper/webhelp/Reference__Options__Languages__Common__Generated_Members.html so that personal preferences can be taken into account. |
Just to investigate what kind of data the intellisense component would be facing, I've looked at the AST when you're writing:
and the expression on the right-hand of the binding is considered respectively:
Technically it's not an issue but it'd be a bit hacky if we treat them as special cases. |
@ovatsus Your suggestion is more or less implemented :) (see the second GIF). I had to specify a dummy value to the field for the parser to identify it as a record expression (and with the field symbol included in the tree). |
Cool :) |
@OkayX6 It definitely looks more useful now. |
@OkayX6 I don't think we have to alter behaviours of the parser. We could accept the fact that the ASTs could return computation expressions and look for symbols based on the identifiers. If the symbol is an It's difficult to expect the parser to return what we want when the information is incomplete. In general, we should always do filtering based on multiple sources (ASTs, symbols, and in some cases lexer tokens). |
For that, we need Investigation results depending on caret position & source code:
|
I'm OK with accepting computation expressions, I'm just concerned we take too many dependencies on accidental behaviors of the parser. It would make it easy to break the component if the parser changes its behavior (if for instance, they enhance it so that it can parse more degraded source code). But maybe I'm too pessimistic? |
I don't think the parser is that easy to change. Visual F# Tools has strong dependencies on it; it's difficult to revise the parser without breaking changes there. Regarding intellisense - assume that when users type |
Fair enough. I think that you'll be able to reuse most of the code that deals with the AST. Regarding intellisense though, you'll need |
I managed to clean up the history. |
I think the merge commits appear again now. |
How's your intellisense experiment going? If you finish the last TODO items and rebase to master, we should be able to merge this. |
Ha, in fact I thought that you or Vasily wanted to take over the work I had done, and make it use the Intellisense UI instead of Smart Tags. This is why I kind of stopped working on it. I acknowledge your comment so I can finish the last TODO item by the beginning of next week (I won't have access to my laptop before). (As per using the Intellisense UI, I didn't go far, I just managed to get the MSDN walkthrough working. The API behaved a bit weird to me when I tried to augment the existing completion list instead of creating a new Tab) |
// Minimum let x: MyRecord = { }
When the record expression didn't start at the same line as the type annotation, then the Smart Tagger wouldn't know where to insert the stubs.
I've rebased my branch and resolved the latest TODO item. |
It would be nice to share the code for the F# addin in XS, we've already borrowed the implement interface stuff because theres no sharing mechanism for us to use yet... |
So, it seems to work in two scenarios: let _ = { Reco|rd.Field = "valid value" } and let _: Record = { Fi|eld = "valid value" } Am I right? |
@7sharp9 We're going to use this as a temporary solution only, until number of FCS bugs are fixed. So, I don't think you should use it in Xamarin. |
@vasily-kirichenko I wouldn't put it in until it was stable anyway, implement interface is in the latest master though. |
Three scenarios: |
@OkayX6 Oh, this last scenario is great! |
Generate record stubs
First POC
Status:
let x = { Field1 = }
expressionlet x = { MyRecord.Field1 = }
expressionSee:
