Sign in to follow this  

Code organization without the limitations of files

This topic is 1183 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I don't personally have a problem with the standard arrangement of code living in files, but let's consider other possibilities. Would you be more satisfied if instead of a directory structure (where each file must live in a single directory) we had tags, similarly to GMail messages? That way you could tag a piece of code as both "fireball" and "lightning", and you would see it whether you are browsing for "fireball" things or for "lightning" things.

If you are in a Unix-style file system, you can already achieve some of this by making directories for the different tags and using hard links to place the file in any number of directories.

Share this post


Link to post
Share on other sites
I've pondered the tagging idea a bit, and I think it has potential - but it runs into a tricky issue: how do you go from code you can text-edit to data on disk? Ideally that process preserves the ability to do things like diffs and version control.

Share this post


Link to post
Share on other sites

Now suppose I want to view all code related to casting a fireball spell in this particular game - head to toe, from the UI button that triggers the spell to the game logic that handles it to the graphics code that renders it. Throw in audio effects for good measure.

 

This just doesn't make sense in practice much of the time. First, many bits of code and assets are going to be shared common structures without attachment to one specific effect. For two, things like fireballs are data files and definitions, not code, so the organization imposed by source files is quite irrelevant. Third, content creators are especially bad at organizing files or using such tools which is why you so often seen projects with fireball.png + fireball2.png + fireball_final.png + fireball_final_final.png + fireball_test_final_shipit.png + fireball_test_final_shipit2.png and so on.

 

Some engines do completely roll content management into their game editors, though, and some of these then offer tagging facilities. These are separate from the on-disk file structure. e.g. data/textures/vfx/fireball.png might have a corresponding fireball.json file that includes a UUID, "friendly" name, description, list of tags, and other metadata used by the editor for content browsing and linking. This data isn't available in other programs but you can conceivably include an Explorer plugin or the like that makes consumption and modification of that metadata using stock OS UIs a bit easier.

 

This is all for content still. You really, really shouldn't ever need a source file for a fireball or so on. Your source should be a collection of resuable modules/components and higher-level game primitives can be composed out of those. A fireball would be a particle effect, a DamageOverTime component, a physics collision model, some sound files, materials for burn marks and a component that applies them, etc. No fireball-specific source code would ever be required. Content designers can then be free to create lightning balls or so on without ever bugging a highly-paid engineer or having to wait for new builds to be released to the team.

Share this post


Link to post
Share on other sites
I'm using C# most of the time lately on large projects (about a thousand files, so maybe not THAT large of a project), and I don't really have file navigation problems.

If:
- I have no idea what the thing is called: I ask a teammate (or if nobody remembers, I open up the Object Browser).
- I've seen the code: I exclusively use the IDE's navigation functions (go-to-def, find-all-refs, navigate-by-symbol/file-substring, navigate forward/back). This completely removes the need for me to remember which folder a file is in.

As far as where I actually put new stuff:

- Files: Wherever makes sense. For Unity, I just have to make sure to put it in the correct combination of plugins-or-not, editor-or-not, and potentially in a platform-specific folder if necessary. This is more likely for repository management purposes (submodules, etc) than source code organization.

- Classes: Typically one per file. I like short files. Sometimes I use partial classes to split up extremely large classes across multiple files (I usually only feel like doing this for machine code disassemblers since they are essentially just massive nested switch statements). Edited by Nypyren

Share this post


Link to post
Share on other sites

What I've seen is that projects sometimes are split in multiple projects and eventually become a bigger mess that the original code base.

I've tried different structures, both for C# and C++, and I usually keep one file per class and map directory structure to namespaces. For C++, I keep headers and source files together (handy if you just want to browse some files with a text editor instead of working with the full IDE). If I have related structures/functions/etc that are relatively small, I keep them in the same code unit for brevity. Also, I've come to heavily rely on IDEs' code navigation features, and I can't image coding efficiently without them.

 

I've also noticed that no matter how I start a project, once it grows into something used by customers, it always degrades into exceptions to the rule. Different formatting here, different file/directory structure there, folders with lots of files in them and then folders with just a single file.

 

