digitalmars.D - A hypothetical question
- Ellery Newcomer (29/29) Aug 25 2009 Say you have an IDE for D (such as Descent), featuring autocompletion,
- Michel Fortin (22/23) Aug 25 2009 In case you're interested, Xcode, Apple's IDE, has to deal with
- Ary Borenszweig (65/98) Aug 25 2009 I think it makes a lot of sense because often when you make a change to
- Ellery Newcomer (46/95) Aug 25 2009 yeah, sort of. I had this in mind, though:
- Tim Matthews (2/37) Aug 25 2009 IDEs require a lot of parsing code to be of any use eg: in visual studio...
Say you have an IDE for D (such as Descent), featuring autocompletion, error highlighting, and any number of other features which require solid semantic analysis. In the course of performing said analysis (strictly the non-interactive part), how much sense does it make to attempt to analyze all conditional blocks? On the one hand, you have the compiler, which throws conditional blocks away with little ado. These blocks may be designed to work under specific version sets which may not be readily gleanable from source. They may contain complete garbage (e.g. syntax or semantics not valid for this version of D, but maybe valid for another version). This could swamp the user with error messages which aren't really valid. On the other hand, this is an IDE. Any moderately ambitious project is going to have different versions for different platforms, different modes of operation, etc. If you have errors in specific versions, you want to know about them up front. And you don't want autocompletion to suddenly stop working in part or in full inside odd version statements. Another point is efficiency. If you have symbols that can resolve to different types depending on version, it could potentially make semantic analysis much slower when checking expressions that use those symbols. The possibilities I see are: * have the user input a single version set to use when performing analysis (ape the compiler), and change it whenever he/she/it wants to work on different versions (bleach!) * have the user input specific version sets, all of which must be checked when performing analysis * run analysis over all version sets * let the user choose which of these to use Thoughts? (And I have no idea what Descent does in this regard. Ary?)
Aug 25 2009
On 2009-08-25 20:10:44 -0400, Ellery Newcomer <ellery-newcomer utulsa.edu> said:Thoughts?In case you're interested, Xcode, Apple's IDE, has to deal with multiple versions all the time. It's typical for Mac developement to build two or four versions of the same executable (PowerPC 32 and/or 64 bit + Intel 32 and/or 64 bit) before merging all four in the same executable file. That's done automatically by Xcode under the hood by compiling each file multiple time for all the targets. So with Xcode you're generally compiling several versions of the same code at one time. Xcode doesn't do a very rigourous semantic analysis: it merly ignores conditionals when it gathers its list of symbol for autocompletion, and it doesn't itself flag errors as you type (it does run the compiler in the background though, and shows errors inline in the source code instantanously when you build). So a similar idea for an IDE like Eclipse/Descent could do is allow you to select one or more sets of compiler flags and combine the result (autocompletion choices + errors) in a single view. Xcode does that only for the architecture. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Aug 25 2009
Hello Ellery :) Ellery Newcomer escribió:Say you have an IDE for D (such as Descent), featuring autocompletion, error highlighting, and any number of other features which require solid semantic analysis. In the course of performing said analysis (strictly the non-interactive part), how much sense does it make to attempt to analyze all conditional blocks?I think it makes a lot of sense because often when you make a change to one version you want to make the other version kept in-sync, so any quick errors you get because of out of sync changes is good. It also makes sense when renaming a symbol: you want (do you?) all possible versions of a symbol to also be renamed.On the one hand, you have the compiler, which throws conditional blocks away with little ado. These blocks may be designed to work under specific version sets which may not be readily gleanable from source. They may contain complete garbage (e.g. syntax or semantics not validrequirement. So in this case D is better.for this version of D, but maybe valid for another version). This could swamp the user with error messages which aren't really valid. On the other hand, this is an IDE. Any moderately ambitious project is going to have different versions for different platforms, different modes of operation, etc. If you have errors in specific versions, you want to know about them up front. And you don't want autocompletion to suddenly stop working in part or in full inside odd version statements.In Descent autocompletion doesn't work in inactive code (code not reached by the current debug/version conditions). It also appears as grey.Another point is efficiency. If you have symbols that can resolve to different types depending on version, it could potentially make semantic analysis much slower when checking expressions that use those symbols.I think this isn't a big deal. At least in Descent full semantic analysis is run for the current module: the other modules are partially looked as needed.The possibilities I see are: * have the user input a single version set to use when performing analysis (ape the compiler), and change it whenever he/she/it wants to work on different versions (bleach!) * have the user input specific version sets, all of which must be checked when performing analysis * run analysis over all version sets * let the user choose which of these to useDescent has the bleach option. :-PThoughts? (And I have no idea what Descent does in this regard. Ary?)It's made that way because it's the easiest of the options. Also Visual Studio works exactly like that. I just tried renaming a symbol which has another definition in some other inactive code, and the inactive symbol wasn't renamed. So I thought "If Visual Studio works like that and I never saw anyone complaining, it must be a good choice". But... I think used them). So it would be nice to check also version branches. The problem is that if you have a file like this: version(Foo) { // Something } version(Bar) { // Something else } You'll have to make semantic analyis for these cases: - !Foo && !Bar - !Foo && Bar - Foo && !Bar - Foo && Bar because each one of those combination is a valid version combination. Also you have to combine that with debug levels (that combination can be reduced by checking if there are debug versions in the affected modules). You might get errors with some combinations because those were not intended to be used together (for example Windows, Unix, etc.) I think we arrived to this conclusion with Robert Fraser. :) On the other hand maybe semantic analysis can be performed with any of those versions. You thihk that can work? Because that'll solve a big problem in Descent that's: if your current version is Windows, all the posix/unix modules in Phobos/Tango give you an error because many things are not defined. The other problem is: version(Unix) { } else { static assert("This module should only be compiled with Unix version"); } You'll get that error in each module that looks like that if Unix version is not set. So... should I try checking each version? I wouldn't know which errors to show (the union? that'll trigger the static assert above; the current version? that brings us to the beginning of this discussion). Also... Descent is still not good at showing exactly the same errors as DMD would give you, and probably will never be like that (partially because some errors are in the back-end and when most of the code was ported we didn't have access to it, partially because it's hard to make it work like DMD when you need to reduce the amount of semantic analysis needed to make the IDE work fast). So the only benefit I would see is getting autocompletion/go-to-definition in inactive code. Finally, no one complained about this, but probably because not many people use Descent. ;-)
Aug 25 2009
Ary Borenszweig wrote:requirement. So in this case D is better.yeah, sort of. I had this in mind, though: version(D1){ int i; }else version(D2){ mixin("shared int i;"); }I think this isn't a big deal. At least in Descent full semantic analysis is run for the current module: the other modules are partially looked as needed.Here's what I'm visualizing: Say you have symbols A,B,C. A can be defined one of say four ways by: version(4){ typedef int A; }else version(3){ typedef real A; }else version(2){ typedef FoobarClass A; }else{ typedef FoobarUnion A; } or something of that nature. B and C are the same way (their respective version conditionals are independent, though). Now say you have an expression that contains A, B, and C and you want to deduce its type. you have potentially 64 different types that could result from that depending on which versions you choose. Maybe efficiency isn't a big deal, but combinatorial growth does scare me.So it would be nice to check also version branches. The problem is that if you have a file like this: version(Foo) { // Something } version(Bar) { // Something else } You'll have to make semantic analyis for these cases: - !Foo && !Bar - !Foo && Bar - Foo && !Bar - Foo && Bar because each one of those combination is a valid version combination. Also you have to combine that with debug levels (that combination can be reduced by checking if there are debug versions in the affected modules). You might get errors with some combinations because those were not intended to be used together (for example Windows, Unix, etc.) I think we arrived to this conclusion with Robert Fraser. :)My current mode of thinking is that you would treat the version blocks as if they were both there and just return multiple results when symbol lookup could result in something in either one of them and/or in the enclosing scope and handle analysis accordingly. But hmm, there's going to have to be some sort of enforcement for the case when any of those blocks get chopped.On the other hand maybe semantic analysis can be performed with any of those versions. You thihk that can work? Because that'll solve a big problem in Descent that's: if your current version is Windows, all the posix/unix modules in Phobos/Tango give you an error because many things are not defined. The other problem is: version(Unix) { } else { static assert("This module should only be compiled with Unix version"); }Yuck. I suppose you could treat a lone static assert(false) inside a version block as a hint... ugh more complexity..You'll get that error in each module that looks like that if Unix version is not set. So... should I try checking each version? I wouldn't know which errors to show (the union? that'll trigger the static assert above; the current version? that brings us to the beginning of this discussion).Maybe not. I don't know how descent is set up right now. Michel suggested running separate passes for different version sets, which would probably be easiest. Another thought I had was to group errors hierarchically based on version and let the user control which errors should be displayed.Also... Descent is still not good at showing exactly the same errors as DMD would give you, and probably will never be like thatSpare me an ulcer and don't try to make it conform. In my view, unless you have access to the guts of the compiler, your ide shouldn't try to mimic it. It should only flag a well specified set of error conditions and leave the rest to be flagged during the actual build. I think if you align yourself too closely with DMD, you're setting yourself up for trouble when other implementations of D come out, which could behave very differently. And then there's all the incorrect and inane behavior inside DMD, which IMO is pointless to duplicate (though maybe difficult to identify)
Aug 25 2009
Ellery Newcomer Wrote:Say you have an IDE for D (such as Descent), featuring autocompletion, error highlighting, and any number of other features which require solid semantic analysis. In the course of performing said analysis (strictly the non-interactive part), how much sense does it make to attempt to analyze all conditional blocks? On the one hand, you have the compiler, which throws conditional blocks away with little ado. These blocks may be designed to work under specific version sets which may not be readily gleanable from source. They may contain complete garbage (e.g. syntax or semantics not valid for this version of D, but maybe valid for another version). This could swamp the user with error messages which aren't really valid. On the other hand, this is an IDE. Any moderately ambitious project is going to have different versions for different platforms, different modes of operation, etc. If you have errors in specific versions, you want to know about them up front. And you don't want autocompletion to suddenly stop working in part or in full inside odd version statements. Another point is efficiency. If you have symbols that can resolve to different types depending on version, it could potentially make semantic analysis much slower when checking expressions that use those symbols. The possibilities I see are: * have the user input a single version set to use when performing analysis (ape the compiler), and change it whenever he/she/it wants to work on different versions (bleach!) * have the user input specific version sets, all of which must be checked when performing analysis * run analysis over all version sets * let the user choose which of these to use Thoughts? (And I have no idea what Descent does in this regard. Ary?)IDEs require a lot of parsing code to be of any use eg: in visual studio it often reports false problems with your c++ code but then becomes successful at compiling and developers usually install plugins like visual assist x. Clang is a successful project that identified this problem and wrote a set of independent libraries to be used by ide's, compilers and anything else. In the long run I hope we can have something similar for D.
Aug 25 2009