I wouldn't worry about it, this is what Ctrl+F or Ctrl+Shift+F are for. When I learn a new code base, I don't always rely on the IDE's navigation features, as some names may be used in strings, etc, so finding in all files works better. But it's always a pain.

Share this post


Link to post
Share on other sites

Interesting line of thought Apoch, but is the file structure on the disc really the problem? What if we could afford to write our own IDE to handle all file-related stuff for us?

 

With a custom IDE, the IDE itself could decide how to map the code written into different files on the disc, ideally without intervention from the developer. Then, the IDE could display a custom "view" on the code in whichever way you prefer. To solve the issue of navigating around and tracing paths through code, maybe it would be possible to generate some sort of "code-flow-graph" that maps the connections between methods or code-fragments in the code base. This could be partially automated (like a recursive call to "Go to definition"), but there still has to be a lot of intervention for more obscure connections, starting with virtual methods (MethodX takes an ISomething and calls a virtual method on it, where does this go to?) and harder-to-trace things like event queues in multithreaded applications or network serialization (Cast fireball? Well we are playing an MMORPG and first have to ask the server if we can do this and then a frame later or something the control-path of "casting a fireball" resumes). This would require some sort of meta-information about the code, i guess similar to the tags that Álvaro mentioned. This is potentially error-prone, just like writing comments, because the meta-information has to be kept in sync with the actual code. But if you were to provide that information during creation of a code-segment, maybe this could be simplified a little. Just as regular code is grouped into modules, upon creation of a new code-element (could be a class or a global function or whatever) this particular code-element could be assigned one or more "domains", like "memory allocation", "unit movement" or "casting fireball". A domain would be similar to a namespace or package, but it maps more directly to "use-cases" in the application and is independent of the underlying grouping of code-fragments. 

Then it would be possible to map a code-path for domain "casting fireball" starting from a given point. This could then also be displayed in a single document or in multiple connected documents or whatever is convenient.

The domains would also have the positive side-effect of making dependencies between code-pieces easier to track (though I'm sure this is somehow already possible with some tools). 

Thinking about it, if you get a new code-base from someone who has worked with this IDE and followed its rules, you would open the project and could display a high-level "domain overview" showing all the different elements of the whole code-base. 

The downside would be that version control has to be somehow integrated into the IDE and has to work with the meta-information too. 

 

Could be fun to try out if that would even work or if it is a stupid idea biggrin.png All in all I personally would prefer an approach that lets me work with code without having to deal with how it is stored on the disk instead of creating a new storage scheme smile.png

Share this post


Link to post
Share on other sites

Firsty, I really don't agree with you about it being a problem. It's normal to have to alter multiple files for a single change, and I'm quite happy with that.

 

If you are really worried about code bloat and repetition on code blocks, restructure your classes in a nice OO way. Then turn on link time optomisation.

 

Ok that out of the way... smile.png

 

If you want to work in a different way, you have to write some code that sits in front of your compiler. This is not a new principle, most game engines use an editor instead of just a mass of source code.

 

You can make your "editor" for lack of a better word work in any way you want, then when you hit the magic build button, it spits out files that can be compiled by a traditional compiler.

 

This , again, is not a new idea.

 

Your chance to come up with something that is new, is what happens when you press the magic button.

 

What would you like? If you can dream it, someone can code it.

Share this post


Link to post
Share on other sites

I remember someone bringing up an idea about storing code in some sort of loosely-defined database, rather than plain text files. This was in GD maybe a decade ago so good luck finding a reference to the old thread, but the idea does have some merit.

 

Source control could operate on individual items (add class foo, rename function bar, move that code from x to z) instead of plain non-semantic text. More complicated to implement, certainly, but it would be really interesting to what new programming capabilities could arise then.

 

 

The real challenge is that this would require very tight integration between the programming language, the IDE and the source control system. It would not work with C++, but it might just be feasible with something like Go or C# (Roslyn!)

Share this post


Link to post
Share on other sites

I remember someone bringing up an idea about storing code in some sort of loosely-defined database, rather than plain text files. This was in GD maybe a decade ago so good luck finding a reference to the old thread, but the idea does have some merit.

 

Source control could operate on individual items (add class foo, rename function bar, move that code from x to z) instead of plain non-semantic text. More complicated to implement, certainly, but it would be really interesting to what new programming capabilities could arise then.

 

 

The real challenge is that this would require very tight integration between the programming language, the IDE and the source control system. It would not work with C++, but it might just be feasible with something like Go or C# (Roslyn!)

 

That's the first thing I thought of as well.

 

Another thought, since we're throwing things out there, was to perhaps store it in some sort of AST format.  In that format search for related code would be relatively trivial I imagine.

Share this post


Link to post
Share on other sites
Maybe I'm just getting tied up in the example provided by the OP with fireballs and such (which I agree with Sean, is not the correct thing to do in code, that's a data issue) but it seems to me that code is a collection of algorithms. You group together related ones (same class, same "system", whatever) close to eachother in some manner (maybe same file, maybe multiple files across a directory) to more easily see them side-by-side.

However if you're asking "I want to see all the code that executes when I cast a fireball" then... well... that's what a debugger is for, surely? You're asking a run-time question.

On the flipside, I think the IDE is the correct way to go about this and I could see someone making a tool where you could somehow input some parameters into a function, and then have it "run" the code, collecting all code hit into a giant pseudo-function that you could look at all at once. Heck, IDE and profiling tools already exist that can give you whole call trees which then let you jump to each function in the code.

Course, I have no idea how you'd even begin to edit the function from that standpoint...

In the end, code organization is something you have to decide for yourself. And whatever you pick will be ideal for task X, but will suck for task Y. You simply cannot organize code in such a manner that all possible queries on said codebase are represented. Even storing functions individually won't work because functions may have conditions which change what code inside them executes based on parameters - which means pulling the function in pulls in code you're not interested in because of pre-conditions.

Get a good IDE and organize your code for the most common use case. In my case, that is to group systems into folders and classes into single pairs of h/cpp files. Then let the IDE and other tools parse the code and provide you the data you want for less-common tasks like "what calls me?" or "who do I call?" or "If Bob is blue, then how does metal smell?"

Share this post


Link to post
Share on other sites

However if you're asking "I want to see all the code that executes when I cast a fireball" then... well... that's what a debugger is for, surely? You're asking a run-time question.


Not really; you come to a new system, you are trying to add 'something' to it but in order to do so you need to follow the flow of the code and this can get complicated FAST when moving across multiple dependent and independent files.

I've had to deal with this a lot recently and my current method of dealing with it is to use the 'pin tab' functionality of VS to track files I've been in (and if jumping among those files even that isn't great) as well as noting down the flow on paper... all of which is a bit of a faff.

Even a small example, adding ADPCM support for Android in UE4, resulted in my having four or five files pin'd while trying to track all the logic going on.

What would have made this easier would have been anything which could have integrated the code fragments into a single view (or a sub-set of them into a couple of views if that made sense), bonus points for being able to display call linkage either in the same view or in a 'map' view so I can jump around and see where things go to/come from.

So, in the sound case, I wanted to see how 'createbuffer' was called; my current solution was to use VAX to 'find references' and open the correct file from there. What would have been 'nicer' would be same initial flow ('find references') but instead of files the output would be a list of tagged versions so that I could say 'ahah! AndroidAudioDevice!', double click on it and get that function inserted below the current code (which I could then optionally drag/drop above so that the flow made more sense) so now I can see call site and destination in the same view.

By the end of this session I might have 7 or 8 functions in the chain on screen which would have meant having 4 or 5 files open but instead all viewable on screen in a single session.

----

This does feel like something which needs to be also tackled at the language level however; many existing languages rely on the concept of a file and file system structure to control compile order or dependency information which could cause problems and, ultimately, not make it useful for things like C or C++.

(Although, for languages like that you could maintain the existing file setup and have the IDE work magic to give you the new views and handle changing the original data when you update the functions).

Version control would either have to be based on 'fragments' too or you'd have to provide a compatibility layer so that while the fragment 'void foo()' doesn't sit in a file normally the comp layer shoves it into one for version tracking - however being able to track on the fragment level would probably be better, bonus points for allowing a checkin to reference multiple fragments; "changed Audio to support ADPCM" for example would reference the 7 or 8 fragments changed to support it which makes it clear what has changed in that check in.

I think the idea has merits, but you will need to build it in from Day 1 and it would require retooling for a few things as well as a fundamental shift in how people think about code and structure.

I could see it making life easier however when you are tasked with doing Things in a large code base.

Share this post


Link to post
Share on other sites

There was a video floating about of a former Visual Studio developer that was writing an IDE that was similar to what was described.  Instead of showing files, it would show functions, so as you followed a bit of code, like, say you were debugging, instead of showing you the file, it would just show you the function you're currently in, above it would be the function it was called from and all its code, etc.  Basically, a very verbose callstack.

Share this post


Link to post
Share on other sites

However if you're asking "I want to see all the code that executes when I cast a fireball" then... well... that's what a debugger is for, surely? You're asking a run-time question.


Not really; you come to a new system, you are trying to add 'something' to it but in order to do so you need to follow the flow of the code and this can get complicated FAST when moving across multiple dependent and independent files.


True - but again, I think this is still more of a "let's write a tool that will do that" thing then a "how do I organize a file system which shouldn't have anything to do with my program but does because that's how the C compilation model works".

And again, whatever you do to organize will work well for a set of questions you want to ask of your code base, but not others, so you're going to at least want multiple views on the data depending on the work you're doing.

Share this post


Link to post
Share on other sites

Not really; you come to a new system, you are trying to add 'something' to it but in order to do so you need to follow the flow of the code and this can get complicated FAST when moving across multiple dependent and independent files.

I've had to deal with this a lot recently and my current method of dealing with it is to use the 'pin tab' functionality of VS to track files I've been in (and if jumping among those files even that isn't great) as well as noting down the flow on paper... all of which is a bit of a faff.

This is certainly an area where I can see something like tags being helpful. The ability to immediately query for something (assuming you know the tag), have a browser of tags, be able to search on tags, etc. could speed up the finding of these functional bits immensely faster. At the moment you're kind of stuck reading through a function and then "Go To Definition" on various calls or looking at the parent caller to find out where things are going and how the logic is flowing in order to make a change to a single piece of functionality.

Even a small example, adding ADPCM support for Android in UE4, resulted in my having four or five files pin'd while trying to track all the logic going on.

What would have made this easier would have been anything which could have integrated the code fragments into a single view (or a sub-set of them into a couple of views if that made sense), bonus points for being able to display call linkage either in the same view or in a 'map' view so I can jump around and see where things go to/come from.

So, in the sound case, I wanted to see how 'createbuffer' was called; my current solution was to use VAX to 'find references' and open the correct file from there. What would have been 'nicer' would be same initial flow ('find references') but instead of files the output would be a list of tagged versions so that I could say 'ahah! AndroidAudioDevice!', double click on it and get that function inserted below the current code (which I could then optionally drag/drop above so that the flow made more sense) so now I can see call site and destination in the same view.

By the end of this session I might have 7 or 8 functions in the chain on screen which would have meant having 4 or 5 files open but instead all viewable on screen in a single session.

Yes, I can see how this might work... use edit controls in a parent view. Have the edit controls be inline and expandable so that they're fairly transparent (makes the text area look like a single file) but with a header notation on each function/method/class/etc. that indicated its physical location. i.e. something like <tt>@/src/spells/elites/fierygreatsword/FieryRush.cs#433</tt>.
 

This does feel like something which needs to be also tackled at the language level however; many existing languages rely on the concept of a file and file system structure to control compile order or dependency information which could cause problems and, ultimately, not make it useful for things like C or C++.

(Although, for languages like that you could maintain the existing file setup and have the IDE work magic to give you the new views and handle changing the original data when you update the functions).

C# and Java already have the ability to annotate code with attributes, so you could simply implement a Tag attribute in C# (for example), and you've got a quarter of the problem solved. The other quarter is building the UI pieces into visual studio.

Version control would either have to be based on 'fragments' too or you'd have to provide a compatibility layer so that while the fragment 'void foo()' doesn't sit in a file normally the comp layer shoves it into one for version tracking - however being able to track on the fragment level would probably be better, bonus points for allowing a checkin to reference multiple fragments; "changed Audio to support ADPCM" for example would reference the 7 or 8 fragments changed to support it which makes it clear what has changed in that check in.

I think the idea has merits, but you will need to build it in from Day 1 and it would require retooling for a few things as well as a fundamental shift in how people think about code and structure.

I could see it making life easier however when you are tasked with doing Things in a large code base.

Probably a compatibility layer at first, so that you could have dual workflows. The tag based one as it was implemented and grew into maturity, and the default workflow people are currently used to.

I am surprised to see so little discussion on this, I think the idea is certainly worth exploring with current languages and we certainly have the capability to implement it now at least on some platforms... Edited by Washu

Share this post


Link to post
Share on other sites

It's a very human trait to endure ridiculous amounts of inconvenience when that inconvenience is familiar and comfortable. Changing to a better - but different - workflow is often too scary to "justify" leaving behind the immense pain that must be endured in the known, "safe" workflow.

Frankly, though, I'm tired of the way code organization and exploration is forced to happen in contemporary languages. I'm going to solve this problem even if the majority of programmers are content to metaphorically punch themselves in the gonads all day. If grep and Find All References are good enough for someone, then so be it. They aren't good enough for me.

Especially since Find All References doesn't work 100% even in managed language code bases.

I think there are fundamentally several intertwined issues going on here that are worth considering:

  • Finding a home for newly written code
  • Viewing call graphs: how does code flow into and out of a given function?
  • Viewing related code, where "related" is an arbitrary concept/axis
  • Viewing structurally proximal code, i.e. stuff in a single file/module/unit of some kind
  • Treating related code as if it were proximal
It's starting to sound like the right direction is to leave the general file-based organizational hierarchy intact, but layer some kind of viewing filters on top of that. It would take serious IDE/compiler integration but I think it's totally doable especially in the context of a novel language.

Well, the Visual Studio SDK is quite powerful, you could probably relatively quickly build a tag based plugin (assuming that's the route one went) for any of the managed languages probably with only a few hours of investment. But for a language like C++... I honestly don't see it happening.

I have a half-formed mental image of a "Build Code View" dialog that allows cherry-picking code chunks from a variety of sources:

  • A tree-view of directories, files, and code units within each file
  • A list of known tags and/or a tree-view of tag "regions" or "spaces"
  • Call graphs centered on arbitrary code units in the program
So I open up this thing, click on whatever chunks of code make sense, and I get a new Project tree entry called "Some View Foo" which contains exactly the code I selected. I'm not entirely sure what happens if I write new code into this view, but that seems like a minor question overall.

Then I can share my views with anyone else on the team, for example, and they can pop open a pre-selected perspective of the project that completely details, say, all the network messages transmitted by the system, or all the custom UI element implementations, or whatever.


I kind of like the idea of making views orthogonal to the file structure. It makes cooperating with version control a lot easier, although it doesn't get the cool benefits like function-level revision history. Maybe it's worth digging deeper to come up with a fundamental way to solve both issues, or maybe I should be happy to solve one thing at a time...

Code Views, like database views.

That would be much more doable in non-managed languages. As for the source control integration and version history: Why not? You can run blame on a single line of code, so no reason you couldn't run that blame against the file for the set of lines that makes up the function and simply cut out all lines that are not that function.

Share this post


Link to post
Share on other sites

I think this is one of those cases where an implementation detail forces you to use a tool in a specific way. ie. code stored in a hierarchical filesystem forces you to structure your program in such way.

The problem with hierarchies is that they are strict and rigid and force you to put your code in a dichotomy that is very ill suited for a multi dimensional problem like computer programs.

 

What you want is to abstract away the file system from the programmer and treat it as an optimization problem for the IDE to feed into the compiler.

Ultimately the source code would be stored in database that is closely modeled after the language specification, as a normalized, canonical representation of the program.

 

All the features that you wrote about would then be views on top of that database. That way you can choose a representation that fits the task you are currently trying to solve.

 

Big problem I see with this, like others have said, is the tight coupling to the IDE.

 

But it could be interesting nevertheless, I actually thought about this exact thing before.

Share this post


Link to post
Share on other sites
Analysis of call graphs ranges from easy to ugly:

- Fixed calls (easy)
- Virtual calls (easy?): Do you show just the statically-known class or include all derived classes?
- Callbacks (easy? hard?): What's the ideal representation? Sequence diagrams? Something else?
- Functors/delegates/lambdas/etc: No idea how you'd analyze or represent these nicely.

How do you render the call graph? I wouldn't think that anything less than a Graphviz-style layout would be sufficient, but I've done call graphs with Graphviz, and real-world graphs tend to become completely unreadable very quickly. The density of calls is usually just too high to visualize cleanly.

What might be really badass is if you could trace data flow in the graph. For example, let's say we have a call from method A to method B, where one of the arguments is passed straight through without change. It might be nice to indicate that in the graph layout:
 
| Namespace | ========> | Namespace2 |
| Class     |           | Class      |
| Method    |           | Method     |
| Arg1      |     /---> | Arg1       |
| Arg2      | ---/
Or let's say you can select two variables in the graph and press a button which makes the IDE show you all of the statements that are involved in the data flow between those two variables (or tell you if no data flows between them). This would likely only be precise for stack variables, but it seems like you might be able to do some conservative analysis for object fields as well...


I like the tag-and-view idea. I was thinking that in C#, you could easily adapt the #region/#endregion directives to function as tagging constructs:
 
#region tags: spells, attacks
// ...whatever code you want to put here...
#endregion
You might want to automatically assign a GUID to each region as well, so that you could cherry-pick regions instead of being forced to get every region with a specific set of tags.
 
#region guid: {1BD2771D-D38F-4AB1-8076-8A10D5EBDE51} tags: spells, attacks
// ...whatever code you want to put here...
#endregion
Your view files would then just list guid and tag expressions:
 
guid: {1BD2771D-D38F-4AB1-8076-8A10D5EBDE51}
tags: spells && attacks
(In my example, that region matches the guid AND the tags, but this would obviously not be necessary) Edited by Nypyren

Share this post


Link to post
Share on other sites

Analysis of call graphs ranges from easy to ugly:

- Virtual calls (easy?): Do you show just the statically-known class or include all derived classes?

Let them choose. If it's an interface, then you indicate as such (icons), if I know X is going to be a Q then I'll want to be able to select Q.F() instead of B.F(). I should be able to easily change my choice later though, in case I was wrong or need to trace the flow through two or more different sets of derived methods. If we're doing this in a "view" based format, you could have separate chunks of the view for each virtual method I'm tracking.

- Callbacks (easy? hard?): What's the ideal representation? Sequence diagrams? Something else?

Probably sequence graphs if you're familiar with them. Alternatively: Callstack.

- Functors/delegates/lambdas/etc: No idea how you'd analyze or represent these nicely.

Same idea as Callbacks.

How do you render the call graph? I wouldn't think that anything less than a Graphviz-style layout would be sufficient, but I've done call graphs with Graphviz, and real-world graphs tend to become completely unreadable very quickly. The density of calls is usually just too high to visualize cleanly.

The real problem I see with this is that you can never eliminate the shit you don't care about, and at the same time bookmark the stuff you DO care about. Ideally I would want to be able to, in a method, right click on a function and say "add to view." At this point I can now see the method in my view alongside all the other methods. If this method is called by (either directly or through a potential derived instance) then I would like to see that relationship, either due to the implicit ordering of the method with relation to its callee, or by having the ability to show and hide a relation graph that might be a side part of the editor window.

What might be really badass is if you could trace data flow in the graph. For example, let's say we have a call from method A to method B, where one of the arguments is passed straight through without change. It might be nice to indicate that in the graph layout:
 

| Namespace | ========> | Namespace2 |
| Class     |           | Class      |
| Method    |           | Method     |
| Arg1      |     /---> | Arg1       |
| Arg2      | ---/

This is doable currently, just needs a bit of static analysis. You can do this in the latest C# CTP for 6.0 and roslyn.

I like the tag-and-view idea. I was thinking that in C#, you could easily adapt the #region/#endregion directives to function as tagging constructs:
 

#region tags: spells, attacks
// ...whatever code you want to put here...
#endregion
You might want to automatically assign a GUID to each region as well, so that you could cherry-pick regions instead of being forced to get every region with a specific set of tags.
 
#region guid: {1BD2771D-D38F-4AB1-8076-8A10D5EBDE51} tags: spells, attacks
// ...whatever code you want to put here...
#endregion
Your view files would then just list guid and tag expressions:
 
guid: {1BD2771D-D38F-4AB1-8076-8A10D5EBDE51}
tags: spells && attacks
(In my example, that region matches the guid AND the tags, but this would obviously not be necessary)

Hmm, you could use regions for this yes. This would result in the data not being available post-compile time though. Using attributes is another option...
[Tag("fireball","spells","attacks")]
[Tag("fireball, spells, attacks")]
[Tag("fireball"), Tag("spells"), Tag("attacks")]
This would result in the data being available after compilation for use by external automation tools...

Share this post


Link to post
Share on other sites

Analysis of call graphs ranges from easy to ugly:

- Virtual calls (easy?): Do you show just the statically-known class or include all derived classes?

Let them choose. If it's an interface, then you indicate as such (icons), if I know X is going to be a Q then I'll want to be able to select Q.F() instead of B.F(). I should be able to easily change my choice later though, in case I was wrong or need to trace the flow through two or more different sets of derived methods. If we're doing this in a "view" based format, you could have separate chunks of the view for each virtual method I'm tracking.


That's a good point. I typically think of call graphs as something the IDE generates which I can't tweak. If we let the user tweak the view to show what they're interested in, then it gets much better!

(side note: I found something I had been looking for which sounds a lot like this, but is currently debugging-oriented: http://visualstudiogallery.msdn.microsoft.com/4a979842-b9aa-4adf-bfef-83bd428a0acb )
 

Hmm, you could use regions for this yes. This would result in the data not being available post-compile time though. Using attributes is another option...




[Tag("fireball","spells","attacks")]
[Tag("fireball, spells, attacks")]
[Tag("fireball"), Tag("spells"), Tag("attacks")]
This would result in the data being available after compilation for use by external automation tools...


That's another good point - I was only thinking of this from a source perspective. .Net definitely emphasizes including metadata in DLLs so that consumers don't NEED the source code to use it conveniently. Attributes might be a good way to do this (I don't know of any alternatives).

If you had to add those attributes to everything by hand though, it would be seriously tedious. Ideally you could somehow multi-select whatever you want to add tags to and have the IDE add the attributes for you. Edited by Nypyren

Share this post


Link to post
Share on other sites

Let them choose. If it's an interface, then you indicate as such (icons), if I know X is going to be a Q then I'll want to be able to select Q.F() instead of B.F(). I should be able to easily change my choice later though, in case I was wrong or need to trace the flow through two or more different sets of derived methods. If we're doing this in a "view" based format, you could have separate chunks of the view for each virtual method I'm tracking.


That's a good point. I typically think of call graphs as something the IDE generates which I can't tweak. If we let the user tweak the view to show what they're interested in, then it gets much better!

(side note: I found something I had been looking for which sounds a lot like this, but is currently debugging-oriented: http://visualstudiogallery.msdn.microsoft.com/4a979842-b9aa-4adf-bfef-83bd428a0acb )

Yes, that is the essence of what I was thinking of writing up (at the moment) in VSIX. Except mine would be more views on methods in managed source files.
 

That's another good point - I was only thinking of this from a source perspective. .Net definitely emphasizes including metadata in DLLs so that consumers don't NEED the source code to use it conveniently. Attributes might be a good way to do this (I don't know of any alternatives).

If you had to add those attributes to everything by hand though, it would be seriously tedious. Ideally you could somehow multi-select whatever you want to add tags to and have the IDE add the attributes for you.

At first, yes, but then it becomes just like doc comments. In addition, with a bit of UI magic you could trivially have autocomplete capabilities on your tags.

Share this post


Link to post
Share on other sites

This topic is 1183 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this