|
@ -0,0 +1 @@
|
|||
*.pdb
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// AssemblyInfo.cs: Assembly information
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2003 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly: AssemblyTitle("Type Reflector")]
|
||||
[assembly: AssemblyDescription("Displays System.Reflection Information for .NET Types")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Jon Pryor Research Labs")]
|
||||
[assembly: AssemblyProduct("Type Reflector")]
|
||||
[assembly: AssemblyCopyright("Copyright (C) 2002-2003")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("0.6.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile("")]
|
||||
[assembly: AssemblyKeyName("")]
|
|
@ -0,0 +1,24 @@
|
|||
Type Reflector (C) 2002 Jonathan Pryor
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to
|
||||
do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,422 @@
|
|||
2005-04-12 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* type-reflector.exe.config: Change fully-qualified name of the Gtk# type
|
||||
displayer (namespace had to change).
|
||||
* TypeFactory.cs: protect against a null entry (if no suck key exists).
|
||||
|
||||
2005-02-09
|
||||
|
||||
* type-reflector.in: Added; used so the installed script knows which
|
||||
type-reflector program to launch.
|
||||
* Makefile: Rewrite install/uninstall to be a better Linux citizen.
|
||||
We shouldn't install type-reflector.exe into $prefix/bin; that's evil.
|
||||
Instead, install it into $prefix/share/type-reflector/, and install a
|
||||
script $prefix/bin/type-reflector which invokes the .exe.
|
||||
|
||||
2004-09-18 Jonathan Pryor <jonpryor@vt.edu>
|
||||
+ Summary: Add new command-line argument, -r, which takes assembly partial
|
||||
names instead of assembly file names. This allows us to load assembly "by
|
||||
name" from the GAC, such as mscorlib, Mono.Posix, and gtk-sharp, without
|
||||
needing to load *everything* (via --load-default-assemblies), or knowing
|
||||
the actual path to the GAC (to explicity load the assemblies).
|
||||
* Makefile: Update TARGETS so that it references the correct temporary
|
||||
files. This allows ``make clean'' to actually clean up the appropriate
|
||||
files, permitting proper rebuilds.
|
||||
* TypeLoader.cs: Add assembly references collection, and use
|
||||
Assembly.LoadWithPartialName() to load referenced assemblies. Change
|
||||
internal collection type from IList<string> to IList<Assembly>.
|
||||
* TypeReflectorApp.cs: Add handling of referenced assemby information.
|
||||
* TypeReflectorOptions.cs: Add referenceAssembies argument, and change
|
||||
showInheritedMembers option so referenceAssemblies can use -r. This
|
||||
provides a command-line parameter more similar to mcs, etc.
|
||||
* displayers/gtk/GtkTypeDisplayer.cs: Don't store uints in the TreeStore,
|
||||
just ints. This removes a number of Gtk-WARNING messages.
|
||||
* type-reflector: Permit spaces to be in the script filename.
|
||||
|
||||
2004-06-02 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Makefile: Update GUI_GTK_LIBS variable for new mcs syntax (-pkg:...).
|
||||
|
||||
2004-03-07 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Makefile: The "gui" target needs to use the "gtkui" and "swfui" sub-target
|
||||
names; the gtk and swf targets no longer exist.
|
||||
|
||||
2003-11-30 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Makefile: change names of gtk & swf targets. Prior versions of
|
||||
type-reflector didn't have a `dispayers' directory, but had
|
||||
`displayers/gtk', etc., as top-level dirs.
|
||||
Since these files are touched during the build process, this creates a CVS
|
||||
update conflict (CVS expects a `gtk' directory, but a `gtk' file may
|
||||
exist).
|
||||
Change the names of the files generated (hence, the target names) to avoid
|
||||
this conflict.
|
||||
|
||||
2003-11-23 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Makefile: Add rule to create TestTypes.dll, used in testing.
|
||||
|
||||
2003-10-25 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Makefile: Add displayers/gtk/AppWindowManager.cs to build.
|
||||
|
||||
2003-??-?? Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Makefile: Merged contents of Makefile & makefile.gnu & makefile.core.
|
||||
This simplifies building (only 1 Makefile), and makes it easier to be a
|
||||
part of mono-tools. Also added new targets, such as "dist", "distdir".
|
||||
* makefile.core: removed
|
||||
* makefile.gnu: removed
|
||||
|
||||
2003-09-28 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TypeReflectorApp.cs: Update Version, Cope with ITypeDisplayer changes.
|
||||
* makefile.core: add artwork resources
|
||||
* type-reflector.exe.config: add Gtk# Displayer trace switch
|
||||
|
||||
2003-08-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TypeReflectorApp.cs: Update Version, more debugging information.
|
||||
|
||||
2003-07-05 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TypeReflectorApp.cs: Ensure that TraceListeners are flushed before program
|
||||
exit. This ensures that any TraceListeners added in the .config file will
|
||||
get everything they should.
|
||||
* TypeReflectorOptions.cs: Remove "Experimental" wording, and make sure that
|
||||
the right information is displayed.
|
||||
* type-reflector.exe.config: Add additional examples (use of <assert/>).
|
||||
|
||||
2003-07-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* IPolicy.cs: New File. Root interface for all "policies" -- things that can
|
||||
change, such as INodeFinder, and INodeFormatter.
|
||||
* Policy.cs: Default implementation of IPolicy interface.
|
||||
* README: updated documentation
|
||||
* TODO: Updated TODO list
|
||||
* TypeFactory.cs: I don't want the Gtk# GUI displaying "short names" for
|
||||
finders, formatters, etc. For example, to get C# formatting, you'd
|
||||
normally pass `--formatter=csharp'. I don't want Gtk# showing "csharp," I
|
||||
want it to show "C#". Furthermore, I don't want to update the GUI
|
||||
whenever I add a new language. The solution is to add extra information
|
||||
to the type-reflector.exe.config file. Now, instead of having the "key"
|
||||
contain the actual factory key, it includes both the key and the
|
||||
description, in the format "key:description," so the C# formatter can be
|
||||
described as "csharp:C#". This could have been done with the "value"
|
||||
instead of the "key", but ':' could be special in assembly names.
|
||||
- Introduce TypeFactoryEntry, which contains the factory Key (everything
|
||||
before the ':'), the Description (everything after the ':'), and the Type
|
||||
(the value of the .config-file entry).
|
||||
- TypeFactory is now a map from string -> TypeFactoryEntry (instead of
|
||||
string -> Type).
|
||||
* TypeLoader.cs: Allow directories to be specified. This requires expanding
|
||||
directories into a list of .dll's and .exe's to open. Alternatively, we
|
||||
could just open *all* files in the directory, but this seems safer for
|
||||
now. Also, it's *not* recursive. This could change in the future.
|
||||
* TypeReflectorApp.cs: Update version number, update for TypeFactory
|
||||
changes, make '.' the default Type search character (instead of requiring
|
||||
it as a parameter), ITypeDisplayer changes
|
||||
* TypeReflectorOptions.cs: More far-reaching changes. It didn't make sense
|
||||
to default to opening all assemblies -- this took forever -- and not
|
||||
provide a default type search, so now it's flipped -- there are no default
|
||||
assemblies (one must be provided, through -a), but the default Type search
|
||||
is '.', which is the only sensible default. Update documentation.
|
||||
* makefile.core: Cope with new files, install type-reflector script.
|
||||
* type-reflector: shell script for Unix-like systems so that typing
|
||||
type-reflector.exe isn't necessary. Script idea initially proposed on
|
||||
mono-list, IIRC.
|
||||
* type-reflector.exe.config: Add descriptions for various policies
|
||||
(displayers and formatters).
|
||||
|
||||
2003-06-26 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TypeFactory.cs: Make a Factory look like a Dictionary. Useful for
|
||||
enumerating over factory contents (e.g. debugging)
|
||||
* TypeLoader.cs: Print the regex out before constructing the Regex. Useful
|
||||
when the Regex constructor throws an exception.
|
||||
* TypeReflectorApp.cs: Misc. Changes:
|
||||
- Added static Version propery, which is used in the Gtk# About dialog
|
||||
- Add/Remove some diagnostics messages
|
||||
- Provide overloads for CreateFinder & CreateFormatter. These are used in
|
||||
the Gtk# front-end to permit dynamic language selection.
|
||||
* makefile.core: simplify the resource name for the Gtk# .glade file, add
|
||||
the gnome-sharp.dll library for Gtk#.
|
||||
|
||||
2003-02-19 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TestTypes.cs: Added test cases.
|
||||
* makefile.core: Re-enabled debugging as default
|
||||
|
||||
2003-01-16 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* makefile.core: Fix the multiple-build problem. Again. Hopefully it'll
|
||||
stay fixed this time...
|
||||
|
||||
2003-01-14 Jonathan Pryor <jonpryor@vt.edu>
|
||||
- General: massive file movement. I felt it would be cleaner if related
|
||||
files were in the same directory, instead of (nearly) everything
|
||||
cluttering up the root directory. Since the current architecture seems
|
||||
pretty final (I don't see any major changes; it works) I split things up
|
||||
among namespace boundaries.
|
||||
* ConsoleTypeDisplayer.cs: moved to displayers/
|
||||
* ITypeDisplayer.cs: moved to displayers/
|
||||
* TypeDisplayer.cs: moved to displayers/
|
||||
* IndentingTextWriter.cs: moved to displayers/
|
||||
* gtk/: moved to displayers/
|
||||
* swf/: moved to displayers/
|
||||
* ExplicitNodeFinder.cs: moved to finders/
|
||||
* GroupingNodeFinder.cs: moved to finders/
|
||||
* INodeFinder.cs: moved to finders/
|
||||
* NodeFinder.cs: moved to finders/
|
||||
* ReflectionNodeFinder.cs: moved to finders/
|
||||
* INodeFormatter.cs: moved to formatters/
|
||||
* NodeFormatter.cs: moved to formatters/
|
||||
* DefaultNodeFormatter.cs: moved to formatters/
|
||||
* CSharpNodeFormatter.cs: moved to formatters/
|
||||
* VBNodeFormatter.cs: moved to formatters/
|
||||
* makefile.core: update for new file locations.
|
||||
|
||||
2003-01-12 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* makefile.core: Add dependencies to `gui' target so it doesn't rebuild when
|
||||
it doesn't need to. Reported by gonzalo.
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* CSharpNodeFormatter.cs: New properties required by LanguageNodeFormatter
|
||||
* LanguageNodeFormatter.cs: Allow more declarative control over generation
|
||||
of Property members.
|
||||
* ReflectionNodeFinder.cs: Make sure the instance is appropriate. This
|
||||
allows us to view static property values when using the
|
||||
ReflectionNodeFinder.
|
||||
* VBNodeFormatter.cs: New properties required by LanguageNodeFormatter
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
- General: Specify the order of displayers to use in the .config file. This
|
||||
allows us to have "intelligent" defaults, so that (by default) GUI
|
||||
front-ends are preferred to console output. If no GUI is supported, then
|
||||
fallback to console output.
|
||||
* README: Updates
|
||||
* TypeReflectorApp.cs: Follow the "displayer-order" when finding the default
|
||||
displayer.
|
||||
* TypeReflectorOptions.cs: Change default Displayer to "" so that we know if
|
||||
the user has specified a preferred displayer.
|
||||
* type-reflector.exe.config: Specify the default displayer ordering.
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TypeReflectorApp.cs: Don't always require that types be specified on the
|
||||
command line. This isn't necessary for the GUI front-ends, as the user
|
||||
can just open an assembly from within the app after it's running.
|
||||
* IndentingTextWriter.cs: Move to Mono.TypeReflector.Displayers.
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
- General: Namespace partitioning. It was getting annoying (when using
|
||||
type-reflector to display itself) to have ~70 classes in a single
|
||||
namespace. So I split up the classes into namespace according to
|
||||
function. For example, Finders (ExplicitNodeFinder, ReflectionNodeFinder)
|
||||
went into Mono.TypeReflector.Finders.
|
||||
* CSharpNodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* ConsoleTypeDisplayer.cs: Moved into Mono.TypeReflector.Displayers.
|
||||
* DefaultNodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* ExplicitNodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* Factories.cs: Reference the appropriate namespaces.
|
||||
* GroupingNodeFinder.cs: Moved into Mono.TypeReflector.Finders.
|
||||
* INodeFinder.cs: Moved into Mono.TypeReflector.Finders.
|
||||
* INodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* ITypeDisplayer.cs: Moved into Mono.TypeReflector.Displayers.
|
||||
* LanguageNodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* Node.cs: Reference the appropriate namespaces.
|
||||
* NodeFinder.cs: Moved into Mono.TypeReflector.Finders.
|
||||
* NodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* NodeGrouper.cs: Moved into Mono.TypeReflector.Finders.
|
||||
* ReflectionNodeFinder.cs: Moved into Mono.TypeReflector.Finders.
|
||||
* TypeDisplayer.cs: Moved into Mono.TypeReflector.Displayers.
|
||||
* TypeReflectorApp.cs: Reference the appropriate namespaces.
|
||||
* VBNodeFormatter.cs: Moved into Mono.TypeReflector.Formatters.
|
||||
* type-refelctor.exe.config: Update type names.
|
||||
|
||||
2003-01-09 Jonathan Pryor <jonpryor@vt.edu>
|
||||
- General: Do the most hackish thing I've ever thought of. OK, perhaps not
|
||||
the *most*, but it must be up there...
|
||||
- Problem: type-reflector supports multiple GUI toolkits. However, I don't
|
||||
want to require the existance of any one of them to compile. Because of
|
||||
this, the default has been to support only console output. Nothing else
|
||||
was supported by the default build.
|
||||
- Solution: Try to build everything. Literally. Due to the wonders of the
|
||||
shell's || operator, if one build fails we can provide another build as a
|
||||
backup. This boils down to doing the following:
|
||||
|
||||
make gui-all || make gtk || make swf || make console
|
||||
|
||||
The "make console" is to ensure that, at the very least, console-support
|
||||
is built-in. If no GUI toolkit is available, we'll at least have
|
||||
something.
|
||||
- Good news: this works, and will support as many toolkits as the build
|
||||
platform supports.
|
||||
- Bad news: It may invoke several compilations. For example, my Windows box
|
||||
doesn't have Gtk# support, so "gui-all" and "gtk" both fail before "swf"
|
||||
successfully compiles. That's two failed compilation efforts, resulting
|
||||
in additional overhead.
|
||||
* Makefile: provide a MAKEFILE variable so that makefile.core can invoke the
|
||||
correct top-level makefile for its sub-makes (see description above)
|
||||
* makefile.core:
|
||||
- "all" invokes the "gui" target, not "console". "gui", in turn,
|
||||
carries out the process described above. It isn't pretty.
|
||||
- removed support for "linux" target. This hasn't been used for awhile.
|
||||
* makefile.gnu: provide a MAKEFILE variable so that makefile.core can invoke
|
||||
the correct top-level makefile for its sub-makes (see description above)
|
||||
|
||||
2003-01-09 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TypeReflectorApp.cs: Remove hard-coded factory initialization and #ifdef
|
||||
preprocessor use. Factory information is located in
|
||||
type-reflector.exe.config now. This removes dependence on the
|
||||
preprocessor, simplifies addition of new formatters/etc. (For example, if
|
||||
you want to add a new formatter, you can just edit
|
||||
type-reflector.exe.config with the appropriate type.)
|
||||
* makefile.core:
|
||||
- Remove -d:SYMBOL compiler arguments for GUI support
|
||||
- Due to above, we can simplify GUI targets to use $(CSC_INVOKE). (I
|
||||
would have done this before, but bug 36410 prevented this from working.)
|
||||
* type-reflector.exe.config: Provide new sections to specify the displayers,
|
||||
finders, and formatters that can be used.
|
||||
|
||||
2003-01-08 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* AssemblyInfo.cs: New; Assembly Information (version, etc.)
|
||||
* DefaultNodeFormatter.cs: Use AddMethodReturnValue to invoke methods
|
||||
* ITypeDisplayer.cs: Provide a way to display error messages
|
||||
* LanguageNodeFormatter.cs: Use AddMethodReturnValue to invoke methods
|
||||
* Makefile: Since I need to use csc.exe to compile System.Windows.Forms
|
||||
support, I need a way to use directory separators in a (reasonably)
|
||||
portable fashion. Hennce the DS (Directory Separator) variable, which
|
||||
holds the directory separator of the current platform. Set it to
|
||||
backslash for Windows.
|
||||
* NodeFormatter.cs:
|
||||
- Provide an option to enable/disable invoking methods. See README for a
|
||||
short discussion of why this is needed. (Search for [1].)
|
||||
- Minor formatting changes.
|
||||
- Add AddMethodReturnValue() function. This is used by derived classes,
|
||||
instead of directly invoking a method, if invocation is permitted.
|
||||
* README: Updates.
|
||||
* TypeDisplayer.cs:
|
||||
- Check for a null namespace. This apparently can happen under .NET.
|
||||
I'm not sure why, but handle it.
|
||||
- Provide default implementation of ITypeDisplayer.ShowError().
|
||||
* TypeFactory.cs: Remove Console messages, clean formatting.
|
||||
* TypeReflectorApp.cs:
|
||||
- There's > 1 factory now. Change names so it makes more sense.
|
||||
- Add "swf" displayer.
|
||||
- Use ITypeDisplayer.ShowError() for errors
|
||||
- Handle new program options for formatter objects
|
||||
* TypeReflectorOptions.cs: Add option to enable method invocation. Clean up
|
||||
formatting.
|
||||
* makefile.core:
|
||||
- Add "swf" target for System.Windows.Forms display:
|
||||
- csc.exe wants ".dll" appended to referenced assemblies. Add this.
|
||||
- csc.exe wants a colon, not a space, after -r. Fix.
|
||||
- Add new files (AssemblyInfo.cs, swf/*.cs)
|
||||
- Use $(DS) where appropriate.
|
||||
* makefile.gnu: Add $(DS) variable
|
||||
* type-reflector.exe.config: Comment out default listeners, enable
|
||||
type-factory messages by default.
|
||||
|
||||
2003-01-02 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* NodeFormatter.cs: Change formatting of error message.
|
||||
* NodeInfo.cs: Nested types are MemberTypes.NestedType; set as
|
||||
NodeTypes.Type so we don't get error messages under .NET.
|
||||
|
||||
2002-12-31 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ConsoleTypeDisplayer.cs: New; Display reflection information to the console
|
||||
* CSharpNodeFormatter.cs: Most formatting information was moved to
|
||||
LanguageNodeFormatter.cs (to permit sharing with the VBNodeFormatter)
|
||||
* ExplicitNodeFinder.cs: Updates due to NodeFinder changes.
|
||||
* Factories.cs: Add new "Displayer" factory, remove "Factory" from name of
|
||||
factory objects; the fact they're in a "Factories" class should be
|
||||
sufficient.
|
||||
* IndentingTextWriter.cs: Ensure that if a string sent to Write or WriteLine
|
||||
contains embedded newlines, that we indent the text after the newlines
|
||||
appropriately.
|
||||
* ITypeDisplayer.cs: New; Abstraction for displaying reflection information
|
||||
* LanguageNodeFormatter.cs: Massive cleanup & Consolidation of features.
|
||||
Now works as a control class for generating Language-like output,
|
||||
simplifying C# and VB.NET language formatting.
|
||||
* Makefile: Most contents moved to `makefile.core'; just sets variables and
|
||||
forwards operation to `makefile.core'.
|
||||
* Node.cs: Debugging ToString() implementation
|
||||
* NodeFinder.cs: Change virtual Get* methods to Add* methods, as
|
||||
they're supposed to Add stuff to the Collection object passed as the first
|
||||
paramter, not actually return ("get") anything; Removed `maxDepth', as
|
||||
it's not used in the NodeFinder.
|
||||
* NodeFormatter.cs: Move language-like attribute formatting to
|
||||
LanguageNodeFormatter; check that base type isn't null before accessing
|
||||
its name; recent CVS snapshots have the base object of interfaces as the
|
||||
null object (before it was System.Object); this may be a mono bug.
|
||||
* NodeInfo.cs: Debugging ToString() implementation
|
||||
* ProgramOptions.cs: Make classes public, not internal
|
||||
* README: Updates
|
||||
* ReflectionNodeFinder.cs: Updates due to NodeFinder changes.
|
||||
* TestTypes.cs: More tests
|
||||
* TypeDisplayer.cs: New; Helper implementation for ITypeDisplayer
|
||||
* TypeFactory.cs: Trace/log the exception generated when creating a new
|
||||
object
|
||||
* TypeLoader.cs: Take a list of types to search for, not just a single type.
|
||||
This simplifies looking for types, as we can do a single search for all
|
||||
types, instead of separate searches for each type. Also improves
|
||||
performance.
|
||||
* TypeReflectorApp.cs: New; Formerly ConsoleOutput.cs; sets things in motion
|
||||
* TypeReflectorOptions.cs: Make public; Add --displayer argument
|
||||
* VBNodeFormatter.cs: New; Displayer reflection information in VB.NET
|
||||
* gtk: new directory for Gtk# front-end
|
||||
* makefile.core: New; Common makefile rules shared between Makefile,
|
||||
makefile.gnu
|
||||
* makefile.gnu: New; makefile used on Linux, used by tools/makefile.gnu for
|
||||
recursive makes.
|
||||
* type-reflector.exe.config: Add new switch, sample listener
|
||||
|
||||
2002-12-21 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ConsoleOutput.cs: Use a Switch for trace messages.
|
||||
* ExplicitNodeFinder.cs: Use a Switch for trace messages.
|
||||
* GroupingNodeFinder.cs: Use a Switch for trace messages.
|
||||
* IndentingTextWriter.cs: Use a Switch for trace messages; remove copyright
|
||||
statement.
|
||||
* NodeFinder.cs: Use a Switch for trace messages.
|
||||
* TypeLoader.cs: Use a Switch for trace messages; remove copyright
|
||||
statement.
|
||||
* type-reflector.exe.config: default .config file (disable all trace
|
||||
messages)
|
||||
|
||||
2002-12-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* TestTypes.cs: Use a different attribute type for [return:] attribute on
|
||||
TestClass.PublicMethod, as mcs doesn't support [return:] attributes yet
|
||||
and it was generating an error for the two "MyAttribute" attributes.
|
||||
|
||||
2002-12-08 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* DESIGN: Read this to understand the new design that was implemented.
|
||||
* ConsoleOutput.cs: Deal with "new world order" of Node objects
|
||||
* Makefile: minor cleanup
|
||||
* TestTypes.cs: additional tests
|
||||
* TypeReflectorOptions.cs: new options
|
||||
* CSharpTypeDisplayer.cs: removed
|
||||
* ExplicitTypeDisplayer.cs: removed
|
||||
* IndentingTypeDisplayer.cs: removed
|
||||
* ReflectionTypeDisplayer.cs: removed
|
||||
* TypeDisplayer.cs: removed
|
||||
* TypeDisplayerFactory.cs: removed
|
||||
* CSharpNodeFormatter.cs: new file
|
||||
* DefaultNodeFormatter.cs: new file
|
||||
* ExplicitNodeFinder.cs: new file
|
||||
* Factories.cs: new file
|
||||
* GroupingNodeFinder.cs: new file
|
||||
* INodeFinder.cs: new file
|
||||
* INodeFormatter.cs: new file
|
||||
* LICENSE: new file
|
||||
* LanguageNodeFormatter.cs: new file
|
||||
* Node.cs: new file
|
||||
* NodeFinder.cs: new file
|
||||
* NodeFormatter.cs: new file
|
||||
* NodeGrouper.cs: new file
|
||||
* NodeInfo.cs: new file
|
||||
* NodeTypes.cs: new file
|
||||
* ReflectionNodeFinder.cs: new file
|
||||
* TypeFactory.cs: new file
|
||||
|
||||
2002-09-04 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* CSharpTypeDisplayer.cs: Better attribute output
|
||||
* TestTypes.cs: Improve test cases
|
||||
|
||||
2002-09-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ChangeLog: Added
|
||||
* ConsoleOutput.cs: s/parse/display; makes more sense
|
||||
* ExplicitTypeDisplayer.cs: Add additional output
|
||||
* IndentingTextWriter.cs: Allow indenting to be specified
|
||||
* ProgramOptions.cs: Allow more space for program options in output
|
||||
* ReflectionTypeDisplayer.cs: Formatting changes
|
||||
* TypeDisplayer.cs: Trivial formatting changes
|
||||
* TypeReflectorOptions.cs: Re-enable program option, formatting changes
|
||||
|
||||
# vim: noexpandtab
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
Overview:
|
||||
--------
|
||||
The major design is that of a connected model & controller. No view (as in
|
||||
MVC) is needed because the data that is modelled will never change--it's
|
||||
information about types, which must be static (or the CLR gets mad).
|
||||
|
||||
The main problem (at this point) is one of future directions: I'd like to have
|
||||
a GUI front-end. Ideally, the GUI and console front-ends would use the same
|
||||
internal representation, which we could format as desired (e.g. format for
|
||||
different languages such as C#, Visual Basic, CLOS, Eiffel, etc.).
|
||||
|
||||
|
||||
GUI Issues:
|
||||
----------
|
||||
Additionally, with the GUI we don't want the entire tree to be generated --
|
||||
that would take too long. We want sub-nodes to be expanded only when required
|
||||
(the user clicks on them), and not sooner.
|
||||
|
||||
The GUI actually becomes the most complicated design consideration. If we
|
||||
have a tree, we need to show to the user that the tree can be expanded by
|
||||
having a `+' next to it. This is typically done by having sub-nodes under the
|
||||
node to click. But these are the nodes we want to avoid displaying!
|
||||
|
||||
I can think of two solutions to this: show them anyway, but not *their*
|
||||
children (so we only need to generate two levels when starting -- the
|
||||
top-level elements and their immediate children). We thus always have the
|
||||
children -- permitting (somewhat) rapid expansion of tree nodes, but when the
|
||||
children are displayed we'll have to grab the grand-children.
|
||||
|
||||
Alternatively, instead of having the children available, we have a single
|
||||
placeholder available, and the first time the `+' is clicked we remove the
|
||||
placeholder and generate the immediate children that should be displayed.
|
||||
|
||||
The problem with either of these approaches is that it requires that type
|
||||
displaying be interruptable. The 0.2 version had it simpler -- it would
|
||||
stream the type information to the console, following all children as it found
|
||||
them. This was simple, but it didn't permit a GUI view.
|
||||
|
||||
Hopefully, all of these issues can be handled in the design below.
|
||||
|
||||
|
||||
Categories:
|
||||
----------
|
||||
I would like to retain the current 0.2 behavior of categorizing the output,
|
||||
where a category would be Fields, Methods, Properties, Constructors, etc.
|
||||
|
||||
The question becomes: how is this supported? We want (e.g.) all interfaces to
|
||||
be grouped together; who maintains the grouping?
|
||||
|
||||
Answer: NodeGrouper.
|
||||
|
||||
|
||||
Nodes:
|
||||
-----
|
||||
|
||||
A node is an element in a tree hierarchy. In a GUI, it would be the
|
||||
underyling dat for an item in a tree-view (hierarchical display widget).
|
||||
It has a display string. It has sub-nodes (children). It also has an
|
||||
associated `object' which could be used for
|
||||
additional output possibilities. (This isn't explored very far, but I can see
|
||||
it as being useful. The `object' would be a Type instance for class names, a
|
||||
`MemberInfo' for members, etc.)
|
||||
|
||||
Nodes have three classes associated with them: a NodeFormatter, which formats
|
||||
the display string described above. It also has a NodeFinder object, which is
|
||||
used to determine which sub-nodes will be displayed. Finally, it has a
|
||||
NodeInfo instance, which collects various information about the node such as
|
||||
its type (NodeTypes) and related information.
|
||||
|
||||
The NodeInfo type is used as the sole communication between NodeFinder and
|
||||
NodeFormatter. A NodeFinder returns a collection of NodeInfo objects, each of
|
||||
which is sent to the NodeFormatter object before being displayed.
|
||||
|
||||
Categorization can be done through "decorators" (see GoF) on the NodeFinder.
|
||||
|
||||
|
||||
Design:
|
||||
------
|
||||
|
||||
Controller [View]
|
||||
\ /
|
||||
\ /
|
||||
Node
|
||||
/ | \
|
||||
/ | \
|
||||
INodeFormatter INode- NodeInfo
|
||||
Finder
|
||||
|
||||
|
||||
Controller:
|
||||
- GUI App, Console Main program
|
||||
-- Controls output, display
|
||||
|
||||
[View]:
|
||||
- Display device for Nodes.
|
||||
- Note quite MVC; there's no feedback mechanism so that Views change when
|
||||
the Node changes
|
||||
- Nodes can't change; the type system is static
|
||||
- However, this could be added in the future if necessary.
|
||||
|
||||
Node (Model)
|
||||
- Members:
|
||||
- string Description {get; set;}
|
||||
-- The display string
|
||||
- NodeInfo NodeInfo {get;}
|
||||
-- Information about this node
|
||||
- NodeCollection GetChildren ();
|
||||
-- Returns the sub-nodes of this node
|
||||
|
||||
INodeFormatter:
|
||||
-- Formats a node for output (particular language, etc.)
|
||||
- Methods:
|
||||
- string GetDescription (NodeInfo)
|
||||
- LanguageFormatter
|
||||
- CSharpFormatter, ...
|
||||
|
||||
INodeFinder:
|
||||
-- Decides which children are present
|
||||
- Members:
|
||||
- NodeInfoCollection GetChildren(NodeInfo);
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Factory.cs: Declares finder and formatter policy factories
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using Mono.TypeReflector.Displayers;
|
||||
using Mono.TypeReflector.Finders;
|
||||
using Mono.TypeReflector.Formatters;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public sealed class Factories
|
||||
{
|
||||
public sealed class FinderTypeFactory : TypeFactory
|
||||
{
|
||||
public new INodeFinder Create (object key)
|
||||
{
|
||||
return (INodeFinder) base.Create (key);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class FormatterTypeFactory : TypeFactory
|
||||
{
|
||||
public new INodeFormatter Create (object key)
|
||||
{
|
||||
return (INodeFormatter) base.Create (key);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DisplayerTypeFactory : TypeFactory
|
||||
{
|
||||
public new ITypeDisplayer Create (object key)
|
||||
{
|
||||
return (ITypeDisplayer) base.Create (key);
|
||||
}
|
||||
}
|
||||
|
||||
public static FinderTypeFactory Finder = new FinderTypeFactory ();
|
||||
public static FormatterTypeFactory Formatter = new FormatterTypeFactory ();
|
||||
public static DisplayerTypeFactory Displayer = new DisplayerTypeFactory ();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// INodePolicy.cs: Root Policy interface to describe other policies.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2003 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public interface IPolicy : ICloneable {
|
||||
|
||||
string Description {get; set;}
|
||||
string FactoryKey {get; set;}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (C) 2002 Jonathan Pryor
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to
|
||||
do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
# this is used in the MCS build system, but it doesn't make sense to me.
|
||||
# Where's OS defined?
|
||||
ifndef PLATFORM
|
||||
ifeq ($(OS), Windows_NT)
|
||||
PLATFORM = win32
|
||||
else
|
||||
PLATFORM = linux
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM), win32)
|
||||
CSC = csc
|
||||
DS=\\
|
||||
else
|
||||
CSC = mcs
|
||||
DS=/
|
||||
endif
|
||||
|
||||
PACKAGE = type-reflector
|
||||
VERSION = 0.8
|
||||
topdir = .
|
||||
mkinstalldirs = mkdir -p
|
||||
|
||||
INSTALL = install
|
||||
|
||||
PROGRAM = type-reflector.exe
|
||||
|
||||
PROGRAM_LIBS = -r:System.dll
|
||||
|
||||
PROGRAM_FLAGS = -out:$(PROGRAM) -d:TRACE -d:DEBUG $(PROGRAM_LIBS)
|
||||
|
||||
# For debugging
|
||||
CSCFLAGS = /debug+ /debug:full
|
||||
# CSCFLAGS =
|
||||
|
||||
MONO = mono
|
||||
|
||||
DISPLAYERS_DIR=displayers$(DS)
|
||||
|
||||
DISPLAYERS_FILES = \
|
||||
$(DISPLAYERS_DIR)ConsoleTypeDisplayer.cs \
|
||||
$(DISPLAYERS_DIR)IndentingTextWriter.cs \
|
||||
$(DISPLAYERS_DIR)ITypeDisplayer.cs \
|
||||
$(DISPLAYERS_DIR)TypeDisplayer.cs \
|
||||
|
||||
FINDERS_DIR=finders$(DS)
|
||||
|
||||
FINDERS_FILES = \
|
||||
$(FINDERS_DIR)ExplicitNodeFinder.cs \
|
||||
$(FINDERS_DIR)GroupingNodeFinder.cs \
|
||||
$(FINDERS_DIR)INodeFinder.cs \
|
||||
$(FINDERS_DIR)NodeFinder.cs \
|
||||
$(FINDERS_DIR)ReflectionNodeFinder.cs \
|
||||
|
||||
FORMATTERS_DIR=formatters$(DS)
|
||||
|
||||
FORMATTERS_FILES = \
|
||||
$(FORMATTERS_DIR)CSharpNodeFormatter.cs \
|
||||
$(FORMATTERS_DIR)DefaultNodeFormatter.cs \
|
||||
$(FORMATTERS_DIR)INodeFormatter.cs \
|
||||
$(FORMATTERS_DIR)LanguageNodeFormatter.cs \
|
||||
$(FORMATTERS_DIR)NodeFormatter.cs \
|
||||
$(FORMATTERS_DIR)VBNodeFormatter.cs \
|
||||
|
||||
PROGRAM_FILES = \
|
||||
AssemblyInfo.cs \
|
||||
Factories.cs \
|
||||
IPolicy.cs \
|
||||
Node.cs \
|
||||
NodeGrouper.cs \
|
||||
NodeInfo.cs \
|
||||
Policy.cs \
|
||||
NodeTypes.cs \
|
||||
ProgramOptions.cs \
|
||||
TestTypes.cs \
|
||||
TextFormatter.cs \
|
||||
TypeFactory.cs \
|
||||
TypeLoader.cs \
|
||||
TypeReflectorApp.cs \
|
||||
TypeReflectorOptions.cs \
|
||||
$(DISPLAYERS_FILES) \
|
||||
$(FINDERS_FILES) \
|
||||
$(FORMATTERS_FILES) \
|
||||
|
||||
CSC_INVOKE = $(CSC) $(CSCFLAGS) $(PROGRAM_FLAGS) $(PROGRAM_FILES) $(PROGRAM_LIBS)
|
||||
|
||||
GUI_LIBS = -r:System.Drawing.dll
|
||||
|
||||
GUI_ART_DIR = $(DISPLAYERS_DIR)art$(DS)
|
||||
|
||||
GUI_RESOURCES = \
|
||||
-resource:$(GUI_ART_DIR)abstract.png,abstract.png \
|
||||
-resource:$(GUI_ART_DIR)class.png,class.png \
|
||||
-resource:$(GUI_ART_DIR)constructor.png,constructor.png \
|
||||
-resource:$(GUI_ART_DIR)enum.png,enum.png \
|
||||
-resource:$(GUI_ART_DIR)event.png,event.png \
|
||||
-resource:$(GUI_ART_DIR)field.png,field.png \
|
||||
-resource:$(GUI_ART_DIR)interface.png,interface.png \
|
||||
-resource:$(GUI_ART_DIR)method.png,method.png \
|
||||
-resource:$(GUI_ART_DIR)prop-read-only.png,prop-read-only.png \
|
||||
-resource:$(GUI_ART_DIR)prop-read-write.png,prop-read-write.png \
|
||||
-resource:$(GUI_ART_DIR)prop-write-only.png,prop-write-only.png \
|
||||
-resource:$(GUI_ART_DIR)sealed.png,sealed.png \
|
||||
-resource:$(GUI_ART_DIR)transparent.png,transparent.png
|
||||
|
||||
GUI_GTK_DIR = $(DISPLAYERS_DIR)gtk$(DS)
|
||||
|
||||
GUI_GTK_FILES = \
|
||||
$(GUI_GTK_DIR)GtkTypeDisplayer.cs \
|
||||
$(GUI_GTK_DIR)AppWindowManager.cs \
|
||||
|
||||
GUI_GTK_GLADE_FILE = $(GUI_GTK_DIR)type-reflector.glade
|
||||
|
||||
GUI_GTK_FLAGS = -resource:$(GUI_GTK_GLADE_FILE),type-reflector.glade
|
||||
|
||||
GUI_GTK_LIBS = -pkg:gtk-sharp -pkg:glade-sharp -pkg:gnome-sharp
|
||||
|
||||
GUI_SWF_DIR = $(DISPLAYERS_DIR)swf$(DS)
|
||||
|
||||
GUI_SWF_FILES = \
|
||||
$(GUI_SWF_DIR)SwfWindow.cs \
|
||||
$(GUI_SWF_DIR)SwfTypeDisplayer.cs \
|
||||
|
||||
GUI_SWF_LIBS = -r:System.Windows.Forms.dll
|
||||
|
||||
GUI_SWF_FLAGS =
|
||||
|
||||
# These are files that are `touch'ed during the build process to prevent
|
||||
# constant rebuilding.
|
||||
TARGETS = gui-all gtkui swfui
|
||||
|
||||
all: gui test-assemblies
|
||||
|
||||
test-assemblies : TestTypes.dll
|
||||
|
||||
TestTypes.dll: TestTypes.cs
|
||||
$(CSC) -out:$@ -t:library $<
|
||||
|
||||
console : $(PROGRAM)
|
||||
|
||||
$(PROGRAM) : $(PROGRAM_FILES)
|
||||
$(CSC_INVOKE)
|
||||
chmod +x $(PROGRAM)
|
||||
|
||||
# Pick the appropriate GUI Toolkit...
|
||||
# Fall back on console-only if nothing else compiles.
|
||||
gui: $(PROGRAM_FILES) $(GUI_GTK_FILES) $(GUI_GTK_GLADE_FILE) $(PROGRAM_FILES) $(GUI_SWF_FILES)
|
||||
$(MAKE) gui-all || $(MAKE) gtkui || $(MAKE) swfui || $(MAKE) console
|
||||
|
||||
# Compile in support for all GUI front-ends (Gtk#, Swf, and anything else...)
|
||||
gui-all: $(PROGRAM_FILES) $(GUI_GTK_FILES) $(GUI_GTK_GLADE_FILE) $(PROGRAM_FILES) $(GUI_SWF_FILES)
|
||||
$(CSC_INVOKE) $(GUI_GTK_FLAGS) $(GUI_SWF_FLAGS) $(GUI_GTK_FILES) $(GUI_SWF_FILES) $(GUI_GTK_LIBS) $(GUI_SWF_LIBS) $(GUI_RESOURCES) $(GUI_LIBS)
|
||||
chmod +x $(PROGRAM)
|
||||
touch $@
|
||||
|
||||
# Gtk# front-end
|
||||
gtkui: $(PROGRAM_FILES) $(GUI_GTK_FILES) $(GUI_GTK_GLADE_FILE)
|
||||
$(CSC_INVOKE) $(GUI_GTK_FLAGS) $(GUI_GTK_FILES) $(GUI_GTK_LIBS) $(GUI_RESOURCES) $(GUI_LIBS)
|
||||
chmod +x $(PROGRAM)
|
||||
touch $@
|
||||
|
||||
# System.Windows.Forms front-end
|
||||
swfui: $(PROGRAM_FILES) $(GUI_SWF_FILES)
|
||||
$(CSC_INVOKE) $(GUI_SWF_FLAGS) $(GUI_SWF_FILES) $(GUI_SWF_LIBS) $(GUI_RESOURCES) $(GUI_LIBS)
|
||||
chmod +x $(PROGRAM)
|
||||
touch $@
|
||||
|
||||
test-run : $(PROGRAM)
|
||||
$(MONO) $(PROGRAM) -A $(PROGRAM) $(ARGS)
|
||||
|
||||
test-type : $(PROGRAM)
|
||||
$(MONO) $(PROGRAM) -A $(PROGRAM) --max-depth=10000 $(ARGS) TestClass$$
|
||||
|
||||
run : $(PROGRAM)
|
||||
$(MONO) $(PROGRAM) $(ARGS)
|
||||
|
||||
windows:
|
||||
NAnt -buildfile:type-reflector.build
|
||||
|
||||
clean:
|
||||
rm -f *.exe *.pdb *.dll *.dbg *~ $(TARGETS) $(DISPLAYERS_DIR)*~ $(GUI_GTK_DIR)*~ $(GUI_SWF_DIR)*~ $(FINDERS_DIR)*~ $(FORMATTERS_DIR)*~
|
||||
|
||||
# We don't generate any files for building, so don't do anything
|
||||
distclean: clean
|
||||
|
||||
|
||||
TR_FILES = \
|
||||
$(PROGRAM) \
|
||||
$(PROGRAM).config \
|
||||
|
||||
|
||||
install: $(BIN_FILES) $(TR_FILES)
|
||||
if test "x$$prefix" = x; then \
|
||||
echo Usage is: make -f makefile.gnu install prefix=YOURPREFIX; \
|
||||
exit 1; \
|
||||
fi
|
||||
mkdir -p "$(prefix)/bin/"
|
||||
mkdir -p "$(prefix)/share/$(PACKAGE)/"
|
||||
cat type-reflector.in | sed 's:@PREFIX@:$(prefix):g' > "$(prefix)/bin/$(PACKAGE)"
|
||||
chmod +x "$(prefix)/bin/$(PACKAGE)"
|
||||
for i in $(TR_FILES) ; do \
|
||||
($(INSTALL) -m 755 $$i $(prefix)/share/$(PACKAGE)/) || exit 1; \
|
||||
done
|
||||
|
||||
uninstall:
|
||||
if test x$$prefix = x; then \
|
||||
echo Usage is: make -f makefile.gnu uninstall prefix=YOURPREFIX; \
|
||||
exit 1; \
|
||||
fi
|
||||
rm "$(prefix)/bin/$(PACKAGE)"
|
||||
for i in $(TR_FILES) ; do \
|
||||
(rm -f $(prefix)/share/$(PACKAGE)/$$i) || exit 1; \
|
||||
done
|
||||
-rmdir $(prefix)/share/$(PACKAGE)
|
||||
|
||||
linecount:
|
||||
wc -l $(PROGRAM_FILES) $(GUI_GTK_FILES)
|
||||
|
||||
|
||||
# For packaging into a tarball
|
||||
distdir = $(topdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
# Simple, probably inaccurate (it'll likely copy too many files), but effective
|
||||
distdir:
|
||||
-mkdir $(distdir)
|
||||
for f in `find . | grep -v CVS | grep -v ~$$ | grep -v $(distdir)` ; do \
|
||||
if test -d $$f; then \
|
||||
$(mkinstalldirs) "$(distdir)/$$f" ; \
|
||||
else \
|
||||
cp -p "$$f" "$(distdir)/$$f" ; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
dist dist-all: distdir
|
||||
tar chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
rm -rf $(distdir)
|
||||
|
||||
# vim: noexpandtab
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// Node.cs: Used to contain the output tree before display.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using Mono.TypeReflector.Finders;
|
||||
using Mono.TypeReflector.Formatters;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public sealed class Node : ICloneable {
|
||||
|
||||
INodeFormatter formatter;
|
||||
INodeFinder finder;
|
||||
|
||||
NodeInfo nodeInfo;
|
||||
|
||||
public Node (INodeFormatter formatter, INodeFinder finder)
|
||||
{
|
||||
this.formatter = formatter;
|
||||
this.finder = finder;
|
||||
}
|
||||
|
||||
public object Clone ()
|
||||
{
|
||||
return MemberwiseClone();
|
||||
}
|
||||
|
||||
public string Description {
|
||||
get {return formatter.GetDescription(nodeInfo);}
|
||||
}
|
||||
|
||||
public NodeCollection GetChildren ()
|
||||
{
|
||||
NodeCollection children = new NodeCollection ();
|
||||
NodeInfoCollection nic = finder.GetChildren (nodeInfo);
|
||||
// foreach (NodeInfo o in finder.GetChildren (nodeInfo)) {
|
||||
foreach (NodeInfo o in nic) {
|
||||
Node n = (Node) this.Clone ();
|
||||
n.NodeInfo = o;
|
||||
children.Add (n);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
public NodeInfo NodeInfo {
|
||||
get {return nodeInfo;}
|
||||
set {nodeInfo = value;}
|
||||
}
|
||||
}
|
||||
|
||||
public class NodeCollection : CollectionBase {
|
||||
|
||||
internal NodeCollection ()
|
||||
{
|
||||
}
|
||||
|
||||
public Node this [int index] {
|
||||
get {return (Node) InnerList[index];}
|
||||
set {InnerList[index] = value;}
|
||||
}
|
||||
|
||||
public int Add (Node value)
|
||||
{
|
||||
return InnerList.Add (value);
|
||||
}
|
||||
|
||||
public void AddRange (Node[] values)
|
||||
{
|
||||
foreach (Node node in values)
|
||||
Add (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// NodeGrouper.cs: A general way to sub-group nodes.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
namespace Mono.TypeReflector.Finders
|
||||
{
|
||||
public delegate void NodeGrouper (NodeInfoCollection c, NodeInfo root, object extra);
|
||||
|
||||
public class NodeGroup {
|
||||
private string groupName;
|
||||
private NodeGrouper grouper;
|
||||
private object extra;
|
||||
|
||||
public NodeGroup (string name, object extra, NodeGrouper grouper)
|
||||
{
|
||||
this.groupName = name;
|
||||
this.grouper = grouper;
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public NodeGroup (string name, NodeGrouper grouper)
|
||||
: this (name, grouper, null)
|
||||
{
|
||||
}
|
||||
|
||||
public string GroupName {
|
||||
get {return groupName;}
|
||||
}
|
||||
|
||||
public NodeGrouper Grouper {
|
||||
get {return grouper;}
|
||||
}
|
||||
|
||||
public void Invoke (NodeInfoCollection c, NodeInfo root)
|
||||
{
|
||||
grouper (c, root, extra);
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return groupName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
//
|
||||
// NodeInfo.cs:
|
||||
//
|
||||
// A NodeInfo object represents a node in Type tree, such as a Constructor,
|
||||
// Field, or pseudo-collections like GroupingNodeFinder's "Methods:" branch.
|
||||
//
|
||||
// Additionally, it's used to get additional information about the node, such
|
||||
// as invoke methods to get additional information.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002-2003 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class NodeInfo {
|
||||
private NodeInfo parent;
|
||||
private NodeTypes type;
|
||||
private object reflectionObject = null;
|
||||
private object reflectionInstance = null;
|
||||
private object description = null;
|
||||
|
||||
public NodeInfo (NodeInfo parent, NodeTypes type, object reflectionObject,
|
||||
object reflectionInstance, object description)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
this.reflectionObject = reflectionObject;
|
||||
this.reflectionInstance = reflectionInstance;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public NodeInfo (NodeInfo parent, NodeTypes type, object reflectionObject,
|
||||
object reflectionInstance)
|
||||
: this (parent, type, reflectionObject, reflectionInstance, null)
|
||||
{
|
||||
}
|
||||
|
||||
public NodeInfo (NodeInfo parent, NodeTypes type)
|
||||
: this (parent, type, null, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public NodeInfo (NodeInfo parent, object description)
|
||||
: this (parent, NodeTypes.Other, null, null, description)
|
||||
{
|
||||
}
|
||||
|
||||
public NodeInfo (NodeInfo parent, MemberInfo mi)
|
||||
: this (parent, mi, null)
|
||||
{
|
||||
}
|
||||
|
||||
public NodeInfo (NodeInfo parent, MemberInfo mi, object instance)
|
||||
: this (parent, NodeTypes.Other, mi, instance, null)
|
||||
{
|
||||
// set type
|
||||
switch (mi.MemberType) {
|
||||
case MemberTypes.NestedType:
|
||||
case MemberTypes.TypeInfo:
|
||||
this.type = NodeTypes.Type;
|
||||
break;
|
||||
case MemberTypes.Constructor:
|
||||
this.type = NodeTypes.Constructor;
|
||||
break;
|
||||
case MemberTypes.Event:
|
||||
this.type = NodeTypes.Event;
|
||||
break;
|
||||
case MemberTypes.Field:
|
||||
this.type = NodeTypes.Field;
|
||||
break;
|
||||
case MemberTypes.Method:
|
||||
this.type = NodeTypes.Method;
|
||||
break;
|
||||
case MemberTypes.Property:
|
||||
this.type = NodeTypes.Property;
|
||||
break;
|
||||
default:
|
||||
this.type = NodeTypes.Other;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the type of the NodeInfo object.
|
||||
/// </summary>
|
||||
public NodeTypes NodeType {
|
||||
get {return type;}
|
||||
set {type = value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the parent NodeInfo object. This is used to help represent
|
||||
/// the tree.
|
||||
/// </summary>
|
||||
public NodeInfo Parent {
|
||||
get {return parent;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If non-null, this is the underlying System.Reflection object, such as
|
||||
/// System.Reflection.MemberInfo or System.Reflection.ParameterInfo.
|
||||
/// </summary>
|
||||
public object ReflectionObject {
|
||||
get {return reflectionObject;}
|
||||
set {reflectionObject = value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the object instance to pass to System.Reflection methods using
|
||||
/// the ReflectionObject.
|
||||
/// </summary>
|
||||
public object ReflectionInstance {
|
||||
get {return reflectionInstance;}
|
||||
set {reflectionInstance = value;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is an arbitrary description that can be attached to the node.
|
||||
/// This is only useful if ReflectionObject is null or NodeType is a value
|
||||
/// that doesn't match against a "real" System.Reflection type, such as
|
||||
/// NodeTypes.Other.
|
||||
/// </summary>
|
||||
public object Description {
|
||||
get {return description;}
|
||||
set {description = value;}
|
||||
}
|
||||
|
||||
/*
|
||||
public override string ToString ()
|
||||
{
|
||||
Console.WriteLine ("** (NodeInfo (parent {0}) (type {1}) (rObj {2}) (rIns {3}) (description {4}))",
|
||||
parent, type, reflectionObject, reflectionInstance, description);
|
||||
return base.ToString ();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public sealed class NodeInfoCollection : CollectionBase {
|
||||
|
||||
internal NodeInfoCollection ()
|
||||
{
|
||||
}
|
||||
|
||||
public NodeInfo this [int index] {
|
||||
get {return (NodeInfo) InnerList[index];}
|
||||
set {InnerList[index] = value;}
|
||||
}
|
||||
|
||||
public int Add (NodeInfo value)
|
||||
{
|
||||
return InnerList.Add (value);
|
||||
}
|
||||
|
||||
public void AddRange (NodeInfo[] values)
|
||||
{
|
||||
foreach (NodeInfo n in values)
|
||||
Add (n);
|
||||
}
|
||||
|
||||
public void AddRange (NodeInfoCollection values)
|
||||
{
|
||||
foreach (NodeInfo n in values)
|
||||
Add (n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// NodeTypes.cs: The types of nodes that can be displayed.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
/// <summary>
|
||||
/// The types of Nodes that can be displayed.
|
||||
/// </summary>
|
||||
public enum NodeTypes {
|
||||
// Meta-nodes
|
||||
Assembly,
|
||||
Library,
|
||||
Namespace,
|
||||
Module,
|
||||
// Type information
|
||||
CustomAttributeProvider,
|
||||
Type,
|
||||
BaseType,
|
||||
Interface,
|
||||
Field,
|
||||
Constructor,
|
||||
Method,
|
||||
Parameter,
|
||||
Property,
|
||||
Event,
|
||||
// Misc
|
||||
ReturnValue, // needed? could be simulated
|
||||
Alias, // Refer's to a previous node. Description is the prior object
|
||||
Other
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// NodePolicy.cs:
|
||||
//
|
||||
// Default implementation of the INodePolicy interface.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2003 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class Policy : IPolicy {
|
||||
|
||||
private string description, key;
|
||||
|
||||
public string Description {
|
||||
get {return description;}
|
||||
set {description = value;}
|
||||
}
|
||||
|
||||
public string FactoryKey {
|
||||
get {return key;}
|
||||
set {key = value;}
|
||||
}
|
||||
|
||||
public virtual object Clone ()
|
||||
{
|
||||
return MemberwiseClone ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
//
|
||||
// ProgramOptions.cs: Parser for Program Options
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any
|
||||
// person obtaining a copy of this software and associated
|
||||
// documentation files (the "Software"), to deal in the
|
||||
// Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software,
|
||||
// and to permit persons to whom the Software is furnished to
|
||||
// do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice
|
||||
// shall be included in all copies or substantial portions
|
||||
// of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Use a Dictionary object to store options
|
||||
* - Removes O(n) searches that are currently used for option lookup
|
||||
* - OR -
|
||||
* - sort the options and use BinarySearch
|
||||
*
|
||||
* Option Handling:
|
||||
* - Specify two sets of option groups:
|
||||
* - Those that are "combinable"
|
||||
* - Those that aren't
|
||||
*
|
||||
* - "Combining" refers to the ability to specify multiple options "at once",
|
||||
* e.g. `ls -ctr' is a combined form of `ls -c -t -r'.
|
||||
*
|
||||
* - Specify a way to state how many '-'s prefix an option
|
||||
*
|
||||
* - Specify the actual option prefix ('/' or '-' or...)
|
||||
*
|
||||
* - Specify a way to set the delimeter between the option and the argument.
|
||||
*
|
||||
* - Add a `count' field so that options can be specified multiple times
|
||||
*
|
||||
* - Allow options to be specified multiple times, and collect all of the
|
||||
* arguments for the option.
|
||||
*
|
||||
* - These changes to option handling should permit:
|
||||
* - GCC-style options
|
||||
* - e.g. `-dumpspecs' is a valid option (note 1 '-', not 2A)
|
||||
* - e.g. `-DMYSYMBOL' is the option `-D' with the value `MYSYMBOL'
|
||||
* - e.g. `-DFOO -DBAR' makes arguments `FOO' and `BAR' available when
|
||||
* searching for option `D'
|
||||
* - CSC.EXE-style options
|
||||
* - /out:file-name
|
||||
* - /help
|
||||
* - /t:exe or /target:exe (/t is a synonym for /target)
|
||||
* - Multiple level options (forget which program I saw this in...)
|
||||
* - -v is 1 level of verbosity
|
||||
* - -vv is 2 levels of verbosity
|
||||
* - ...
|
||||
*
|
||||
* Sanity Checking
|
||||
* - Should make sure that there aren't any duplicate entries
|
||||
*
|
||||
* Pie-in-the-sky:
|
||||
* - Provide a way to specify how many positions an argument takes up.
|
||||
* - Currently, options with arguments can have 1 argv[] slot (for the
|
||||
* argument) (for non-long-opt options).
|
||||
* - It might be useful to allow arguments to have > 1
|
||||
* - Not aware of any program that would actually make use of this.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class OptionException : Exception {
|
||||
|
||||
public char ShortForm;
|
||||
|
||||
public OptionException (string reason, char shortForm )
|
||||
: base (reason)
|
||||
{
|
||||
this.ShortForm = shortForm;
|
||||
}
|
||||
|
||||
public OptionException (string reason)
|
||||
: base (reason)
|
||||
{
|
||||
}
|
||||
|
||||
public OptionException (string reason, Exception inner)
|
||||
: base (reason, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ProgramOptions {
|
||||
|
||||
private class Option {
|
||||
public char ShortForm = '\0';
|
||||
public string LongForm = null;
|
||||
public string Description = null;
|
||||
public bool Found = false;
|
||||
public bool HasArgument = false;
|
||||
public string ArgumentValue = null;
|
||||
public bool AllowMultiple = false;
|
||||
public string ArgumentDescription = null;
|
||||
|
||||
public Option (char shortForm, string longForm, string description, string argDesc, bool hasArgument)
|
||||
{
|
||||
ShortForm = shortForm;
|
||||
LongForm = longForm;
|
||||
Description = description;
|
||||
HasArgument = hasArgument;
|
||||
ArgumentDescription = argDesc;
|
||||
}
|
||||
|
||||
public Option (char shortForm, string description)
|
||||
{
|
||||
ShortForm = shortForm;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public Option (string longForm, string description)
|
||||
{
|
||||
LongForm = longForm;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
// Option array
|
||||
private ArrayList options = new ArrayList ();
|
||||
|
||||
// string array
|
||||
private ArrayList unmatched = new ArrayList ();
|
||||
|
||||
public IList UnmatchedOptions {
|
||||
get {return unmatched;}
|
||||
}
|
||||
|
||||
public ProgramOptions ()
|
||||
{
|
||||
}
|
||||
|
||||
private void AddOption (Option opt)
|
||||
{
|
||||
options.Add (opt);
|
||||
}
|
||||
|
||||
public void AddHelpOption ()
|
||||
{
|
||||
AddOption (new Option ('h', "help", "Display this help and exit.", null, false));
|
||||
}
|
||||
|
||||
public void AddOption (char shortForm, string description)
|
||||
{
|
||||
AddOption (new Option (shortForm, description));
|
||||
}
|
||||
|
||||
public void AddArgumentOption (char shortForm, string description, string argument)
|
||||
{
|
||||
AddOption (new Option (shortForm, null, description, argument, true));
|
||||
}
|
||||
|
||||
public void AddOption (string longForm, string description)
|
||||
{
|
||||
AddOption (new Option (longForm, description));
|
||||
}
|
||||
|
||||
public void AddArgumentOption (string longForm, string description, string argument)
|
||||
{
|
||||
AddOption (new Option ('\0', longForm, description, argument, true));
|
||||
}
|
||||
|
||||
public void AddOption (char shortForm, string longForm, string description)
|
||||
{
|
||||
AddOption (new Option (shortForm, longForm, description, null, false));
|
||||
}
|
||||
|
||||
public void AddArgumentOption (char shortForm, string longForm, string description, string argument)
|
||||
{
|
||||
AddOption (new Option (shortForm, longForm, description, argument, true));
|
||||
}
|
||||
|
||||
public virtual void ParseOptions (string[] options)
|
||||
{
|
||||
int len = options.Length;
|
||||
bool handle = true;
|
||||
for (int cur = 0; cur != len; ++cur) {
|
||||
string option = options[cur];
|
||||
// necessary?
|
||||
if (option == null || option.Length == 0)
|
||||
continue;
|
||||
if (handle) {
|
||||
if (option.StartsWith ("-")) {
|
||||
// possible option
|
||||
if (option == "--")
|
||||
handle = false;
|
||||
else if (option.StartsWith ("--"))
|
||||
ParseLongOption (options, ref cur);
|
||||
else
|
||||
ParseShortOptions (options, ref cur);
|
||||
}
|
||||
else
|
||||
unmatched.Add (option);
|
||||
}
|
||||
else
|
||||
unmatched.Add (option);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseLongOption (string[] args, ref int currentIndex)
|
||||
{
|
||||
// get rid of "--"
|
||||
string arg = args[currentIndex].Substring (2);
|
||||
bool found = false;
|
||||
foreach (Option o in options) {
|
||||
if (o.LongForm == null)
|
||||
continue;
|
||||
if (!arg.StartsWith(o.LongForm))
|
||||
continue;
|
||||
found = true;
|
||||
o.Found = true;
|
||||
if (o.HasArgument) {
|
||||
try {
|
||||
o.ArgumentValue = arg.Substring (arg.IndexOf('=')+1);
|
||||
} catch (Exception e) {
|
||||
throw new OptionException (
|
||||
"missing argument to option --" + o.LongForm,
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
throw new OptionException (
|
||||
String.Format ("Unrecognized option `{0}'", args[currentIndex]));
|
||||
}
|
||||
|
||||
private void ParseShortOptions (string[] args, ref int currentIndex)
|
||||
{
|
||||
string arg = args[currentIndex].Substring (1);
|
||||
int needsArg = 0;
|
||||
Option forArg = null;
|
||||
for (int i = 0; i != arg.Length; ++i) {
|
||||
bool found = false;
|
||||
foreach (Option o in options) {
|
||||
if (o.ShortForm != arg[i])
|
||||
continue;
|
||||
found = true;
|
||||
o.Found = true;
|
||||
if (o.HasArgument) {
|
||||
++needsArg;
|
||||
forArg = o;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
throw new OptionException (
|
||||
String.Format("Unrecognized option `-{0}'", arg[i]));
|
||||
}
|
||||
|
||||
if (needsArg > 1)
|
||||
throw new OptionException ("too many options requiring arguments specified");
|
||||
else if (needsArg == 1) {
|
||||
if (currentIndex == (args.Length - 1))
|
||||
throw new OptionException ("missing argument to option -" + forArg.ShortForm);
|
||||
++currentIndex;
|
||||
forArg.ArgumentValue = args[currentIndex];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear ()
|
||||
{
|
||||
foreach (Option o in options) {
|
||||
o.Found = false;
|
||||
o.ArgumentValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly string[] OptionFormats =
|
||||
{
|
||||
// 0: no short, no long, no arg
|
||||
"<invalid option format: 0: 0={0},1={1},2={2}>",
|
||||
// 1: short only
|
||||
" -{0}",
|
||||
// 2: long only
|
||||
" --{1}",
|
||||
// 3: long & short
|
||||
" -{0}, --{1}",
|
||||
// 4: no short, no long, arg
|
||||
"<invalid option format: 4: 0={0},1={1},2={2}>",
|
||||
// 5: short w/ arg
|
||||
" -{0} {2}",
|
||||
// 6: long w/ arg
|
||||
" --{1}={2}",
|
||||
// 7: short & long w/ arg
|
||||
" -{0}, --{1}={2}"
|
||||
};
|
||||
|
||||
public virtual string OptionsHelp {
|
||||
get {
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
foreach (Option o in options) {
|
||||
uint f_s = Convert.ToUInt32 (o.ShortForm != '\0');
|
||||
uint f_l = Convert.ToUInt32 (o.LongForm != null);
|
||||
uint f_h = Convert.ToUInt32 (o.HasArgument);
|
||||
uint format = (f_s << 0) | (f_l << 1) | (f_h << 2);
|
||||
string opt = String.Format (OptionFormats[format],
|
||||
o.ShortForm,
|
||||
o.LongForm,
|
||||
o.ArgumentDescription);
|
||||
string fmt = null;
|
||||
if (opt.Length < 30)
|
||||
fmt = "{0,-30}{1}";
|
||||
else
|
||||
fmt = "{0,-30}\n{2,-30}{1}";
|
||||
string d = new TextFormatter (30, 80, 2).Group (o.Description);
|
||||
sb.Append (String.Format (fmt, opt, d, ""));
|
||||
sb.Append ("\n");
|
||||
}
|
||||
return sb.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly string ProgramName = Environment.GetCommandLineArgs()[0];
|
||||
|
||||
public bool FoundOption (char shortForm)
|
||||
{
|
||||
foreach (Option o in options) {
|
||||
if (o.ShortForm != shortForm)
|
||||
continue;
|
||||
return o.Found;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool FoundOption (string longForm)
|
||||
{
|
||||
foreach (Option o in options) {
|
||||
if (o.LongForm != longForm)
|
||||
continue;
|
||||
return o.Found;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public string FoundOptionValue (char shortForm)
|
||||
{
|
||||
foreach (Option o in options) {
|
||||
if (o.ShortForm != shortForm)
|
||||
continue;
|
||||
return o.ArgumentValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public string FoundOptionValue (string longForm)
|
||||
{
|
||||
foreach (Option o in options) {
|
||||
if (o.LongForm != longForm)
|
||||
continue;
|
||||
return o.ArgumentValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool FoundHelp {
|
||||
get {return FoundOption ('h');}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
Overview
|
||||
========
|
||||
``type-reflector'' is a program similar in spirit to the .NET ``TypeFinder''
|
||||
SDK Sample. As is often the case with Unix-style programs, it has more
|
||||
program options and more flexibility.
|
||||
|
||||
It allows a regular expression (as understood by
|
||||
System.Text.RegularExpressions) to be used for finding types.
|
||||
|
||||
It allows a specific list of assemblies to be searched to be specified,
|
||||
narrowing down the list of assemblies searched for a matching type.
|
||||
|
||||
It also allows the types to be viewed according to three different policies.
|
||||
The "finder" policy dictates how members are found. There are currently two
|
||||
such policies:
|
||||
|
||||
explicit - Searches for members by name
|
||||
reflection - uses System.Reflection for member lookup
|
||||
|
||||
The finder policies often display different results, as "explicit" has had
|
||||
more work done on it, and "reflection" is dependant upon System.Reflection,
|
||||
which may or may not be complete, depending on the platform.
|
||||
|
||||
The second policy is the "formatter" policy, which dictates how a member is
|
||||
displayed. There are currently three such policies:
|
||||
|
||||
default - typically the result of .ToString() on the member reflection object
|
||||
csharp - attempts to display the member as if it were from C# source code.
|
||||
vb - attempts to display the member as if it were from VB.NET source code.
|
||||
|
||||
The third policy is the "displayer" policy, which is how the members are
|
||||
displayed to the user. This is described below.
|
||||
|
||||
Type Reflector shows (virtually) everything about a type that is available
|
||||
through the System.Reflection facility. Everything from the actual Attributes
|
||||
specified for a member, to custom attributes, the reflected type, GUID, where
|
||||
it was declared... This constitutes a great deal of information that isn't
|
||||
normally present without writing test programs to view the available
|
||||
information.
|
||||
|
||||
I prefer to think of it as the "Frankenstein" combination of ``TypeFinder''
|
||||
and a debugger. It doesn't just find types. It doesn't just display the
|
||||
members of those types. It will also (when able to) display the result of
|
||||
invoking methods on a type. The method must fulfill some limitations:
|
||||
|
||||
- There must be a valid object instance. For arbitrary types, this
|
||||
effectively means you can only get the result of invoking static
|
||||
methods/properties, but this can be useful when looking at Reflection
|
||||
objects.
|
||||
|
||||
- The invoked methods must accept 0 arguments.
|
||||
|
||||
Thus, for the C# class definition:
|
||||
|
||||
public class Test {
|
||||
public static int Foo {get {return 42;}}
|
||||
}
|
||||
|
||||
we can use type-reflector to determine the value returned by Test.Foo.
|
||||
|
||||
This is also useful for determining the values of class constants/readonly
|
||||
fields and properties, such as Enumeration values.
|
||||
|
||||
There is also support to invoke (and display the return value) of class
|
||||
methods that accept no arguments. However, due to "problems" [1] this is not
|
||||
enabled by default; pass the -n argument to enable.
|
||||
|
||||
[1] Some of the mono tools do actual work in their static methods that accept
|
||||
no arguments. For example, using Type Reflector on itself to display the
|
||||
member Mono.TypeReflector.TypeReflectorApp.PrintVersion would display the
|
||||
version information to the console. Other apps request user input when
|
||||
invoked, halting all display until the user presses a key. Displaying all
|
||||
libraries would cause core dumps as gtk_init could be called before gdk_init
|
||||
(as they were P/Invoked from the Gtk# assemblies) during this process.
|
||||
|
||||
I thought this would be cool, but unless you're careful, things can get weird.
|
||||
|
||||
|
||||
Displayers
|
||||
==========
|
||||
Type Reflector has three displayers, the "console" displayer, which sends
|
||||
output to the console, and two GUI front-ends, the availability of which
|
||||
depends upon which platform you're on. The front-end is specified with the
|
||||
--displayer program argument.
|
||||
|
||||
All front ends have their own makefile target. For now, the "gui" target
|
||||
attempts to compiles in support for all displayers (Gtk#,
|
||||
System.Windows.Forms, and Console output).
|
||||
|
||||
The ``--displayer'' argument is no longer required in order to use GUI output.
|
||||
The displayer to be used is specified in the .config file. (In the
|
||||
<appSettings/> element, <add/> sub-element with attribute
|
||||
key="displayer-order". XPath:
|
||||
/configuration/appSettings/add[@key='displayer-order'].)
|
||||
|
||||
The current order is Gtk#, followed by System.Windows.Forms, followed by
|
||||
console output. If you don't like this order, change the entry so your
|
||||
preferred displayer is first.
|
||||
|
||||
Gtk#
|
||||
----
|
||||
The Gtk# front-end uses (duh!) Gtk#. And Glade#. And any other Gnome
|
||||
technology I feel like throwing in at any given point in time. Ahem.
|
||||
To compile it, run:
|
||||
|
||||
make -f makefile.gnu gtk
|
||||
|
||||
To run it, pass ``--displayer=gtk'' on the command line:
|
||||
|
||||
type-reflector.exe --displayer=gtk --use-default-assemblies .
|
||||
|
||||
This will display all types in all assemblies; it takes ~25 seconds to finish
|
||||
loading (PIII 700 MHz notebook).
|
||||
|
||||
|
||||
System.Windows.Forms
|
||||
--------------------
|
||||
The Windows.Forms front-end is the "swf" displayer. To compile, run:
|
||||
|
||||
make swf
|
||||
|
||||
This must be done on a Windows box, as (at present) the Mono
|
||||
System.Windows.Forms implementation will not permit compilation.
|
||||
|
||||
To run it, pass ``--displayer=gtk'' on the command line:
|
||||
|
||||
type-reflector.exe --displayer=swf -S --use-default-assemblies .
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
A better way of displaying Custom Attributes needs to be used, so that the
|
||||
actual properties/field values of the custom attribute is displayed.
|
||||
|
||||
A better way of specifying Assemblies on the command line. It would be useful
|
||||
to say ``-a foo.dll -a bar.dll -a baz.dll'' instead of
|
||||
``-a foo.dll:bar.dll:baz.dll''. The framework for such parsing is described
|
||||
in ``ProgramOptions.cs''.
|
||||
|
||||
Any of the TODO items listed in ``ProgramOptions.cs''.
|
||||
|
||||
For Gtk#:
|
||||
- Make View->Formatter be synchronized with the Formatter sidebar. Requires
|
||||
some way of getting information about the selected item. (There doesn't
|
||||
appear to be a simple way to find the Menu Item Label text from a
|
||||
RadioMenuItem. :-(
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// TestTypes.cs: Sample types for testing type-reflector
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace Testing
|
||||
{
|
||||
public interface IFoo {}
|
||||
public interface IBar {}
|
||||
public interface IBaz : IFoo, IBar {}
|
||||
|
||||
public delegate void FooEventHandler ();
|
||||
public delegate void FooEventHandler2 (int n);
|
||||
public delegate void FooEventHandler3 (int n, long l);
|
||||
|
||||
public class MyAttribute : Attribute {
|
||||
private string _f;
|
||||
public MyAttribute (string f) {
|
||||
_f = f;
|
||||
}
|
||||
public string F {
|
||||
get {return _f;}
|
||||
}
|
||||
}
|
||||
|
||||
public class AnotherAttribute : Attribute {
|
||||
private int n;
|
||||
private string s;
|
||||
|
||||
public AnotherAttribute (int _n) {
|
||||
n = _n;
|
||||
}
|
||||
|
||||
public AnotherAttribute (string _s) {
|
||||
s = _s;
|
||||
}
|
||||
|
||||
public int N {
|
||||
get {return n;}
|
||||
}
|
||||
|
||||
public string S {
|
||||
get {return s;}
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeAttributes : Attribute {
|
||||
public TypeAttributes () {}
|
||||
|
||||
public char Char = 'a';
|
||||
public decimal Decimal = 42m;
|
||||
public double Double = 17.0;
|
||||
public int Int = 24;
|
||||
public long Long = 57L;
|
||||
public string String = "hello, world!";
|
||||
public float Float = 34.0f;
|
||||
public uint UInt = 10;
|
||||
public ulong ULong = 20;
|
||||
}
|
||||
|
||||
// [CLSCompliant(false)]
|
||||
[MyAttribute ("Hello, world!")]
|
||||
[Serializable]
|
||||
public class TestClass : IFoo, IBar, IBaz {
|
||||
|
||||
[TypeAttributes]
|
||||
public sealed class NestedClass {
|
||||
public static int Foo = 10;
|
||||
public const int Bar = 20;
|
||||
public int Baz {
|
||||
get {return 30;}
|
||||
}
|
||||
}
|
||||
|
||||
private int PrivateField;
|
||||
protected float ProtectedField;
|
||||
|
||||
[MyAttribute("foo!")]
|
||||
public double PublicField;
|
||||
|
||||
internal long InternalField;
|
||||
|
||||
public TestClass (short s) {PublicField = 3.14;}
|
||||
protected TestClass (long l) {ProtectedField = 2.71F;}
|
||||
private TestClass (int i) {PrivateField = 13;}
|
||||
internal TestClass (float f) {InternalField = 64;}
|
||||
|
||||
// indexer
|
||||
public int this [int index] {
|
||||
get {return 42;}
|
||||
set {/* ignore */}
|
||||
}
|
||||
|
||||
[MyAttribute ("Public Property")]
|
||||
public int PublicGetSet {
|
||||
get {return 0;}
|
||||
set {PublicField = value;}
|
||||
}
|
||||
|
||||
public static int StaticGetter {
|
||||
get {return 42;}
|
||||
}
|
||||
|
||||
public static int StaticSetter {
|
||||
set {/* ignore */}
|
||||
}
|
||||
|
||||
protected short ProtectedGetter {
|
||||
get {return -1;}
|
||||
}
|
||||
|
||||
private char PrivateSetter {
|
||||
set {PrivateField = value;}
|
||||
}
|
||||
|
||||
internal float InternalProperty {
|
||||
get {return ProtectedField;}
|
||||
set {ProtectedField = value;}
|
||||
}
|
||||
|
||||
public event FooEventHandler PubFoo;
|
||||
protected event FooEventHandler ProFoo;
|
||||
private event FooEventHandler PrivFoo;
|
||||
internal event FooEventHandler IntFoo;
|
||||
|
||||
public static int msFoo = 42;
|
||||
public const int msBar = 64;
|
||||
|
||||
[MyAttribute ("Some Name")]
|
||||
[return: AnotherAttribute ("Return Attribute")]
|
||||
public short PublicMethod ([MyAttribute("The parameter")] [AnotherAttribute(42)] short s)
|
||||
{
|
||||
PubFoo (); return s;
|
||||
}
|
||||
|
||||
public static TestEnum PublicMethod2 ()
|
||||
{
|
||||
return TestEnum.Foo;
|
||||
}
|
||||
|
||||
public void ParamsMethod (params object[] objs)
|
||||
{
|
||||
}
|
||||
|
||||
protected internal void ProtectedInternalFunction ()
|
||||
{
|
||||
}
|
||||
|
||||
private int PrivateMethod (int i) {PrivFoo (); return i;}
|
||||
protected long ProtectedMethod (long l) {ProFoo (); return l;}
|
||||
internal float InternalMethod (float f) {IntFoo (); return f;}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum TestEnum {
|
||||
Foo,
|
||||
Bar,
|
||||
Baz,
|
||||
Qux,
|
||||
Quux
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
//
|
||||
// TextFormatter.cs: Formats text for display output
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any
|
||||
// person obtaining a copy of this software and associated
|
||||
// documentation files (the "Software"), to deal in the
|
||||
// Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software,
|
||||
// and to permit persons to whom the Software is furnished to
|
||||
// do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice
|
||||
// shall be included in all copies or substantial portions
|
||||
// of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
internal class TextFormatter {
|
||||
private int leftMargin = 0;
|
||||
private int rightMargin = 80;
|
||||
private int subsequentIndent = 0;
|
||||
|
||||
public int LeftMargin {
|
||||
get {return leftMargin;}
|
||||
set {leftMargin = value;}
|
||||
}
|
||||
|
||||
public int RightMargin {
|
||||
get {return rightMargin;}
|
||||
set {rightMargin = value;}
|
||||
}
|
||||
|
||||
public int SubsequentIndent {
|
||||
get {return subsequentIndent;}
|
||||
set {subsequentIndent = value;}
|
||||
}
|
||||
|
||||
public TextFormatter ()
|
||||
: this (0)
|
||||
{
|
||||
}
|
||||
|
||||
public TextFormatter (int leftMargin)
|
||||
: this (leftMargin, 80)
|
||||
{
|
||||
}
|
||||
|
||||
public TextFormatter (int leftMargin, int rightMargin)
|
||||
: this (leftMargin, rightMargin, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public TextFormatter (int leftMargin, int rightMargin, int subsequentIndent)
|
||||
{
|
||||
this.leftMargin = leftMargin;
|
||||
this.rightMargin = rightMargin;
|
||||
this.subsequentIndent = subsequentIndent;
|
||||
}
|
||||
|
||||
private void WrapText (string text, int width, IList lines)
|
||||
{
|
||||
if (text.Length <= width) {
|
||||
lines.Add (text);
|
||||
return;
|
||||
}
|
||||
|
||||
while (text.Length > width) {
|
||||
int b = width;
|
||||
if (!Char.IsWhiteSpace(text[b])) {
|
||||
b = text.LastIndexOf (' ', b);
|
||||
if (b == -1)
|
||||
// couldn't find an earlier word break
|
||||
b = width;
|
||||
}
|
||||
lines.Add (text.Substring (0, b));
|
||||
text = text.Substring (b).Trim();
|
||||
}
|
||||
lines.Add (text);
|
||||
}
|
||||
|
||||
private ICollection WrapText (string text, int width)
|
||||
{
|
||||
ArrayList lines = new ArrayList ();
|
||||
string[] paragraphs = text.Split(new char[] {'\n'});
|
||||
foreach (string p in paragraphs)
|
||||
WrapText (p, width, lines);
|
||||
return lines;
|
||||
}
|
||||
|
||||
public string Group (string text)
|
||||
{
|
||||
// should be "- followingIndent", but need an extra space for the '\n'.
|
||||
int width = (RightMargin - LeftMargin) - (SubsequentIndent+1);
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
string format1 = "{1}";
|
||||
string formatN = "{0,-" + (LeftMargin + SubsequentIndent) + "}{1}";
|
||||
ICollection c = WrapText (text, width);
|
||||
int last = c.Count;
|
||||
string format = format1;
|
||||
foreach (string s in c) {
|
||||
string line = String.Format (format, "", s);
|
||||
sb.Append (line);
|
||||
if (--last != 0) {
|
||||
format = formatN;
|
||||
sb.Append ("\n");
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static int MaxDepth (string[][] args)
|
||||
{
|
||||
int max = 0;
|
||||
foreach (string[] arg in args) {
|
||||
if (arg.Length > max)
|
||||
max = arg.Length;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static string Format (string format, params string[][] args)
|
||||
{
|
||||
int count = MaxDepth (args);
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
for (int i = 0; i != count; ++i) {
|
||||
ArrayList row = new ArrayList ();
|
||||
foreach (string[] arg in args) {
|
||||
if (arg.Length > i)
|
||||
row.Add (arg[i]);
|
||||
else
|
||||
row.Add ("");
|
||||
}
|
||||
sb.Append (string.Format (format, row.ToArray()));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
//
|
||||
// TypeFactory.cs: Generic factory implementation
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class TypeFactoryEntry
|
||||
{
|
||||
private string key, desc;
|
||||
private Type type;
|
||||
|
||||
public TypeFactoryEntry (string key, string description, Type type)
|
||||
{
|
||||
this.key = key;
|
||||
this.desc = description;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public string Key {
|
||||
get {return key;}
|
||||
}
|
||||
|
||||
public string Description {
|
||||
get {return desc;}
|
||||
}
|
||||
|
||||
public Type Type {
|
||||
get {return type;}
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeFactory : IDictionary
|
||||
{
|
||||
private static BooleanSwitch info = new BooleanSwitch (
|
||||
"type-factory",
|
||||
"Information about creating types.");
|
||||
|
||||
// type: IDictionary<string, TypeFactoryEntry>
|
||||
private IDictionary entries = new Hashtable ();
|
||||
|
||||
//
|
||||
// ICollection interface
|
||||
//
|
||||
public int Count {
|
||||
get {return entries.Count;}
|
||||
}
|
||||
|
||||
public bool IsSynchronized {
|
||||
get {return entries.IsSynchronized;}
|
||||
}
|
||||
|
||||
public object SyncRoot {
|
||||
get {return entries.SyncRoot;}
|
||||
}
|
||||
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
entries.CopyTo (array, index);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return entries.GetEnumerator ();
|
||||
}
|
||||
|
||||
//
|
||||
// IDictionary interface
|
||||
//
|
||||
|
||||
public bool IsFixedSize {
|
||||
get {return false;}
|
||||
}
|
||||
|
||||
public bool IsReadOnly {
|
||||
get {return false;}
|
||||
}
|
||||
|
||||
public object this [object key] {
|
||||
get {return entries[key];}
|
||||
set {entries[key] = value;}
|
||||
}
|
||||
|
||||
public ICollection Keys {
|
||||
get {return entries.Keys;}
|
||||
}
|
||||
|
||||
public ICollection Values {
|
||||
get {return entries.Values;}
|
||||
}
|
||||
|
||||
void IDictionary.Add (object key, object value)
|
||||
{
|
||||
Add (key, (TypeFactoryEntry) value);
|
||||
}
|
||||
|
||||
void IDictionary.Clear ()
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
public bool Contains (object key)
|
||||
{
|
||||
return entries.Contains (key);
|
||||
}
|
||||
|
||||
public IDictionaryEnumerator GetEnumerator ()
|
||||
{
|
||||
return entries.GetEnumerator ();
|
||||
}
|
||||
|
||||
public void Remove (object key)
|
||||
{
|
||||
entries.Remove (key);
|
||||
}
|
||||
|
||||
//
|
||||
// New methods
|
||||
//
|
||||
|
||||
public void Add (object key, TypeFactoryEntry value)
|
||||
{
|
||||
entries.Add (key, value);
|
||||
}
|
||||
|
||||
public void Add (TypeFactoryEntry entry)
|
||||
{
|
||||
Add (entry.Key, entry);
|
||||
}
|
||||
|
||||
private object CreateInstance (Type type)
|
||||
{
|
||||
return Activator.CreateInstance (type);
|
||||
}
|
||||
|
||||
public object Create (object key)
|
||||
{
|
||||
TypeFactoryEntry entry = null;
|
||||
try {
|
||||
entry = (TypeFactoryEntry) entries[key];
|
||||
object o = CreateInstance (entry.Type);
|
||||
IPolicy policy = o as IPolicy;
|
||||
if (policy != null) {
|
||||
policy.FactoryKey = entry.Key;
|
||||
policy.Description = entry.Description;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
catch (Exception e) {
|
||||
Trace.WriteLineIf (info.Enabled, string.Format (
|
||||
"Exception creating ({0}, {1}): {2})",
|
||||
key, entry == null ? null : entry.Type, e.ToString()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
//
|
||||
// TypeLoader.cs: Loads types from a list of Assemblies
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class TypeLoader {
|
||||
|
||||
private static TraceSwitch info =
|
||||
new TraceSwitch ("type-loader", "TypeLoader messages");
|
||||
|
||||
// String collection
|
||||
private ICollection assemblies = null;
|
||||
private ICollection references = null;
|
||||
|
||||
private bool matchFullName = true;
|
||||
private bool matchName = false;
|
||||
private bool matchBase = false;
|
||||
private bool matchMethodReturnType = false;
|
||||
private bool matchNamespace = false;
|
||||
|
||||
public bool MatchFullName {
|
||||
get {return matchFullName;}
|
||||
set {matchFullName = value;}
|
||||
}
|
||||
|
||||
public bool MatchClassName {
|
||||
get {return matchName;}
|
||||
set {matchName = value;}
|
||||
}
|
||||
|
||||
public bool MatchBase {
|
||||
get {return matchBase;}
|
||||
set {matchBase = value;}
|
||||
}
|
||||
|
||||
public bool MatchMethodReturnType {
|
||||
get {return matchMethodReturnType;}
|
||||
set {matchMethodReturnType = value;}
|
||||
}
|
||||
|
||||
public bool MatchNamespace {
|
||||
get {return matchNamespace;}
|
||||
set {matchNamespace = value;}
|
||||
}
|
||||
|
||||
public TypeLoader ()
|
||||
{
|
||||
}
|
||||
|
||||
public TypeLoader (ICollection assemblies, ICollection references)
|
||||
{
|
||||
Assemblies = assemblies;
|
||||
References = references;
|
||||
}
|
||||
|
||||
public ICollection Assemblies {
|
||||
get {return assemblies;}
|
||||
set {assemblies = GetAssemblies (value);}
|
||||
}
|
||||
|
||||
public ICollection References {
|
||||
get {return references;}
|
||||
set {references = GetPartialAssemblies (value);}
|
||||
}
|
||||
|
||||
private ICollection GetAssemblies (ICollection assemblies)
|
||||
{
|
||||
// Assemblies may contain directories; if it's a directory, load all
|
||||
// assemblies in the directory.
|
||||
IList realAssemblies = new ArrayList ();
|
||||
foreach (string a in assemblies) {
|
||||
DirectoryInfo di = new DirectoryInfo (a);
|
||||
// TODO: should the assembly search on directories be recursive?
|
||||
if (di.Exists) {
|
||||
foreach (FileInfo fi in di.GetFiles ("*.dll"))
|
||||
AddAssembly (realAssemblies, Assembly.LoadFrom (fi.FullName));
|
||||
foreach (FileInfo fi in di.GetFiles ("*.exe"))
|
||||
AddAssembly (realAssemblies, Assembly.LoadFrom (fi.FullName));
|
||||
}
|
||||
else
|
||||
AddAssembly (realAssemblies, Assembly.LoadFrom (a));
|
||||
}
|
||||
|
||||
return realAssemblies;
|
||||
}
|
||||
|
||||
private void AddAssembly (IList list, Assembly a)
|
||||
{
|
||||
Trace.WriteLineIf (info.TraceInfo, "Adding Assembly: " + a);
|
||||
if (a != null)
|
||||
list.Add (a);
|
||||
}
|
||||
|
||||
private ICollection GetPartialAssemblies (ICollection partialNames)
|
||||
{
|
||||
IList realAssemblies = new ArrayList ();
|
||||
|
||||
AssemblyName an = new AssemblyName ();
|
||||
// an.Version = new Version (-1, -1, -1, -1);
|
||||
|
||||
foreach (string a in partialNames) {
|
||||
an.Name = a;
|
||||
AddAssembly (realAssemblies, Assembly.LoadWithPartialName (a));
|
||||
}
|
||||
return realAssemblies;
|
||||
}
|
||||
|
||||
public ICollection LoadTypes (IList match)
|
||||
{
|
||||
if (assemblies == null)
|
||||
throw new ArgumentNullException ("Assemblies");
|
||||
if (match == null || match.Count == 0)
|
||||
throw new ArgumentNullException ("match");
|
||||
|
||||
StringBuilder regex = new StringBuilder ();
|
||||
regex.Append (match[0]);
|
||||
for (int i = 1; i < match.Count; ++i)
|
||||
regex.AppendFormat ("|{0}", match[i]);
|
||||
|
||||
Trace.WriteLineIf (info.TraceInfo,
|
||||
string.Format ("using regex: '{0}'", regex.ToString()));
|
||||
|
||||
Regex re = new Regex (regex.ToString());
|
||||
|
||||
IList found = new ArrayList ();
|
||||
|
||||
foreach (Assembly a in assemblies) {
|
||||
LoadMatchingTypesFrom (a, regex.ToString(), re, found);
|
||||
}
|
||||
|
||||
foreach (Assembly a in references) {
|
||||
LoadMatchingTypesFrom (a, regex.ToString(), re, found);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private void LoadMatchingTypesFrom (Assembly where, string regex, Regex re, IList types)
|
||||
{
|
||||
try {
|
||||
Type[] _types = where.GetTypes();
|
||||
foreach (Type t in _types) {
|
||||
if (Matches (re, t))
|
||||
types.Add (t);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Trace.WriteLineIf (info.TraceError, String.Format (
|
||||
"Unable to load type regex `{0}' from `{1}'.",
|
||||
regex, where));
|
||||
Trace.WriteLineIf (info.TraceError, e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private bool Matches (Regex r, Type t)
|
||||
{
|
||||
bool f, c, b, rt, n;
|
||||
f = c = b = rt = n = false;
|
||||
if (MatchFullName)
|
||||
f = r.Match(t.FullName).Success;
|
||||
else if (MatchClassName)
|
||||
c = r.Match(t.Name).Success;
|
||||
else if (MatchNamespace)
|
||||
n = r.Match(t.Namespace).Success;
|
||||
if (MatchBase) {
|
||||
b = (!MatchFullName ? false : r.Match (t.BaseType.FullName).Success) ||
|
||||
(!MatchClassName ? false : r.Match (t.BaseType.Name).Success) ||
|
||||
(!MatchNamespace ? false : r.Match (t.BaseType.Namespace).Success);
|
||||
}
|
||||
// TODO: MatchMethodReturnType
|
||||
Trace.WriteLineIf (info.TraceVerbose, String.Format("TypeLoader.Matches: c={0}, b={1}, rt={2}, n={3}", c, b, rt, n));
|
||||
return f || c || b || rt || n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: noexpandtab
|
|
@ -0,0 +1,316 @@
|
|||
//
|
||||
// TypeReflectorApp.cs:
|
||||
// Finds types and sends them to a displayer.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
// #define TRACE
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Mono.TypeReflector.Displayers;
|
||||
using Mono.TypeReflector.Finders;
|
||||
using Mono.TypeReflector.Formatters;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class TypeReflectorApp
|
||||
{
|
||||
private static BooleanSwitch console = new BooleanSwitch ("console",
|
||||
"console-specific and command-line handling output");
|
||||
|
||||
private static void TraceArray (string message, IEnumerable contents)
|
||||
{
|
||||
Trace.WriteLineIf (console.Enabled, message);
|
||||
foreach (object o in contents) {
|
||||
Trace.WriteLineIf (console.Enabled, " " + o);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Version {
|
||||
get {return "0.8.2003-09-28";}
|
||||
}
|
||||
|
||||
public static void PrintVersion ()
|
||||
{
|
||||
Console.WriteLine ("type-reflector {0}", Version);
|
||||
Console.WriteLine ("Written by Jonathan Pryor.");
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine ("Copyright (C) 2002-2003 Jonathan Pryor.");
|
||||
}
|
||||
|
||||
private static void InitFactories ()
|
||||
{
|
||||
InitFactory ("displayers", Factories.Displayer);
|
||||
InitFactory ("finders", Factories.Finder);
|
||||
InitFactory ("formatters", Factories.Formatter);
|
||||
}
|
||||
|
||||
private static void InitFactory (string section, TypeFactory factory)
|
||||
{
|
||||
try {
|
||||
IDictionary d = (IDictionary) ConfigurationSettings.GetConfig (section);
|
||||
foreach (DictionaryEntry de in d) {
|
||||
try {
|
||||
string[] keys = de.Key.ToString().Split (':');
|
||||
string key = keys[0];
|
||||
string desc = keys.Length > 1 ? keys[1] : key;
|
||||
factory.Add (
|
||||
new TypeFactoryEntry (
|
||||
key,
|
||||
desc,
|
||||
Type.GetType (de.Value.ToString(), true)));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Trace.WriteLineIf (console.Enabled,
|
||||
string.Format ("Error adding {0} ({1}): {2}",
|
||||
de.Key, de.Value, e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Trace.WriteLineIf (console.Enabled,
|
||||
string.Format ("Unable to open section: {0}", section));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Main (string[] args)
|
||||
{
|
||||
try {
|
||||
Execute (args);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Console.WriteLine ("Internal Error: Unhandled Exception: {0}", e.ToString());
|
||||
}
|
||||
finally {
|
||||
Trace.Flush ();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Execute (string[] args)
|
||||
{
|
||||
InitFactories ();
|
||||
|
||||
TypeReflectorOptions options = new TypeReflectorOptions ();
|
||||
|
||||
bool quit = false;
|
||||
|
||||
try {
|
||||
options.ParseOptions (args);
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine (e.Message);
|
||||
Console.WriteLine ("See `{0} --help' for more information", ProgramOptions.ProgramName);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (DictionaryEntry de in Factories.Displayer) {
|
||||
Trace.WriteLine (
|
||||
string.Format("registered displayer: {0}={1}", de.Key,
|
||||
((TypeFactoryEntry)de.Value).Type));
|
||||
}
|
||||
|
||||
if (options.FoundHelp) {
|
||||
Console.WriteLine (options.OptionsHelp);
|
||||
quit = true;
|
||||
}
|
||||
|
||||
if (options.DefaultAssemblies) {
|
||||
Console.WriteLine ("The default search assemblies are:");
|
||||
foreach (string s in TypeReflectorOptions.GetDefaultAssemblies ()) {
|
||||
Console.WriteLine (" {0}", s);
|
||||
}
|
||||
quit = true;
|
||||
}
|
||||
|
||||
if (options.Version) {
|
||||
PrintVersion ();
|
||||
quit = true;
|
||||
}
|
||||
|
||||
if (quit)
|
||||
return;
|
||||
|
||||
TraceArray ("Explicit Assemblies: ", options.Assemblies);
|
||||
TraceArray ("Referenced Assemblies: ", options.References);
|
||||
TraceArray ("Search for Types: ", options.Types);
|
||||
|
||||
TypeLoader loader = CreateLoader (options);
|
||||
|
||||
TraceArray ("Actual Search Assemblies: ", loader.Assemblies);
|
||||
TraceArray ("Actual Search Assemblies: ", loader.References);
|
||||
|
||||
ITypeDisplayer displayer = CreateDisplayer (options);
|
||||
if (displayer == null) {
|
||||
Console.WriteLine ("Error: invalid displayer: " + options.Displayer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loader.Assemblies.Count == 0 && loader.References.Count == 0 &&
|
||||
displayer.AssembliesRequired) {
|
||||
Console.WriteLine ("Error: no assemblies specified.");
|
||||
Console.WriteLine ("See `{0} --help' for more information",
|
||||
ProgramOptions.ProgramName);
|
||||
return;
|
||||
}
|
||||
|
||||
INodeFormatter formatter = CreateFormatter (options);
|
||||
if (formatter == null) {
|
||||
Console.WriteLine ("Error: invalid formatter: " + options.Formatter);
|
||||
return;
|
||||
}
|
||||
|
||||
INodeFinder finder = CreateFinder (options);
|
||||
if (finder == null) {
|
||||
Console.WriteLine ("Error: invalid finder: " + options.Finder);
|
||||
return;
|
||||
}
|
||||
|
||||
displayer.Finder = finder;
|
||||
displayer.Formatter = formatter;
|
||||
displayer.Options = options;
|
||||
|
||||
displayer.InitializeInterface ();
|
||||
|
||||
IList types = options.Types;
|
||||
if (types.Count == 0)
|
||||
types = new string[]{"."};
|
||||
|
||||
// Find the requested types and display them.
|
||||
if (loader.Assemblies.Count != 0 || loader.References.Count != 0)
|
||||
FindTypes (displayer, loader, types);
|
||||
|
||||
displayer.Run ();
|
||||
}
|
||||
|
||||
public static void FindTypes (ITypeDisplayer displayer, TypeLoader loader, IList types)
|
||||
{
|
||||
try {
|
||||
ICollection typesFound = loader.LoadTypes (types);
|
||||
Trace.WriteLine (
|
||||
string.Format ("Types Found: {0}", typesFound.Count.ToString()));
|
||||
if (typesFound.Count > 0) {
|
||||
int curType = 1;
|
||||
foreach (Type type in typesFound) {
|
||||
displayer.AddType (type, curType++, typesFound.Count);
|
||||
}
|
||||
}
|
||||
else
|
||||
displayer.ShowError ("Unable to find types.");
|
||||
} catch (Exception e) {
|
||||
displayer.ShowError (string.Format ("Unable to display type: {0}.",
|
||||
e.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeLoader CreateLoader (TypeReflectorOptions options)
|
||||
{
|
||||
TypeLoader loader = new TypeLoader (options.Assemblies, options.References);
|
||||
loader.MatchBase = options.MatchBase;
|
||||
loader.MatchFullName = options.MatchFullName;
|
||||
loader.MatchClassName = options.MatchClassName;
|
||||
loader.MatchNamespace = options.MatchNamespace;
|
||||
loader.MatchMethodReturnType = options.MatchReturnType;
|
||||
return loader;
|
||||
}
|
||||
|
||||
public static ITypeDisplayer CreateDisplayer (TypeReflectorOptions options)
|
||||
{
|
||||
ITypeDisplayer d = null;
|
||||
if (options.Displayer != string.Empty)
|
||||
d = Factories.Displayer.Create (options.Displayer);
|
||||
else
|
||||
d = CreateDefaultDisplayer ();
|
||||
|
||||
if (d != null) {
|
||||
d.MaxDepth = options.MaxDepth;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
private static ITypeDisplayer CreateDefaultDisplayer ()
|
||||
{
|
||||
try {
|
||||
// Get the correct order to load displayers...
|
||||
string order = ConfigurationSettings.AppSettings["displayer-order"];
|
||||
foreach (string d in order.Split (' ')) {
|
||||
ITypeDisplayer displayer = Factories.Displayer.Create (d);
|
||||
if (displayer != null)
|
||||
return displayer;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static INodeFinder CreateFinder (TypeReflectorOptions options)
|
||||
{
|
||||
return CreateFinder (options.Finder, options);
|
||||
}
|
||||
|
||||
public static INodeFinder CreateFinder (string finder, TypeReflectorOptions options)
|
||||
{
|
||||
INodeFinder f = Factories.Finder.Create (finder);
|
||||
|
||||
uint cur = (uint) f.BindingFlags;
|
||||
|
||||
SetFlag (ref cur, options.FlattenHierarchy, (uint) BindingFlags.FlattenHierarchy);
|
||||
SetFlag (ref cur, options.ShowNonPublic, (uint) BindingFlags.NonPublic);
|
||||
SetFlag (ref cur, options.ShowInheritedMembers, (uint) BindingFlags.FlattenHierarchy);
|
||||
|
||||
f.BindingFlags = (BindingFlags) cur;
|
||||
|
||||
cur = (uint) f.FindMembers;
|
||||
SetFlag (ref cur, options.ShowBase, (uint) FindMemberTypes.Base);
|
||||
SetFlag (ref cur, options.ShowConstructors, (uint) FindMemberTypes.Constructors);
|
||||
SetFlag (ref cur, options.ShowEvents, (uint) FindMemberTypes.Events);
|
||||
SetFlag (ref cur, options.ShowFields, (uint) FindMemberTypes.Fields);
|
||||
SetFlag (ref cur, options.ShowInterfaces, (uint) FindMemberTypes.Interfaces);
|
||||
SetFlag (ref cur, options.ShowMethods, (uint) FindMemberTypes.Methods);
|
||||
SetFlag (ref cur, options.ShowProperties, (uint) FindMemberTypes.Properties);
|
||||
SetFlag (ref cur, options.ShowTypeProperties, (uint) FindMemberTypes.TypeProperties);
|
||||
SetFlag (ref cur, options.ShowMonoBroken, (uint) FindMemberTypes.MonoBroken);
|
||||
SetFlag (ref cur, options.VerboseOutput, (uint) FindMemberTypes.VerboseOutput);
|
||||
f.FindMembers = (FindMemberTypes) cur;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
private static void SetFlag (ref uint cur, bool set, uint add)
|
||||
{
|
||||
if (set)
|
||||
cur |= add;
|
||||
else
|
||||
cur &= ~add;
|
||||
}
|
||||
|
||||
public static INodeFormatter CreateFormatter (TypeReflectorOptions options)
|
||||
{
|
||||
return CreateFormatter (options.Formatter, options);
|
||||
}
|
||||
|
||||
public static INodeFormatter CreateFormatter (string formatter, TypeReflectorOptions options)
|
||||
{
|
||||
INodeFormatter nformatter = Factories.Formatter.Create (formatter);
|
||||
NodeFormatter f = nformatter as NodeFormatter;
|
||||
|
||||
if (f != null) {
|
||||
f.InvokeMethods = options.InvokeMethods;
|
||||
}
|
||||
|
||||
return nformatter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
//
|
||||
// TypeReflectorOptions.cs: Handles `type-reflector' program options
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector
|
||||
{
|
||||
public class TypeReflectorOptions : ProgramOptions {
|
||||
|
||||
private static char addAssemblies = 'a';
|
||||
private static string defaultAssemblies = "default-assemblies";
|
||||
private static string useDefaultAssemblies = "load-default-assemblies";
|
||||
private static char matchAll = 'M';
|
||||
private static char matchFullName = 'F';
|
||||
private static char matchClass = 'C';
|
||||
private static char matchBase = 'B';
|
||||
private static char matchNamespace = 'N';
|
||||
private static char matchReturnType = 'R';
|
||||
private static char showBase = 'b';
|
||||
private static char showConstructors = 'c';
|
||||
private static char showEvents = 'e';
|
||||
private static char showFields = 'f';
|
||||
private static char showInterfaces = 'i';
|
||||
private static char showMethods = 'm';
|
||||
private static char showProperties = 'p';
|
||||
private static char showTypeProperties = 't';
|
||||
private static char showNonPublic = 'U';
|
||||
private static char showMonoBroken = 'K';
|
||||
private static char showAll = 'S';
|
||||
private static char showInheritedMembers= 'R';
|
||||
private static char verboseOutput = 'v';
|
||||
private static char flattenHierarchy = 'l';
|
||||
private static char invokeMethods = 'n';
|
||||
private static char referenceAssemblies = 'r';
|
||||
private static string version = "version";
|
||||
private static string formatter = "formatter";
|
||||
private static string finder = "finder";
|
||||
private static string displayer = "displayer";
|
||||
private static string maxDepth = "max-depth";
|
||||
|
||||
public TypeReflectorOptions ()
|
||||
{
|
||||
AddArgumentOption (addAssemblies, "assemblies",
|
||||
"Add the specified assemblies to the list of " +
|
||||
"assemblies searched for types.",
|
||||
"<assembly-list>");
|
||||
AddArgumentOption (referenceAssemblies, "reference",
|
||||
"Add the specified assembly names to the list of " +
|
||||
"assemblies searched for types.",
|
||||
"<assembly-name-list>");
|
||||
AddOption (matchAll, "match-all",
|
||||
"Type names should be matched in all locations"
|
||||
);
|
||||
AddOption (matchFullName, "match-full-name",
|
||||
"Match type names against the full type name " +
|
||||
"(Namespace + Class Name).\n" +
|
||||
"This is the default.");
|
||||
AddOption (matchClass, "match-class",
|
||||
"Match type names against only the class name");
|
||||
AddOption (matchNamespace, "match-namespace",
|
||||
"Match the type's namespace.");
|
||||
AddOption (matchBase, "match-base",
|
||||
"Match type names against the base class " +
|
||||
"name.\nMatching of the base name is " +
|
||||
"identical to top-level type matches--it " +
|
||||
"matches the namespace, class name, or full " +
|
||||
"type name.");
|
||||
/*
|
||||
AddOption (matchReturnType, "match-return-type",
|
||||
"Match the return type of methods");
|
||||
*/
|
||||
AddOption (showBase, "show-base",
|
||||
"Show the base class.");
|
||||
AddOption (showConstructors, "show-constructors",
|
||||
"Show the type's constructors.");
|
||||
AddOption (showEvents, "show-events",
|
||||
"Show the type's events.");
|
||||
AddOption (showFields, "show-fields",
|
||||
"Show the type's fields.");
|
||||
AddOption (showInterfaces, "show-interfaces",
|
||||
"Show the type's interfaces");
|
||||
AddOption (showMethods, "show-methods",
|
||||
"Show the type's methods.");
|
||||
AddOption (showProperties, "show-properties",
|
||||
"Show the type's properties.");
|
||||
AddOption (showTypeProperties, "show-type-properties",
|
||||
"Show the properties of the type's System.Type "+
|
||||
"object.\nThis is not set by -S.");
|
||||
AddOption (showInheritedMembers, "show-inherited-members",
|
||||
"Show inherited members (members declared by " +
|
||||
"base classes).\nThis is not set by -S.");
|
||||
AddOption (showNonPublic, "show-non-public",
|
||||
"Show non-public members.\n" +
|
||||
"This is not set by -S.");
|
||||
AddOption (showMonoBroken, "show-mono-broken",
|
||||
"Some attributes shown in verbose output " +
|
||||
"cause exceptions when run under Mono. " +
|
||||
"These attributes are not shown by default. "+
|
||||
"This option shows these disabled attributes."+
|
||||
"\nThis is not set by -S.");
|
||||
AddOption (showAll, "show-all",
|
||||
"Show everything except System.Type "+
|
||||
"properties, inherited members, non-public "+
|
||||
"members, and \"broken\" Mono attributes. " +
|
||||
"Equivalent to -bcefimp.");
|
||||
AddOption (flattenHierarchy, "flatten-hierarchy",
|
||||
"Static members of base types should be " +
|
||||
"displayed.");
|
||||
AddOption (invokeMethods, "invoke-methods",
|
||||
"Invoke static methods that accept no arguments " +
|
||||
"and display the return value in the method " +
|
||||
"description (e.g. -m).\n" +
|
||||
"This is not set by -S.");
|
||||
StringBuilder formatterDescription = new StringBuilder ();
|
||||
formatterDescription.Append ("Specify the output style to use. Available values are:");
|
||||
foreach (DictionaryEntry de in Factories.Formatter) {
|
||||
TypeFactoryEntry e = (TypeFactoryEntry) de.Value;
|
||||
formatterDescription.AppendFormat ("\n{0}:\t{1}", e.Key, e.Description);
|
||||
}
|
||||
AddArgumentOption (formatter, formatterDescription.ToString(), "<formatter>");
|
||||
|
||||
StringBuilder finderDescription = new StringBuilder ();
|
||||
finderDescription.Append ("Specify how nodes are found. Available values are:");
|
||||
foreach (DictionaryEntry de in Factories.Finder) {
|
||||
TypeFactoryEntry e = (TypeFactoryEntry) de.Value;
|
||||
finderDescription.AppendFormat ("\n{0}:\t{1}", e.Key, e.Description);
|
||||
}
|
||||
AddArgumentOption (finder, finderDescription.ToString(), "<finder>");
|
||||
|
||||
StringBuilder displayerDescription = new StringBuilder ();
|
||||
displayerDescription.Append ("Specify where output should be displayed. Available values are:");
|
||||
foreach (DictionaryEntry de in Factories.Displayer) {
|
||||
TypeFactoryEntry e = (TypeFactoryEntry) de.Value;
|
||||
displayerDescription.AppendFormat ("\n{0}:\t{1}", e.Key, e.Description);
|
||||
}
|
||||
AddArgumentOption (displayer, displayerDescription.ToString(), "<displayer>");
|
||||
|
||||
AddOption (verboseOutput, "verbose-output",
|
||||
"Print the contents of all the public " +
|
||||
"attributes of the reflection information " +
|
||||
"classes.");
|
||||
AddOption (defaultAssemblies,
|
||||
"Print the default search assemblies and exit.");
|
||||
AddOption (useDefaultAssemblies,
|
||||
"Load the default assemblies and display their contents.");
|
||||
AddArgumentOption (maxDepth, "Specify how deep the verbose output tree should display output.\nDefault is 10.", "INTEGER");
|
||||
AddOption (version, "Output version information and exit.");
|
||||
AddHelpOption ();
|
||||
}
|
||||
|
||||
public override void ParseOptions (string[] options)
|
||||
{
|
||||
base.ParseOptions (options);
|
||||
|
||||
_showAll = base.FoundOption (showAll);
|
||||
_matchAll = base.FoundOption (matchAll);
|
||||
}
|
||||
|
||||
public IList Types {
|
||||
get {return base.UnmatchedOptions;}
|
||||
}
|
||||
|
||||
private bool _matchAll;
|
||||
|
||||
public bool MatchAll {
|
||||
get {return _matchAll;}
|
||||
}
|
||||
|
||||
// default: true;
|
||||
public bool MatchFullName {
|
||||
get {
|
||||
if (!MatchClassName && !MatchNamespace && !MatchBase &&
|
||||
!MatchReturnType)
|
||||
return true;
|
||||
return MatchAll || base.FoundOption (matchFullName);
|
||||
}
|
||||
}
|
||||
|
||||
public bool MatchClassName {
|
||||
get {
|
||||
return MatchAll || base.FoundOption (matchClass);
|
||||
}
|
||||
}
|
||||
|
||||
public bool MatchNamespace {
|
||||
get {
|
||||
return MatchAll || base.FoundOption (matchNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
public bool MatchBase {
|
||||
get {
|
||||
return MatchAll || base.FoundOption (matchBase);
|
||||
}
|
||||
}
|
||||
|
||||
public bool MatchReturnType {
|
||||
get {
|
||||
return MatchAll || base.FoundOption (matchReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _showAll;
|
||||
|
||||
public bool ShowAll {
|
||||
get {
|
||||
return _showAll;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowBase {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showBase);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowConstructors {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showConstructors);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowEvents {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showEvents);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowFields {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showFields);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowInterfaces {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showInterfaces);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowMethods {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showMethods);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowProperties {
|
||||
get {
|
||||
return ShowAll || base.FoundOption (showProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowTypeProperties {
|
||||
get {
|
||||
return base.FoundOption (showTypeProperties);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowInheritedMembers {
|
||||
get {
|
||||
return base.FoundOption (showInheritedMembers);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowNonPublic {
|
||||
get {
|
||||
return base.FoundOption (showNonPublic);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowMonoBroken {
|
||||
get {
|
||||
return base.FoundOption (showMonoBroken);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FlattenHierarchy {
|
||||
get {
|
||||
return base.FoundOption (flattenHierarchy);
|
||||
}
|
||||
}
|
||||
|
||||
public bool VerboseOutput {
|
||||
get {
|
||||
return base.FoundOption (verboseOutput);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Version {
|
||||
get {
|
||||
return base.FoundOption (version);
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxDepth {
|
||||
get {
|
||||
string v = base.FoundOptionValue (maxDepth);
|
||||
if (v != null) {
|
||||
try {
|
||||
return Convert.ToInt32 (v);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
public bool InvokeMethods {
|
||||
get {return base.FoundOption (invokeMethods);}
|
||||
}
|
||||
|
||||
public bool DefaultAssemblies {
|
||||
get {
|
||||
return base.FoundOption (defaultAssemblies);
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseDefaultAssemblies {
|
||||
get {
|
||||
return base.FoundOption (useDefaultAssemblies);
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetDefaultAssemblies ()
|
||||
{
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
|
||||
|
||||
string sysdir = null;
|
||||
|
||||
foreach (Assembly a in assemblies) {
|
||||
string codebase = a.CodeBase;
|
||||
if (codebase.EndsWith ("corlib.dll")) {
|
||||
sysdir = codebase.Substring (0, codebase.LastIndexOf ("/"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Directory.GetFiles (new Uri (sysdir).LocalPath, "*.dll");
|
||||
}
|
||||
|
||||
public ICollection Assemblies {
|
||||
get {
|
||||
string a = base.FoundOptionValue (addAssemblies);
|
||||
ArrayList r = new ArrayList ();
|
||||
|
||||
if (UseDefaultAssemblies)
|
||||
r.AddRange (GetDefaultAssemblies ());
|
||||
|
||||
if (a != null)
|
||||
r.AddRange (a.Split (Path.PathSeparator));
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection References {
|
||||
get {
|
||||
string a = base.FoundOptionValue (referenceAssemblies);
|
||||
ArrayList r = new ArrayList ();
|
||||
|
||||
if (a != null)
|
||||
r.AddRange (a.Split (Path.PathSeparator));
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public string Formatter {
|
||||
get {
|
||||
string s = base.FoundOptionValue (formatter);
|
||||
if (s == null)
|
||||
return "default";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public string Finder {
|
||||
get {
|
||||
string s = base.FoundOptionValue (finder);
|
||||
if (s == null)
|
||||
return "explicit";
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public string Displayer {
|
||||
get {
|
||||
string s = base.FoundOptionValue (displayer);
|
||||
if (s == null)
|
||||
return string.Empty;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OptionsHelp {
|
||||
get {
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
TextFormatter tg0 = new TextFormatter ();
|
||||
TextFormatter tg4 = new TextFormatter (4, 80, 0);
|
||||
sb.Append (
|
||||
"Prints out type information\n" +
|
||||
"\n" +
|
||||
"Usage: " + ProgramName + " [options] [types]\n" +
|
||||
"\n" +
|
||||
"Where [options] can include:\n");
|
||||
sb.Append (base.OptionsHelp);
|
||||
sb.Append (
|
||||
"\n" +
|
||||
tg0.Group (
|
||||
"[types] is interpreted as a regular expression. As regular expression " +
|
||||
"meta-characters are seldom used in class names, specifying a type name " +
|
||||
"looks for all types that have the specified type name as a substring. " +
|
||||
"To get a listing of all available types, pass '.' as the type. (Since " +
|
||||
"regular expressions are used, '.' will match any character, thus matching " +
|
||||
"all possible types.) If not specified, `.' is used as the default.") +
|
||||
"\n\n" +
|
||||
tg0.Group (
|
||||
"<assembly-list/> and <assembly-name-list/> are `" +
|
||||
Path.PathSeparator + "'-delimited list. " +
|
||||
"For example, `" +
|
||||
String.Format ("foo{0}bar{0}baz", Path.PathSeparator) + "' is a valid list.") +
|
||||
"\n\n" +
|
||||
tg0.Group (
|
||||
"The difference between -a and -r is the policy for assembly " +
|
||||
"loading. The -a argument loads assemblies by file " +
|
||||
"system path, such as /path/to/file.dll. The -r argument " +
|
||||
"loads assemblies through Assembly Partial Names, such as " +
|
||||
"\"mscorlib\". This allows assemblies to be found in the GAC " +
|
||||
"without knowing their actual path name."
|
||||
) +
|
||||
"\n\n" +
|
||||
tg0.Group (
|
||||
"Behavior when no assemblies are specified depends upon the front end. " +
|
||||
"The console displayer requires that an assembly be specified; failure " +
|
||||
"to provide one (or more) is an error. The graphical displayers (gtk " +
|
||||
"and swf) don't require them on the command line. No assemblies " +
|
||||
"will be opened by default.") +
|
||||
"\n\n"
|
||||
);
|
||||
sb.Append (String.Format (
|
||||
"Examples:\n" +
|
||||
" {0} Type\n", ProgramName));
|
||||
sb.Append (String.Format (" {0}", tg4.Group ("Finds all types that have `Type' (case-sensitive) as part of their name.")));
|
||||
sb.Append (String.Format (
|
||||
"\n\n" +
|
||||
" {0} [Tt][Yy][Pp][Ee]\n", ProgramName));
|
||||
sb.Append (String.Format (" {0}", tg4.Group ("Finds all types that have `Type' (case-insensitive) as part of their name.")));
|
||||
sb.Append (String.Format (
|
||||
"\n\n" +
|
||||
" {0} -a my-assembly.dll MyType\n", ProgramName));
|
||||
sb.Append (String.Format (" {0}", tg4.Group ("Finds all types that have `MyType' as part of their name within the assembly `my-assembly'.")));
|
||||
sb.Append (String.Format (
|
||||
"\n\n" +
|
||||
" {0} -SKt MyType\n", ProgramName));
|
||||
sb.Append (String.Format (" {0}", tg4.Group ("Find all types that have `MyType' as part of their name, and for those types show all information (-S) including information Mono generates exceptions for (-K) and show the values of the public attributes of the System.Type object for the type (-t).")));
|
||||
sb.Append ("\n\nReport bugs to <jonpryor@vt.edu>.");
|
||||
return sb.ToString ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
2003-09-28 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ITypeDisplayer.cs: Add InitializeInterface() method. This is used to
|
||||
split up Type Displayer execution into five phases:
|
||||
- Create the displayer
|
||||
- Set the Properties (Formatter, Finder, etc.)
|
||||
- Initialize the interface
|
||||
- Add Types
|
||||
- Run
|
||||
The primary reason for adding the initialization step was so that GUI
|
||||
code could assume that the properties had been set and were valid
|
||||
before making use of them, which the Gtk# front-end needed to do.
|
||||
* TypeDisplayer.cs: Default implementation of InitializeInterface(); add a
|
||||
Clear() function which is useful for creating new, empty, windows.
|
||||
|
||||
2003-06-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ChangeLog: New file. I can't believe I haven't needed it yet...
|
||||
* ConsoleTypeDisplayer.cs: Cope with changes in ITypeDisplayer
|
||||
* ITypeDisplayer.cs: Assemblies are required now, not types. It's more
|
||||
sensible this way. AddType() now has `curType' and `totalTypes'
|
||||
parameters, which allows GUI displayers to display progress bars.
|
||||
* TypeDisplayer.cs: Cope with changes in ITypeDisplayer
|
||||
|
||||
# vim: noexpandtab
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// ConsoleTypeDisplayer.cs:
|
||||
// Display types on the console.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
// #define TRACE
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers
|
||||
{
|
||||
public class ConsoleTypeDisplayer : TypeDisplayer
|
||||
{
|
||||
private IndentingTextWriter writer = new IndentingTextWriter (Console.Out);
|
||||
|
||||
// `ReflectionTypeDisplayer.PrintTypeProperties' is recursive, but refrains
|
||||
// from printing duplicates. Despite duplicate removal, the output for
|
||||
// printing the Properties of System.Type is > 800K of text.
|
||||
//
|
||||
// 3 levels permits viewing Attribute values, but not the attributes of
|
||||
// those attribute values.
|
||||
//
|
||||
// For example, 3 levels permits:
|
||||
// class System.Type {depth 0}
|
||||
// Properties: {depth 1}
|
||||
// System.Reflection.MemberTypes MemberType {depth 2}
|
||||
// - CanRead=True {depth 3}
|
||||
// - CanWrite=False {depth 3}
|
||||
// ...
|
||||
private int maxDepth = 3;
|
||||
|
||||
public override int MaxDepth {
|
||||
set {maxDepth = value;}
|
||||
}
|
||||
|
||||
public override bool AssembliesRequired {
|
||||
get {return true;}
|
||||
}
|
||||
|
||||
public ConsoleTypeDisplayer ()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
foreach (Assembly a in Assemblies) {
|
||||
writer.WriteLine ("Assembly: FullName='{0}'; Location='{1}'",
|
||||
a.FullName, a.Location);
|
||||
using (Indenter i = Indent()) {
|
||||
foreach (string ns in Namespaces(a)) {
|
||||
writer.WriteLine ("Namespace: {0}", ns);
|
||||
using (Indenter i2 = Indent()) {
|
||||
foreach (Type type in Types (a, ns)) {
|
||||
Node root = new Node (Formatter, Finder);
|
||||
// new GroupingNodeFinder (f));
|
||||
// new ExplicitNodeFinder());
|
||||
// root.Extra = new NodeInfo (null, type, NodeTypes.Type);
|
||||
root.NodeInfo = new NodeInfo (null, type);
|
||||
ShowNode (root, writer, maxDepth);
|
||||
writer.WriteLine ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowNode (Node root, IndentingTextWriter writer, int maxDepth)
|
||||
{
|
||||
writer.WriteLine (root.Description);
|
||||
if (maxDepth > 0) {
|
||||
using (Indenter i = new Indenter (writer)) {
|
||||
foreach (Node child in root.GetChildren()) {
|
||||
ShowNode (child, writer, maxDepth-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Indenter Indent ()
|
||||
{
|
||||
return new Indenter (writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// ITypeDisplayer.cs:
|
||||
// Framework interface for the displaying of types to a display device (e.g.
|
||||
// console or GUI program).
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
using Mono.TypeReflector;
|
||||
using Mono.TypeReflector.Finders;
|
||||
using Mono.TypeReflector.Formatters;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers
|
||||
{
|
||||
public interface ITypeDisplayer
|
||||
{
|
||||
INodeFormatter Formatter {set;}
|
||||
INodeFinder Finder {set;}
|
||||
TypeReflectorOptions Options {set;}
|
||||
int MaxDepth {set;}
|
||||
bool AssembliesRequired {get;}
|
||||
|
||||
void InitializeInterface ();
|
||||
|
||||
void AddType (Type n, int curType, int totalTypes);
|
||||
|
||||
void Run ();
|
||||
|
||||
void ShowError (string message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
//
|
||||
// IndentingTextWriter.cs: Helper class to indent text written to a TextWriter
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers
|
||||
{
|
||||
public class IndentingTextWriter : TextWriter {
|
||||
|
||||
private static BooleanSwitch info =
|
||||
new BooleanSwitch ("indenting-text-writer", "IndentingTextWriter messages");
|
||||
|
||||
private TextWriter _writer;
|
||||
|
||||
private int indentLevel = 0;
|
||||
private int indentSize = 4;
|
||||
private bool needIndent = true;
|
||||
private char indentChar = ' ';
|
||||
|
||||
public IndentingTextWriter (TextWriter writer)
|
||||
{
|
||||
_writer = writer;
|
||||
}
|
||||
|
||||
public int IndentLevel {
|
||||
get {return indentLevel;}
|
||||
set {indentLevel = value;}
|
||||
}
|
||||
|
||||
public int IndentSize {
|
||||
get {return indentSize;}
|
||||
set {indentSize = value;}
|
||||
}
|
||||
|
||||
public char IndentChar {
|
||||
get {return indentChar;}
|
||||
set {indentChar = value;}
|
||||
}
|
||||
|
||||
public void Indent ()
|
||||
{
|
||||
++IndentLevel;
|
||||
}
|
||||
|
||||
public void Unindent ()
|
||||
{
|
||||
--IndentLevel;
|
||||
}
|
||||
|
||||
protected bool NeedIndent {
|
||||
get {return needIndent;}
|
||||
set {needIndent = value;}
|
||||
}
|
||||
|
||||
protected virtual void WriteIndent ()
|
||||
{
|
||||
NeedIndent = false;
|
||||
Trace.WriteLineIf (info.Enabled, String.Format(
|
||||
"WriteIndent: char='{0}',level={1},size={2}",
|
||||
IndentChar, IndentLevel, IndentSize));
|
||||
string indent = new string (IndentChar,
|
||||
IndentLevel * IndentSize);
|
||||
Write (indent);
|
||||
}
|
||||
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
_writer.Close ();
|
||||
}
|
||||
|
||||
public override System.Text.Encoding Encoding {
|
||||
get {return _writer.Encoding;}
|
||||
}
|
||||
|
||||
public override void Write (string value)
|
||||
{
|
||||
string[] lines = value.Split ('\n');
|
||||
_Write (lines[0]);
|
||||
if (lines.Length > 1) {
|
||||
WriteLine ();
|
||||
for (int i = 1; i != lines.Length; ++i)
|
||||
_WriteLine (lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void _Write (string value)
|
||||
{
|
||||
if (NeedIndent)
|
||||
WriteIndent ();
|
||||
_writer.Write (value);
|
||||
}
|
||||
|
||||
public override void WriteLine ()
|
||||
{
|
||||
if (NeedIndent)
|
||||
WriteIndent ();
|
||||
_writer.WriteLine ();
|
||||
NeedIndent = true;
|
||||
}
|
||||
|
||||
public override void WriteLine (string value)
|
||||
{
|
||||
string[] lines = value.Split ('\n');
|
||||
foreach (string s in lines)
|
||||
_WriteLine (s);
|
||||
}
|
||||
|
||||
private void _WriteLine (string value)
|
||||
{
|
||||
Trace.WriteLineIf (info.Enabled, String.Format(
|
||||
"WriteLine: NeedIndent={0}", NeedIndent));
|
||||
if (NeedIndent)
|
||||
WriteIndent ();
|
||||
_writer.WriteLine (value);
|
||||
NeedIndent = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class Indenter : IDisposable {
|
||||
|
||||
private static BooleanSwitch info =
|
||||
new BooleanSwitch ("indenter", "Indenter Messages");
|
||||
|
||||
private IndentingTextWriter _writer;
|
||||
private int level;
|
||||
|
||||
public Indenter (IndentingTextWriter writer)
|
||||
: this (writer, 1)
|
||||
{
|
||||
}
|
||||
|
||||
public Indenter (IndentingTextWriter writer, int level)
|
||||
{
|
||||
this.level = level;
|
||||
_writer = writer;
|
||||
_writer.IndentLevel += level;
|
||||
// _writer.Indent ();
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
_writer.IndentLevel -= level;
|
||||
// _writer.Unindent ();
|
||||
Trace.WriteLineIf (info.Enabled, String.Format(
|
||||
"Disposing; indentlevel={0}",
|
||||
_writer.IndentLevel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// TypeDisplayer.cs:
|
||||
// Common ITypeDisplayer operations
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
// #define TRACE
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Mono.TypeReflector.Finders;
|
||||
using Mono.TypeReflector.Formatters;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers
|
||||
{
|
||||
sealed class DisplayerComparer : IComparer
|
||||
{
|
||||
public static readonly DisplayerComparer Default = new DisplayerComparer ();
|
||||
|
||||
// we store either Assembly's or Types; handle both.
|
||||
public int Compare (object a, object b)
|
||||
{
|
||||
if (a is Assembly) {
|
||||
Assembly aa = (Assembly) a;
|
||||
Assembly ab = (Assembly) b;
|
||||
return aa.FullName.CompareTo (ab.FullName);
|
||||
}
|
||||
if (a is Type) {
|
||||
Type ta = (Type) a;
|
||||
Type tb = (Type) b;
|
||||
return ta.FullName.CompareTo (tb.FullName);
|
||||
}
|
||||
return Comparer.Default.Compare (a, b);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class TypeDisplayer : ITypeDisplayer
|
||||
{
|
||||
private INodeFormatter formatter;
|
||||
private INodeFinder finder;
|
||||
private TypeReflectorOptions options;
|
||||
|
||||
// type: map<Assembly, map<Namespace, list<Type> > >
|
||||
private IDictionary types = CreateDictionary ();
|
||||
|
||||
public TypeDisplayer ()
|
||||
{
|
||||
}
|
||||
|
||||
public void Clear ()
|
||||
{
|
||||
types = CreateDictionary ();
|
||||
}
|
||||
|
||||
public INodeFormatter Formatter {
|
||||
get {return formatter;}
|
||||
set {formatter = value;}
|
||||
}
|
||||
|
||||
public INodeFinder Finder {
|
||||
get {return finder;}
|
||||
set {finder = value;}
|
||||
}
|
||||
|
||||
public TypeReflectorOptions Options {
|
||||
get {return options;}
|
||||
set {options = value;}
|
||||
}
|
||||
|
||||
public abstract int MaxDepth {set;}
|
||||
public abstract bool AssembliesRequired {get;}
|
||||
|
||||
public virtual void InitializeInterface ()
|
||||
{
|
||||
}
|
||||
|
||||
protected ICollection Assemblies {
|
||||
get {return types.Keys;}
|
||||
}
|
||||
|
||||
private static IDictionary CreateDictionary ()
|
||||
{
|
||||
return new SortedList (DisplayerComparer.Default);
|
||||
}
|
||||
|
||||
protected ICollection Namespaces (Assembly a)
|
||||
{
|
||||
return _Namespaces(a).Keys;
|
||||
}
|
||||
|
||||
protected ICollection Types (Assembly a, string ns)
|
||||
{
|
||||
// return (ICollection) _Namespaces(a)[ns];
|
||||
return _Types (_Namespaces(a), ns).Keys;
|
||||
}
|
||||
|
||||
private IDictionary _Namespaces (Assembly a)
|
||||
{
|
||||
IDictionary d = (IDictionary) types[a];
|
||||
if (d == null) {
|
||||
d = CreateDictionary ();
|
||||
types[a] = d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
private IDictionary _Types (IDictionary namespaces, string ns)
|
||||
{
|
||||
if (ns == null)
|
||||
ns = string.Empty;
|
||||
IDictionary list = (IDictionary) namespaces[ns];
|
||||
if (list == null) {
|
||||
list = CreateDictionary ();
|
||||
namespaces[ns] = list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public virtual void AddType (Type type, int curType, int totalTypes)
|
||||
{
|
||||
_Types(_Namespaces(type.Assembly), type.Namespace)[type] = null;
|
||||
}
|
||||
|
||||
public abstract void Run ();
|
||||
|
||||
public virtual void ShowError (string message)
|
||||
{
|
||||
Console.WriteLine (message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
После Ширина: | Высота: | Размер: 517 B |
После Ширина: | Высота: | Размер: 517 B |
После Ширина: | Высота: | Размер: 585 B |
После Ширина: | Высота: | Размер: 284 B |
После Ширина: | Высота: | Размер: 651 B |
После Ширина: | Высота: | Размер: 332 B |
После Ширина: | Высота: | Размер: 708 B |
После Ширина: | Высота: | Размер: 461 B |
После Ширина: | Высота: | Размер: 344 B |
После Ширина: | Высота: | Размер: 348 B |
После Ширина: | Высота: | Размер: 350 B |
После Ширина: | Высота: | Размер: 516 B |
После Ширина: | Высота: | Размер: 133 B |
|
@ -0,0 +1,313 @@
|
|||
//
|
||||
// AppWindowManager.cs:
|
||||
// Handes basic GTK+ window handling (window menu, etc.)
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002-2004 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Gtk;
|
||||
using GtkSharp;
|
||||
using Glade;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers.gtk
|
||||
{
|
||||
public sealed class AppWindowInfo
|
||||
{
|
||||
private Window app_window;
|
||||
private MenuItem app;
|
||||
private MenuItem window;
|
||||
private CheckMenuItem fullscreen;
|
||||
private CheckMenuItem maximize;
|
||||
private string title;
|
||||
|
||||
public AppWindowInfo ()
|
||||
{
|
||||
}
|
||||
|
||||
public AppWindowInfo (Window appWindow, MenuItem app, MenuItem window, CheckMenuItem fullscreen, CheckMenuItem maximize)
|
||||
{
|
||||
this.app_window = appWindow;
|
||||
this.app = app;
|
||||
this.window = window;
|
||||
this.fullscreen = fullscreen;
|
||||
this.maximize = maximize;
|
||||
}
|
||||
|
||||
public Window AppWindow {
|
||||
get {return app_window;}
|
||||
set {
|
||||
app_window = value;
|
||||
app_window.WindowStateEvent +=
|
||||
new WindowStateEventHandler (OnWindowStateEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public MenuItem AppMenu {
|
||||
get {return app;}
|
||||
set {app = value;}
|
||||
}
|
||||
|
||||
public MenuItem WindowMenu {
|
||||
get {return window;}
|
||||
set {window = value;}
|
||||
}
|
||||
|
||||
public CheckMenuItem FullscreenMenu {
|
||||
get {return fullscreen;}
|
||||
set {fullscreen = value;}
|
||||
}
|
||||
|
||||
public CheckMenuItem MaximizeMenu {
|
||||
get {return maximize;}
|
||||
set {maximize = value;}
|
||||
}
|
||||
|
||||
public string Title {
|
||||
get {return title;}
|
||||
}
|
||||
|
||||
internal void SetTitle (string title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
private void OnWindowStateEvent (object sender, WindowStateEventArgs e)
|
||||
{
|
||||
Console.WriteLine ("state event: type=" + e.Event.Type +
|
||||
"; new_window_state=" + e.Event.NewWindowState);
|
||||
|
||||
if (e.Event.Type != Gdk.EventType.WindowState)
|
||||
return;
|
||||
|
||||
switch (e.Event.NewWindowState) {
|
||||
case Gdk.WindowState.Maximized:
|
||||
MaximizeMenu.Active = true;
|
||||
FullscreenMenu.Active = false;
|
||||
break;
|
||||
case Gdk.WindowState.Fullscreen:
|
||||
FullscreenMenu.Active = true;
|
||||
MaximizeMenu.Active = false;
|
||||
break;
|
||||
case (Gdk.WindowState.Fullscreen | Gdk.WindowState.Maximized):
|
||||
MaximizeMenu.Active = true;
|
||||
FullscreenMenu.Active = true;
|
||||
break;
|
||||
case (Gdk.WindowState) 0:
|
||||
FullscreenMenu.Active = false;
|
||||
MaximizeMenu.Active = false;
|
||||
break;
|
||||
default:
|
||||
// ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnPresentWindow (object sender, EventArgs e)
|
||||
{
|
||||
AppWindow.Present ();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AppWindowManager
|
||||
{
|
||||
// type: List<AppWindowInfo>
|
||||
private IList windows = new ArrayList ();
|
||||
|
||||
private int window_offset;
|
||||
|
||||
private string appName;
|
||||
|
||||
public string AppName {
|
||||
get {return appName;}
|
||||
set {appName = value;}
|
||||
}
|
||||
|
||||
public AppWindowManager (string appName)
|
||||
{
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
public void Add (AppWindowInfo window)
|
||||
{
|
||||
if (windows.Count == 0) {
|
||||
Application.Init ();
|
||||
|
||||
window_offset = ((Menu) window.WindowMenu.Submenu).Children.Length - 1;
|
||||
}
|
||||
|
||||
foreach (Label l in window.AppMenu.Children) {
|
||||
l.UseMarkup = true;
|
||||
l.UseUnderline = true;
|
||||
l.MarkupWithMnemonic =
|
||||
string.Format ("<span weight=\"heavy\">{0}</span>", AppName);
|
||||
}
|
||||
|
||||
InitWindowMenu (window);
|
||||
AddWindowMenu (window, "unknown");
|
||||
}
|
||||
|
||||
public void Remove (AppWindowInfo window)
|
||||
{
|
||||
int me = windows.IndexOf (window);
|
||||
windows.RemoveAt (me);
|
||||
|
||||
SyncWindowMenu ();
|
||||
|
||||
window.AppWindow.Destroy ();
|
||||
|
||||
if (windows.Count == 0)
|
||||
Application.Quit ();
|
||||
}
|
||||
|
||||
public void ActivateNext (AppWindowInfo win)
|
||||
{
|
||||
int cur = windows.IndexOf (win);
|
||||
int next = cur+1;
|
||||
if (next == windows.Count)
|
||||
next = 0;
|
||||
AppWindowInfo w = (AppWindowInfo) windows[next];
|
||||
w.AppWindow.Present ();
|
||||
}
|
||||
|
||||
public void ActivatePrevious (AppWindowInfo win)
|
||||
{
|
||||
int cur = windows.IndexOf (win);
|
||||
int prev = cur-1;
|
||||
if (prev == -1)
|
||||
prev = windows.Count - 1;
|
||||
AppWindowInfo w = (AppWindowInfo) windows[prev];
|
||||
w.AppWindow.Present ();
|
||||
}
|
||||
|
||||
public void AllToFront (AppWindowInfo main)
|
||||
{
|
||||
foreach (AppWindowInfo w in windows)
|
||||
w.AppWindow.Present ();
|
||||
main.AppWindow.Present ();
|
||||
}
|
||||
|
||||
public void ShowAll (AppWindowInfo main)
|
||||
{
|
||||
foreach (Window w in Window.ListToplevels()) {
|
||||
w.Present ();
|
||||
}
|
||||
main.AppWindow.Present ();
|
||||
}
|
||||
|
||||
public void HideAll ()
|
||||
{
|
||||
foreach (AppWindowInfo w in windows)
|
||||
w.AppWindow.Iconify ();
|
||||
}
|
||||
|
||||
public void HideOthers (AppWindowInfo main)
|
||||
{
|
||||
foreach (Window w in Window.ListToplevels())
|
||||
w.Iconify ();
|
||||
AllToFront (main);
|
||||
}
|
||||
|
||||
public void SetTitle (AppWindowInfo window, string title)
|
||||
{
|
||||
window.SetTitle (title);
|
||||
SyncWindowMenu ();
|
||||
}
|
||||
|
||||
private void InitWindowMenu (AppWindowInfo window)
|
||||
{
|
||||
Console.WriteLine ("creating window menu");
|
||||
Menu m = (Menu) window.WindowMenu.Submenu;
|
||||
int i = 0;
|
||||
foreach (AppWindowInfo w in windows) {
|
||||
MenuItem r = CreateMenuItem (w.Title, i++);
|
||||
m.Append (r);
|
||||
}
|
||||
window.WindowMenu.ShowAll ();
|
||||
}
|
||||
|
||||
private MenuItem CreateMenuItem (string title, int accel)
|
||||
{
|
||||
// Console.WriteLine ("creating menu item with accel: accel=" +
|
||||
// accel.ToString() + "; # windows=" + s_windows.Count.ToString());
|
||||
MenuItem r = new MenuItem (title);
|
||||
UpdateMenuItem (r, title, accel);
|
||||
return r;
|
||||
}
|
||||
|
||||
private void AddWindowMenu (AppWindowInfo w, string title)
|
||||
{
|
||||
Console.WriteLine ("adding window menu: " + title);
|
||||
windows.Add (w);
|
||||
int n = windows.IndexOf (w);
|
||||
foreach (AppWindowInfo d in windows) {
|
||||
Menu m = (Menu) d.WindowMenu.Submenu;
|
||||
MenuItem mi = CreateMenuItem (title, n);
|
||||
m.Append (mi);
|
||||
d.WindowMenu.ShowAll ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SyncWindowMenu ()
|
||||
{
|
||||
foreach (AppWindowInfo w in windows) {
|
||||
Menu m = (Menu) w.WindowMenu.Submenu;
|
||||
|
||||
// Console.WriteLine (" # menu items: " + m.Children.Count);
|
||||
|
||||
IEnumerator e = m.Children.GetEnumerator ();
|
||||
int cur = 0;
|
||||
|
||||
// Move past non-variable menu items
|
||||
while (e.MoveNext() && cur != window_offset)
|
||||
++cur;
|
||||
|
||||
// We should now be at the variable portion of the Window menu.
|
||||
// Update the titles.
|
||||
while (e.MoveNext() && (cur - window_offset) != windows.Count) {
|
||||
++cur;
|
||||
MenuItem mi = (MenuItem) e.Current;
|
||||
int window = cur-window_offset-1;
|
||||
// Console.WriteLine (" syncing menu item: " + cur.ToString() +
|
||||
// "; is now=" + s_assemblies[window].ToString());
|
||||
UpdateMenuItem (mi, ((AppWindowInfo) windows[window]).Title, window);
|
||||
}
|
||||
|
||||
// Any extra menu items should be removed, probably because the window
|
||||
// was closed
|
||||
if (++cur < m.Children.Length)
|
||||
do {
|
||||
// Console.WriteLine ("removing widget... " + cur.ToString());
|
||||
m.Remove ((Widget) e.Current);
|
||||
++cur;
|
||||
} while (e.MoveNext());
|
||||
|
||||
w.WindowMenu.ShowAll ();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMenuItem (MenuItem mi, string title, int accel)
|
||||
{
|
||||
((Label) mi.Child).Text = title;
|
||||
/*
|
||||
foreach (Label l in mi.Children) {
|
||||
// Console.WriteLine (" updating menu item; was={0}; is={1}",
|
||||
// l.Text, title);
|
||||
l.Text = title;
|
||||
}
|
||||
*/
|
||||
AppWindowInfo d = (AppWindowInfo) windows[accel];
|
||||
// TODO: clear out mi.Activated, so we don't have lots of windows try to
|
||||
// present themselves...
|
||||
mi.Activated += new EventHandler (d.OnPresentWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: noexpandtab
|
|
@ -0,0 +1,129 @@
|
|||
2005-04-12 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs, AppWindowManager: Change namespace to `...gtk'
|
||||
from `...Gtk' (note: it's now fully lowercase). Why? To work around C#
|
||||
"issue" where it prefers names from the current (nested) namespace over
|
||||
the global namespace. So it would look for
|
||||
Mono.TypeReflector.Displayers.Gtk.Window instead of using Gtk.Window
|
||||
--> BAD. The name change fixes this.
|
||||
Thanks to Alexmipego for noticing this.
|
||||
* AppWindowManager.cs: Directly set the MenuItem child text instead of
|
||||
iterating over children. The loop shouldn't be necessary.
|
||||
* GtkTypeDisplayer.cs: Destroy the main window when closing.
|
||||
|
||||
2004-10-09 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Add file drag-and-drop support. You can now DnD
|
||||
files from nautilus onto Type Reflector to open & inspect assemblies.
|
||||
|
||||
2004-06-02 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* AppWindowManager.cs: Update to Gtk# Beta 2 API
|
||||
|
||||
2004-03-07 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* AppWindowManager.cs: Update to gtk-sharp 0.17 API
|
||||
* GtkTypeDisplayer.cs: Update to gtk-sharp 0.17 API
|
||||
|
||||
2003-11-27 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Turn on icon display by default. Change "options"
|
||||
TreeView so that we better organize the options, between binding & members.
|
||||
|
||||
2003-11-23 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Compilation fix for Gtk# 0.14.
|
||||
|
||||
2003-10-25 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* AppWindowManager.cs: New class; "manages" application top-level windows.
|
||||
More accuratey, it manages the "Window" menu, so that it's in sync across
|
||||
all of the created windows.
|
||||
* GtkTypeDisplayer.cs: Factor out the window management code into
|
||||
AppWindowManager.cs.
|
||||
|
||||
2003-10-12 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Gtk# works now, so we can make use of it...
|
||||
- Make the "Reflector" menu bold
|
||||
- Make the "Window" menu update properly, complete with window title names
|
||||
- CVS Gtk# compilation fixes
|
||||
- Some cleanup
|
||||
* type-reflector.gade: I read parts of the Mac OS X HIG; some updates
|
||||
- Preferences should be Ctrl+,
|
||||
- The "short" app name should be referred to in menu items, About, etc.
|
||||
- Add shortcut for Help (F1)
|
||||
|
||||
2003-09-28 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Lots of changes
|
||||
- Initial attempt at adding icons to the TreeView; currently disabled
|
||||
due to runtime error message (needs more debugging); see SHOW_ICONS
|
||||
- Menu layout: We're going Mac OS X style!
|
||||
- More functionality: we can create empty windows, show all windows,
|
||||
hide windows, etc...
|
||||
- Replace Console.WriteLine with Trace.WriteLineIf.
|
||||
- Rename Glade callback functions so that they're not so tied to the
|
||||
menu name. Instead of "on_file_quit_activate", it's "app_quit".
|
||||
* type-reflector.glade: Layout changes:
|
||||
- Use Mac OS X style menu bar
|
||||
- Get rid of stupid spacing on left; it didn't look good or consistent
|
||||
|
||||
2003-09-09 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Compilation fix. Gtk.Window conflicts with
|
||||
Gnome.Window.
|
||||
|
||||
2003-08-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Allow Formatters menu to track updates in Formatters
|
||||
treeview, and vice versa.
|
||||
|
||||
2003-07-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Lots more updates. It's for lots of prototyping...
|
||||
- Prepare for the future of selecting multiple files at once
|
||||
- Complete GUI revamp (new side bar for Formatters, general Finder
|
||||
options, showing/hiding of GUI pieces, name changes, AddType progress...
|
||||
Try it, you'll like it. If the TreeView would ever deal with lots of
|
||||
Reflection, that is. Otherwise, it's horribly broken. But it has been
|
||||
since June 26, so it isn't any worse...
|
||||
* type-reflector.glade: name changes, new widgets, new layout...
|
||||
|
||||
2003-06-26 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Lots 'o' Updates
|
||||
- Clean up OpenFileSelection.
|
||||
- Use the new Managed TreeView functionality.
|
||||
- Allow dynamnic language selection (the View->Formatter menu works now!).
|
||||
- Provide GUI error messages (still needs some work, though).
|
||||
- Fix the Help->About dialog.
|
||||
* type-reflector.glade: Fix the View->Formatter menu, add Accelerator for
|
||||
Help->About, remove unused AboutWindow.
|
||||
|
||||
2003-04-14 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Minor build fixes for latest Gtk#.
|
||||
|
||||
2003-02-19 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Add support for dynamic node expansion, as seen in
|
||||
displayers/swf. For example, if you run "type-displayer -A
|
||||
type-displayer.exe -Sv ." (run Type Displayer on itself, showing
|
||||
everything verbosely), you can keep expanding rows to view detailed
|
||||
parameter information of methods.
|
||||
|
||||
2003-01-14 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: This was moved into /displayers/gtk, so the glade
|
||||
file paths need to be updated.
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs:
|
||||
- If the current window isn't displaying an assembly, open the assembly
|
||||
within the current window.
|
||||
- Use [GladeWidget] attributes to get items from the .glade file.
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Moved to Mono.TypeReflector.Displayers.Gtk.
|
||||
|
||||
2003-01-09 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Change name of OpenFileDialog class to
|
||||
OpenFileSelection. OpenFileDialog is a System.Windows.Forms class, so
|
||||
this was causing compiler errors when attempting to compile both Gtk# and
|
||||
System.Windows.Forms support.
|
||||
|
||||
2002-12-31 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* GtkTypeDisplayer.cs: Remove some debugging messages.
|
||||
|
||||
2002-12-31 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ChangeLog: Added
|
||||
* GtkTypeDisplayer.cs: Gtk# front-end for reflection information
|
||||
* type-reflector.glade: Glade description for Gtk# front-end
|
||||
* type-reflector.gladep: Glade Project file
|
||||
|
||||
# vim: noexpandtab
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
|
||||
|
||||
<glade-project>
|
||||
<name>Type Reflector</name>
|
||||
<program_name>type-reflector</program_name>
|
||||
<gnome_support>FALSE</gnome_support>
|
||||
</glade-project>
|
|
@ -0,0 +1,20 @@
|
|||
2003-07-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* SwfTypeDisplayer.cs: Cope with ITypeDisplayer changes.
|
||||
|
||||
2003-06-26 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* SwfWindow.cs: Remove System.Data namespace (It's unused).
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* SwfTypeDisplayer.cs: If the current window isn't displaying an assembly,
|
||||
open the assembly within the current window.
|
||||
|
||||
2003-01-10 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* SwfTypeDisplayer.cs: Moved to Mono.TypeReflector.Displayers.Swf.
|
||||
* SwfWindow.cs: Moved to Mono.TypeReflector.Displayers.Swf.
|
||||
|
||||
2003-01-08 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ChangeLog: Added
|
||||
* SwfTypeDisplayer.cs: System.Windows.Forms front-end for
|
||||
reflection information
|
||||
* SwfWindow.cs: Creates the actual window, menus, etc.
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
//
|
||||
// SwfTypeDisplayer.cs:
|
||||
// Display types using System.Windows.Forms
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2003 Jonathan Pryor
|
||||
//
|
||||
|
||||
// #define TRACE
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
// for GUI support
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers.Swf
|
||||
{
|
||||
class ReflectorTreeNode : TreeNode
|
||||
{
|
||||
private Node node = null;
|
||||
|
||||
public ReflectorTreeNode (string text)
|
||||
{
|
||||
base.Text = text;
|
||||
}
|
||||
|
||||
public ReflectorTreeNode (Node node)
|
||||
{
|
||||
this.node = node;
|
||||
base.Text = node.Description;
|
||||
}
|
||||
|
||||
public Node Node {
|
||||
get {return node;}
|
||||
}
|
||||
}
|
||||
|
||||
public class SwfTypeDisplayer : TypeDisplayer
|
||||
{
|
||||
private static int windows = 0;
|
||||
|
||||
private const string dummyText = "dummy: you shouldn't see this!";
|
||||
|
||||
private SwfWindow window = new SwfWindow ();
|
||||
|
||||
public override int MaxDepth {
|
||||
set {/* ignore */}
|
||||
}
|
||||
|
||||
public override bool AssembliesRequired {
|
||||
get {return false;}
|
||||
}
|
||||
|
||||
public SwfTypeDisplayer ()
|
||||
{
|
||||
++windows;
|
||||
|
||||
window.FileOpenClick += new EventHandler (OnFileOpen);
|
||||
window.FileQuitClick += new EventHandler (OnFileQuit);
|
||||
|
||||
window.EditCopyClick += new EventHandler (OnEditCopy);
|
||||
|
||||
window.ViewFormatterDefaultClick += new EventHandler (OnViewFormatterDefault);
|
||||
window.ViewFormatterVBClick += new EventHandler (OnViewFormatterVB);
|
||||
window.ViewFormatterCSharpClick += new EventHandler (OnViewFormatterCSharp);
|
||||
window.ViewFinderExplicitClick += new EventHandler (OnViewFinderExplicit);
|
||||
window.ViewFinderReflectionClick += new EventHandler (OnViewFinderReflection);
|
||||
|
||||
window.HelpAboutClick += new EventHandler (OnHelpAbout);
|
||||
|
||||
window.TreeView.BeforeExpand += new TreeViewCancelEventHandler (OnNodeExpand);
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
ShowTypes ();
|
||||
|
||||
Application.Run (window);
|
||||
}
|
||||
|
||||
public override void ShowError (string message)
|
||||
{
|
||||
MessageBox.Show (message, "Type Reflector", MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
private void ShowTypes ()
|
||||
{
|
||||
foreach (Assembly a in Assemblies) {
|
||||
ReflectorTreeNode tn = new ReflectorTreeNode (string.Format ("Assembly: {0}", a.FullName));
|
||||
|
||||
foreach (string ns in Namespaces (a)) {
|
||||
ReflectorTreeNode nn = new ReflectorTreeNode (string.Format ("Namespace: {0}", ns));
|
||||
tn.Nodes.Add (nn);
|
||||
|
||||
foreach (Type type in Types (a, ns))
|
||||
AddType (type, nn);
|
||||
}
|
||||
|
||||
window.TreeView.Nodes.Add (tn);
|
||||
}
|
||||
|
||||
window.Show ();
|
||||
}
|
||||
|
||||
private void AddType (Type type, ReflectorTreeNode parent)
|
||||
{
|
||||
ReflectorTreeNode tn = CreateTreeNode (type);
|
||||
tn.Nodes.Add (new ReflectorTreeNode (dummyText));
|
||||
parent.Nodes.Add (tn);
|
||||
}
|
||||
|
||||
private ReflectorTreeNode CreateTreeNode (Type type)
|
||||
{
|
||||
Node root = new Node (Formatter, Finder);
|
||||
root.NodeInfo = new NodeInfo (null, type);
|
||||
return new ReflectorTreeNode (root);
|
||||
}
|
||||
|
||||
// System.Windows.Forms Functions...
|
||||
private void OnFileQuit (object o, EventArgs args)
|
||||
{
|
||||
Console.WriteLine ("Asked to quit app; windows=" + windows);
|
||||
window.Hide ();
|
||||
window.Dispose ();
|
||||
if (--windows == 0) {
|
||||
Console.WriteLine ("App.Exit");
|
||||
Application.Exit ();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileOpen (object o, EventArgs args)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog ();
|
||||
ofd.CheckFileExists = true;
|
||||
ofd.Multiselect = true;
|
||||
ofd.Title = "Open Assembly";
|
||||
ofd.ValidateNames = true;
|
||||
ofd.Filter =
|
||||
"Assemblies (*.dll;*.exe)|*.dll;*.exe" +
|
||||
"|Dynamic Link Libraries (*.dll)|*.dll" +
|
||||
"|Executables (*.exe)|*.exe" +
|
||||
"|All Files (*.*)|*.*";
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK) {
|
||||
OpenAssemblies (ofd.FileNames);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenAssemblies (string[] assemblies)
|
||||
{
|
||||
SwfTypeDisplayer d = null;
|
||||
if (base.Assemblies.Count == 0)
|
||||
d = this;
|
||||
else {
|
||||
d = new SwfTypeDisplayer ();
|
||||
d.Finder = Finder;
|
||||
d.Formatter = Formatter;
|
||||
d.Options = Options;
|
||||
}
|
||||
|
||||
TypeLoader tl = TypeReflectorApp.CreateLoader (Options);
|
||||
tl.Assemblies = assemblies;
|
||||
|
||||
try {
|
||||
TypeReflectorApp.FindTypes (d, tl, new string[]{"."});
|
||||
d.ShowTypes ();
|
||||
}
|
||||
catch (Exception e) {
|
||||
ShowError (string.Format ("Unable to load Assembly '{0}': {1}",
|
||||
assemblies, e.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEditCopy (object o, EventArgs args)
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
public void OnViewFormatterDefault (object o, EventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnViewFormatterVB (object o, EventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnViewFormatterCSharp (object o, EventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnViewFinderReflection (object o, EventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnViewFinderExplicit (object o, EventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnHelpAbout (object o, EventArgs args)
|
||||
{
|
||||
/* ignore */
|
||||
MessageBox.Show (
|
||||
"Type Reflector, version x.y. Copyright (C) 2002-2003 Jonathan Pryor",
|
||||
"About Type Reflector",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
TypeReflectorApp.PrintVersion ();
|
||||
}
|
||||
|
||||
private void OnNodeExpand (object sender, TreeViewCancelEventArgs e)
|
||||
{
|
||||
/*
|
||||
Console.WriteLine ("(node-expanded (Action {0}) (Cancel {1}) (Node {2}))",
|
||||
e.Action, e.Cancel, e.Node);
|
||||
*/
|
||||
|
||||
if ((e.Node.Nodes.Count > 0) && (e.Node.Nodes[0].Text == dummyText)) {
|
||||
ReflectorTreeNode tn = (ReflectorTreeNode) e.Node;
|
||||
tn.Nodes.Clear ();
|
||||
|
||||
foreach (Node child in tn.Node.GetChildren()) {
|
||||
ReflectorTreeNode cn = new ReflectorTreeNode (child);
|
||||
cn.Nodes.Add (new ReflectorTreeNode (dummyText));
|
||||
tn.Nodes.Add (cn);
|
||||
}
|
||||
|
||||
if (tn.Nodes.Count == 0)
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mono.TypeReflector.Displayers.Swf
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for Form1.
|
||||
/// </summary>
|
||||
public class SwfWindow : System.Windows.Forms.Form
|
||||
{
|
||||
private System.Windows.Forms.MainMenu mainMenu;
|
||||
private System.Windows.Forms.ToolBarButton openButton;
|
||||
private System.Windows.Forms.ToolBarButton preferencesButton;
|
||||
private System.Windows.Forms.TreeView treeView;
|
||||
private System.Windows.Forms.MenuItem menuFile;
|
||||
private System.Windows.Forms.MenuItem menuEdit;
|
||||
private System.Windows.Forms.MenuItem menuView;
|
||||
private System.Windows.Forms.MenuItem menuHelp;
|
||||
private System.Windows.Forms.MenuItem menuFileOpen;
|
||||
private System.Windows.Forms.MenuItem menuFileQuit;
|
||||
private System.Windows.Forms.MenuItem menuEditCopy;
|
||||
private System.Windows.Forms.MenuItem menuFormatter;
|
||||
private System.Windows.Forms.MenuItem menuFinder;
|
||||
private System.Windows.Forms.MenuItem menuViewFormatterDefault;
|
||||
private System.Windows.Forms.MenuItem menuViewFormatterVB;
|
||||
private System.Windows.Forms.MenuItem menuViewFormatterCSharp;
|
||||
private System.Windows.Forms.MenuItem menuViewFinderExplicit;
|
||||
private System.Windows.Forms.MenuItem menuViewFinderReflection;
|
||||
private System.Windows.Forms.MenuItem menuHelpAbout;
|
||||
private System.Windows.Forms.ToolBar toolBar;
|
||||
private System.Windows.Forms.StatusBar statusBar;
|
||||
private System.Windows.Forms.MenuItem menuFileSep1;
|
||||
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.Container components = null;
|
||||
|
||||
public SwfWindow ()
|
||||
{
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent();
|
||||
|
||||
//
|
||||
// TODO: Add any constructor code after InitializeComponent call
|
||||
//
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if( disposing )
|
||||
{
|
||||
if (components != null)
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
}
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.mainMenu = new System.Windows.Forms.MainMenu();
|
||||
this.menuFile = new System.Windows.Forms.MenuItem();
|
||||
this.menuFileOpen = new System.Windows.Forms.MenuItem();
|
||||
this.menuFileSep1 = new System.Windows.Forms.MenuItem();
|
||||
this.menuFileQuit = new System.Windows.Forms.MenuItem();
|
||||
this.menuEdit = new System.Windows.Forms.MenuItem();
|
||||
this.menuEditCopy = new System.Windows.Forms.MenuItem();
|
||||
this.menuView = new System.Windows.Forms.MenuItem();
|
||||
this.menuFormatter = new System.Windows.Forms.MenuItem();
|
||||
this.menuViewFormatterDefault = new System.Windows.Forms.MenuItem();
|
||||
this.menuViewFormatterVB = new System.Windows.Forms.MenuItem();
|
||||
this.menuViewFormatterCSharp = new System.Windows.Forms.MenuItem();
|
||||
this.menuFinder = new System.Windows.Forms.MenuItem();
|
||||
this.menuViewFinderExplicit = new System.Windows.Forms.MenuItem();
|
||||
this.menuViewFinderReflection = new System.Windows.Forms.MenuItem();
|
||||
this.menuHelp = new System.Windows.Forms.MenuItem();
|
||||
this.menuHelpAbout = new System.Windows.Forms.MenuItem();
|
||||
this.toolBar = new System.Windows.Forms.ToolBar();
|
||||
this.openButton = new System.Windows.Forms.ToolBarButton();
|
||||
this.preferencesButton = new System.Windows.Forms.ToolBarButton();
|
||||
this.statusBar = new System.Windows.Forms.StatusBar();
|
||||
this.treeView = new System.Windows.Forms.TreeView();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// mainMenu
|
||||
//
|
||||
this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuFile,
|
||||
this.menuEdit,
|
||||
this.menuView,
|
||||
this.menuHelp});
|
||||
//
|
||||
// menuFile
|
||||
//
|
||||
this.menuFile.Index = 0;
|
||||
this.menuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuFileOpen,
|
||||
this.menuFileSep1,
|
||||
this.menuFileQuit});
|
||||
this.menuFile.Text = "&File";
|
||||
//
|
||||
// menuFileOpen
|
||||
//
|
||||
this.menuFileOpen.Index = 0;
|
||||
this.menuFileOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
|
||||
this.menuFileOpen.Text = "&Open";
|
||||
this.menuFileOpen.Click += new System.EventHandler(this.menuFileOpen_Click);
|
||||
//
|
||||
// menuFileSep1
|
||||
//
|
||||
this.menuFileSep1.Index = 1;
|
||||
this.menuFileSep1.Text = "-";
|
||||
//
|
||||
// menuFileQuit
|
||||
//
|
||||
this.menuFileQuit.Index = 2;
|
||||
this.menuFileQuit.Shortcut = System.Windows.Forms.Shortcut.CtrlQ;
|
||||
this.menuFileQuit.Text = "&Quit";
|
||||
this.menuFileQuit.Click += new System.EventHandler(this.menuFileQuit_Click);
|
||||
//
|
||||
// menuEdit
|
||||
//
|
||||
this.menuEdit.Index = 1;
|
||||
this.menuEdit.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuEditCopy});
|
||||
this.menuEdit.Text = "&Edit";
|
||||
//
|
||||
// menuEditCopy
|
||||
//
|
||||
this.menuEditCopy.Index = 0;
|
||||
this.menuEditCopy.Shortcut = System.Windows.Forms.Shortcut.CtrlC;
|
||||
this.menuEditCopy.Text = "&Copy";
|
||||
this.menuEditCopy.Click += new System.EventHandler(this.menuEditCopy_Click);
|
||||
//
|
||||
// menuView
|
||||
//
|
||||
this.menuView.Index = 2;
|
||||
this.menuView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuFormatter,
|
||||
this.menuFinder});
|
||||
this.menuView.Text = "&View";
|
||||
//
|
||||
// menuFormatter
|
||||
//
|
||||
this.menuFormatter.Index = 0;
|
||||
this.menuFormatter.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuViewFormatterDefault,
|
||||
this.menuViewFormatterVB,
|
||||
this.menuViewFormatterCSharp});
|
||||
this.menuFormatter.Text = "F&ormatter";
|
||||
//
|
||||
// menuViewFormatterDefault
|
||||
//
|
||||
this.menuViewFormatterDefault.Index = 0;
|
||||
this.menuViewFormatterDefault.Text = "&Default";
|
||||
this.menuViewFormatterDefault.Click += new System.EventHandler(this.menuViewFormatterDefault_Click);
|
||||
//
|
||||
// menuViewFormatterVB
|
||||
//
|
||||
this.menuViewFormatterVB.Index = 1;
|
||||
this.menuViewFormatterVB.Text = "&Visual Basic .NET";
|
||||
this.menuViewFormatterVB.Click += new System.EventHandler(this.menuViewFormatterVB_Click);
|
||||
//
|
||||
// menuViewFormatterCSharp
|
||||
//
|
||||
this.menuViewFormatterCSharp.Index = 2;
|
||||
this.menuViewFormatterCSharp.Text = "&C#";
|
||||
this.menuViewFormatterCSharp.Click += new System.EventHandler(this.menuViewFormatterCSharp_Click);
|
||||
//
|
||||
// menuFinder
|
||||
//
|
||||
this.menuFinder.Index = 1;
|
||||
this.menuFinder.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuViewFinderExplicit,
|
||||
this.menuViewFinderReflection});
|
||||
this.menuFinder.Text = "F&inder";
|
||||
//
|
||||
// menuViewFinderExplicit
|
||||
//
|
||||
this.menuViewFinderExplicit.Index = 0;
|
||||
this.menuViewFinderExplicit.Text = "&Explicit";
|
||||
this.menuViewFinderExplicit.Click += new System.EventHandler(this.menuViewFinderExplicit_Click);
|
||||
//
|
||||
// menuViewFinderReflection
|
||||
//
|
||||
this.menuViewFinderReflection.Index = 1;
|
||||
this.menuViewFinderReflection.Text = "&Reflection";
|
||||
this.menuViewFinderReflection.Click += new System.EventHandler(this.menuViewFinderReflection_Click);
|
||||
//
|
||||
// menuHelp
|
||||
//
|
||||
this.menuHelp.Index = 3;
|
||||
this.menuHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuHelpAbout});
|
||||
this.menuHelp.Text = "&Help";
|
||||
//
|
||||
// menuHelpAbout
|
||||
//
|
||||
this.menuHelpAbout.Index = 0;
|
||||
this.menuHelpAbout.Text = "&About";
|
||||
this.menuHelpAbout.Click += new System.EventHandler(this.menuHelpAbout_Click);
|
||||
//
|
||||
// toolBar
|
||||
//
|
||||
this.toolBar.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
|
||||
this.openButton,
|
||||
this.preferencesButton});
|
||||
this.toolBar.DropDownArrows = true;
|
||||
this.toolBar.Name = "toolBar";
|
||||
this.toolBar.ShowToolTips = true;
|
||||
this.toolBar.Size = new System.Drawing.Size(292, 39);
|
||||
this.toolBar.TabIndex = 0;
|
||||
this.toolBar.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar_ButtonClick);
|
||||
//
|
||||
// openButton
|
||||
//
|
||||
this.openButton.Text = "Open";
|
||||
this.openButton.ToolTipText = "Open an Assembly";
|
||||
//
|
||||
// preferencesButton
|
||||
//
|
||||
this.preferencesButton.Text = "Preferences";
|
||||
this.preferencesButton.ToolTipText = "Edit Program Preferences";
|
||||
//
|
||||
// statusBar
|
||||
//
|
||||
this.statusBar.Location = new System.Drawing.Point(0, 244);
|
||||
this.statusBar.Name = "statusBar";
|
||||
this.statusBar.Size = new System.Drawing.Size(292, 22);
|
||||
this.statusBar.TabIndex = 1;
|
||||
//
|
||||
// treeView
|
||||
//
|
||||
this.treeView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.treeView.ImageIndex = -1;
|
||||
this.treeView.Location = new System.Drawing.Point(0, 39);
|
||||
this.treeView.Name = "treeView";
|
||||
this.treeView.SelectedImageIndex = -1;
|
||||
this.treeView.Size = new System.Drawing.Size(292, 205);
|
||||
this.treeView.TabIndex = 2;
|
||||
//
|
||||
// SwfApp
|
||||
//
|
||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||||
this.ClientSize = new System.Drawing.Size(292, 266);
|
||||
this.Controls.AddRange(new System.Windows.Forms.Control[] {
|
||||
this.treeView,
|
||||
this.statusBar,
|
||||
this.toolBar});
|
||||
this.Menu = this.mainMenu;
|
||||
this.Name = "SwfApp";
|
||||
this.Text = "Type Reflector";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected override void OnClosing (CancelEventArgs e)
|
||||
{
|
||||
base.OnClosing (e);
|
||||
e.Cancel = true;
|
||||
FileQuitClick (this, e);
|
||||
}
|
||||
|
||||
private void menuFileOpen_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
FileOpenClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuFileQuit_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
FileQuitClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuEditCopy_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
EditCopyClick (sender, e);
|
||||
}
|
||||
|
||||
private void toolBar_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
|
||||
{
|
||||
menuFileOpen_Click (sender, e);
|
||||
}
|
||||
|
||||
private void menuViewFormatterDefault_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
ViewFormatterDefaultClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuViewFormatterVB_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
ViewFormatterVBClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuViewFormatterCSharp_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
ViewFormatterCSharpClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuViewFinderExplicit_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
ViewFinderExplicitClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuViewFinderReflection_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
ViewFinderReflectionClick (sender, e);
|
||||
}
|
||||
|
||||
private void menuHelpAbout_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
HelpAboutClick (sender, e);
|
||||
}
|
||||
|
||||
public EventHandler FileOpenClick;
|
||||
public EventHandler FileQuitClick;
|
||||
public EventHandler EditCopyClick;
|
||||
public EventHandler ViewFormatterDefaultClick;
|
||||
public EventHandler ViewFormatterVBClick;
|
||||
public EventHandler ViewFormatterCSharpClick;
|
||||
public EventHandler ViewFinderExplicitClick;
|
||||
public EventHandler ViewFinderReflectionClick;
|
||||
public EventHandler HelpAboutClick;
|
||||
|
||||
public TreeView TreeView {
|
||||
get {return treeView;}
|
||||
}
|
||||
|
||||
public StatusBar StatusBar {
|
||||
get {return statusBar;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
2003-07-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ChangeLog: New File.
|
||||
* GroupingNodeFinder.cs: Cope with INodeFinder changes
|
||||
* INodeFinder.cs: It's now a "policy" interface now. BindingFlags and
|
||||
FindMemberTypes are now public properties (instead of public properties of
|
||||
NodeFinder).
|
||||
* NodeFinder.cs: NodeFinder.cs: Cope with INodeFinder changes
|
||||
|
|
@ -0,0 +1,362 @@
|
|||
//
|
||||
// ExplicitNodeFinder.cs: finds sub-nodes for a given NodeInfo
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Finders
|
||||
{
|
||||
public class ExplicitNodeFinder : NodeFinder {
|
||||
|
||||
private static BooleanSwitch info =
|
||||
new BooleanSwitch ("explicit-node-finder", "ExplicitNodeFinder messages");
|
||||
|
||||
// supported sub-groups
|
||||
private const string parameters = "GetParameters():";
|
||||
private const string customAttributes= "GetCustomAttributes(true):";
|
||||
private const string typeInformation = "System.Type Properties:";
|
||||
|
||||
public override NodeInfoCollection GetChildren (NodeInfo root)
|
||||
{
|
||||
// We don't want an infinite loop; quite showing children
|
||||
Trace.WriteLineIf (info.Enabled, "GetChildren for root.NodeType=" + root.NodeType);
|
||||
if (!CanShowChildren (root))
|
||||
return new NodeInfoCollection();
|
||||
|
||||
return base.GetChildren (root);
|
||||
}
|
||||
|
||||
private static bool CanShowChildren (NodeInfo node)
|
||||
{
|
||||
Trace.WriteLineIf (info.Enabled, "CanShowChildren");
|
||||
if (node.Parent != null) {
|
||||
if (node.NodeType == NodeTypes.Parameter)
|
||||
return true;
|
||||
if (node.NodeType == NodeTypes.Other)
|
||||
return true;
|
||||
if (InHistory (2, node, NodeTypes.ReturnValue) &&
|
||||
(CountType(node, NodeTypes.ReturnValue) < 2))
|
||||
return true;
|
||||
|
||||
NodeTypes t = node.Parent.NodeType;
|
||||
// Console.WriteLine ("** CanShowChildren: {0}", t);
|
||||
switch (t) {
|
||||
case NodeTypes.Type:
|
||||
// case NodeTypes.Other:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool InHistory (int count, NodeInfo root, params NodeTypes[] types)
|
||||
{
|
||||
while ((root != null) && (count-- != 0)) {
|
||||
foreach (NodeTypes t in types)
|
||||
if (root.NodeType == t)
|
||||
return true;
|
||||
root = root.Parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int CountType (NodeInfo root, NodeTypes type)
|
||||
{
|
||||
int count = 0;
|
||||
while (root != null) {
|
||||
if (root.NodeType == type)
|
||||
++count;
|
||||
root = root.Parent;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
protected override void AddTypeChildren (NodeInfoCollection c, NodeInfo parent, Type type)
|
||||
{
|
||||
object instance = parent.ReflectionInstance;
|
||||
|
||||
// System.Type information
|
||||
if (ShowTypeProperties)
|
||||
c.Add (new NodeInfo (parent,
|
||||
new NodeGroup (typeInformation, type,
|
||||
new NodeGrouper (GetTypeInformationChildren))));
|
||||
|
||||
// Base Type
|
||||
if (ShowBase)
|
||||
c.Add (new NodeInfo (parent, NodeTypes.BaseType, type.BaseType, type.BaseType));
|
||||
|
||||
// Implemented Interfaces
|
||||
if (ShowInterfaces)
|
||||
foreach (Type t in type.GetInterfaces())
|
||||
c.Add (new NodeInfo (parent, NodeTypes.Interface, t, instance));
|
||||
|
||||
// Constructors
|
||||
if (ShowConstructors)
|
||||
foreach (ConstructorInfo ci in type.GetConstructors (BindingFlags))
|
||||
c.Add (new NodeInfo (parent, ci, instance));
|
||||
|
||||
// Methods
|
||||
if (ShowMethods)
|
||||
foreach (MethodInfo mi in type.GetMethods (BindingFlags))
|
||||
c.Add (new NodeInfo (parent, mi, instance));
|
||||
|
||||
// Fields
|
||||
if (ShowFields)
|
||||
foreach (FieldInfo fi in type.GetFields (BindingFlags))
|
||||
c.Add (new NodeInfo (parent, fi, instance));
|
||||
|
||||
// Properties
|
||||
if (ShowProperties)
|
||||
foreach (PropertyInfo pi in type.GetProperties (BindingFlags))
|
||||
c.Add (new NodeInfo (parent, pi, instance));
|
||||
|
||||
// Events
|
||||
if (ShowEvents)
|
||||
foreach (EventInfo ei in type.GetEvents (BindingFlags))
|
||||
c.Add (new NodeInfo (parent, ei, instance));
|
||||
}
|
||||
|
||||
private void GetTypeInformationChildren (NodeInfoCollection c, NodeInfo parent, object args)
|
||||
{
|
||||
Type type = (Type) args;
|
||||
AddMemberChildren (parent, type, c);
|
||||
AddMembers (parent, type, "Delimiter", c);
|
||||
AddMembers (parent, type, "EmptyTypes", c);
|
||||
AddMembers (parent, type, "FilterAttribute", c);
|
||||
AddMembers (parent, type, "FilterName", c);
|
||||
AddMembers (parent, type, "FilterNameIgnoreCase", c);
|
||||
AddMembers (parent, type, "Missing", c);
|
||||
|
||||
AddMembers (parent, type, "Assembly", c);
|
||||
c.Add (new NodeInfo (parent,
|
||||
new NodeGroup ("Assembly Attributes", type.Assembly,
|
||||
new NodeGrouper (GetAssemblyChildren))));
|
||||
|
||||
AddMembers (parent, type, "AssemblyQualifiedName", c);
|
||||
AddMembers (parent, type, "Attributes", c);
|
||||
AddMembers (parent, type, "BaseType", c);
|
||||
AddMembers (parent, type, "DeclaringType", c);
|
||||
AddMembers (parent, type, "DefaultBinder", c);
|
||||
AddMembers (parent, type, "FullName", c);
|
||||
AddMembers (parent, type, "GUID", c);
|
||||
AddMembers (parent, type, "HasElementType", c);
|
||||
AddMembers (parent, type, "IsAbstract", c);
|
||||
AddMembers (parent, type, "IsAnsiClass", c);
|
||||
AddMembers (parent, type, "IsArray", c);
|
||||
AddMembers (parent, type, "IsAutoClass", c);
|
||||
AddMembers (parent, type, "IsAutoLayout", c);
|
||||
AddMembers (parent, type, "IsByRef", c);
|
||||
AddMembers (parent, type, "IsClass", c);
|
||||
AddMembers (parent, type, "IsCOMObject", c);
|
||||
AddMembers (parent, type, "IsContextful", c);
|
||||
AddMembers (parent, type, "IsEnum", c);
|
||||
AddMembers (parent, type, "IsExplicitLayout", c);
|
||||
AddMembers (parent, type, "IsImport", c);
|
||||
AddMembers (parent, type, "IsInterface", c);
|
||||
AddMembers (parent, type, "IsLayoutSequential", c);
|
||||
AddMembers (parent, type, "IsMarshalByRef", c);
|
||||
AddMembers (parent, type, "IsNestedAssembly", c);
|
||||
AddMembers (parent, type, "IsNestedFamORAssem", c);
|
||||
AddMembers (parent, type, "IsNestedPrivate", c);
|
||||
AddMembers (parent, type, "IsNotPublic", c);
|
||||
AddMembers (parent, type, "IsPointer", c);
|
||||
AddMembers (parent, type, "IsPrimitive", c);
|
||||
AddMembers (parent, type, "IsPublic", c);
|
||||
AddMembers (parent, type, "IsSealed", c);
|
||||
AddMembers (parent, type, "IsSerializable", c);
|
||||
AddMembers (parent, type, "IsSpecialName", c);
|
||||
AddMembers (parent, type, "IsUnicodeClass", c);
|
||||
AddMembers (parent, type, "IsValueType", c);
|
||||
AddMembers (parent, type, "Module", c);
|
||||
AddMembers (parent, type, "Namespace", c);
|
||||
AddMembers (parent, type, "TypeHandle", c);
|
||||
AddMembers (parent, type, "TypeInitializer", c);
|
||||
AddMembers (parent, type, "UnderlyingSystemType", c);
|
||||
}
|
||||
|
||||
private void GetAssemblyChildren (NodeInfoCollection c, NodeInfo parent, object args)
|
||||
{
|
||||
Assembly a = (Assembly) args;
|
||||
AddMembers (parent, a, "CodeBase", c);
|
||||
AddMembers (parent, a, "EntryPoint", c);
|
||||
AddMembers (parent, a, "EscapedCodeBase", c);
|
||||
AddMembers (parent, a, "Evidence", c);
|
||||
AddMembers (parent, a, "FullName", c);
|
||||
AddMembers (parent, a, "GlobalAssemblyCache", c);
|
||||
AddMembers (parent, a, "Location", c);
|
||||
}
|
||||
|
||||
private void AddMembers (NodeInfo parent, object instance, string member, NodeInfoCollection c)
|
||||
{
|
||||
Type type = instance.GetType ();
|
||||
foreach (MemberInfo mi in type.GetMember (member, BindingFlags)) {
|
||||
c.Add (new NodeInfo (parent, mi, instance));
|
||||
}
|
||||
}
|
||||
|
||||
private void AddMemberChildren (NodeInfo parent, MemberInfo mi, NodeInfoCollection c)
|
||||
{
|
||||
AddMembers (parent, mi, "DeclaringType", c);
|
||||
AddMembers (parent, mi, "MemberType", c);
|
||||
AddMembers (parent, mi, "Name", c);
|
||||
AddMembers (parent, mi, "ReflectedType", c);
|
||||
// AddMembers (parent, mi, "GetCustomAttributes", c);
|
||||
c.Add (new NodeInfo (parent,
|
||||
new NodeGroup (customAttributes,
|
||||
mi.GetCustomAttributes (true),
|
||||
new NodeGrouper (GetCustomAttributeProviderChildren))));
|
||||
// c.Add (new NodeInfo (parent, mi, customAttributes, NodeTypes.Other));
|
||||
// c.Add (new NodeInfo (parent, mi, mi, NodeTypes.CustomAttributeProvider));
|
||||
}
|
||||
|
||||
private void GetCustomAttributeProviderChildren (NodeInfoCollection c, NodeInfo root, object args)
|
||||
{
|
||||
object[] attrs = (object[]) args;
|
||||
foreach (object attr in attrs) {
|
||||
// TODO: specify type?
|
||||
c.Add (new NodeInfo (root, attr));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AddFieldChildren (NodeInfoCollection c, NodeInfo parent, FieldInfo field)
|
||||
{
|
||||
Trace.WriteLineIf (info.Enabled, "Getting Field Children");
|
||||
AddMemberChildren (parent, field, c);
|
||||
AddMembers (parent, field, "Attributes", c);
|
||||
AddMembers (parent, field, "FieldHandle", c);
|
||||
AddMembers (parent, field, "FieldType", c);
|
||||
AddMembers (parent, field, "IsAssembly", c);
|
||||
AddMembers (parent, field, "IsFamily", c);
|
||||
AddMembers (parent, field, "IsFamilyAndAssembly", c);
|
||||
AddMembers (parent, field, "IsFamilyOrAssembly", c);
|
||||
AddMembers (parent, field, "IsInitOnly", c);
|
||||
AddMembers (parent, field, "IsLiteral", c);
|
||||
AddMembers (parent, field, "IsNotSerialized", c);
|
||||
AddMembers (parent, field, "IsPinvokeImpl", c);
|
||||
AddMembers (parent, field, "IsPublic", c);
|
||||
AddMembers (parent, field, "IsSpecialName", c);
|
||||
AddMembers (parent, field, "IsStatic", c);
|
||||
|
||||
try {
|
||||
object o = field.GetValue (parent.ReflectionInstance);
|
||||
c.Add (new NodeInfo (parent, NodeTypes.ReturnValue, o.GetType(), o, o));
|
||||
}
|
||||
catch (Exception e) {
|
||||
string r = string.Format ("{{can't get field value; through exception: {0}}}", e.Message);
|
||||
c.Add (new NodeInfo (parent, NodeTypes.ReturnValue, null, null, r));
|
||||
}
|
||||
}
|
||||
|
||||
private void AddMethodBaseChildren (NodeInfo parent, MethodBase mb, NodeInfoCollection c)
|
||||
{
|
||||
AddMemberChildren (parent, mb, c);
|
||||
AddMembers (parent, mb, "Attributes", c);
|
||||
AddMembers (parent, mb, "CallingConvention", c);
|
||||
AddMembers (parent, mb, "IsAbstract", c);
|
||||
AddMembers (parent, mb, "IsAssembly", c);
|
||||
AddMembers (parent, mb, "IsConstructor", c);
|
||||
AddMembers (parent, mb, "IsFamily", c);
|
||||
AddMembers (parent, mb, "IsFamilyAndAssembly", c);
|
||||
AddMembers (parent, mb, "IsFamilyOrAssembly", c);
|
||||
AddMembers (parent, mb, "IsFinal", c);
|
||||
AddMembers (parent, mb, "IsHideBySig", c);
|
||||
AddMembers (parent, mb, "IsPrivate", c);
|
||||
AddMembers (parent, mb, "IsPublic", c);
|
||||
AddMembers (parent, mb, "IsSpecialName", c);
|
||||
AddMembers (parent, mb, "IsStatic", c);
|
||||
AddMembers (parent, mb, "IsVirtual", c);
|
||||
AddMembers (parent, mb, "MethodHandle", c);
|
||||
AddMembers (parent, mb, "GetMethodImplementationFlags", c);
|
||||
c.Add (new NodeInfo (parent,
|
||||
new NodeGroup (parameters, mb,
|
||||
new NodeGrouper (GetParametersChildren))));
|
||||
// c.Add (new NodeInfo (parent, mb, parameters, NodeTypes.Other));
|
||||
}
|
||||
|
||||
private void GetParametersChildren (NodeInfoCollection c, NodeInfo parent, object args)
|
||||
{
|
||||
MethodBase mb = (MethodBase) args;
|
||||
foreach (ParameterInfo pi in mb.GetParameters()) {
|
||||
c.Add (new NodeInfo (parent, NodeTypes.Parameter, pi, pi));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AddParameterChildren (NodeInfoCollection c, NodeInfo parent, ParameterInfo pi)
|
||||
{
|
||||
// TODO: handle custom attributes...
|
||||
// c.Add (new NodeInfo (parent, pi, customAttributes, NodeTypes.Other));
|
||||
// c.Add (new NodeInfo (parent, pi, pi, NodeTypes.CustomAttributeProvider));
|
||||
AddMembers (parent, pi, "Attributes", c);
|
||||
AddMembers (parent, pi, "DefaultValue", c);
|
||||
AddMembers (parent, pi, "IsIn", c);
|
||||
AddMembers (parent, pi, "IsLcid", c);
|
||||
AddMembers (parent, pi, "IsOptional", c);
|
||||
AddMembers (parent, pi, "IsOut", c);
|
||||
AddMembers (parent, pi, "IsRetval", c);
|
||||
AddMembers (parent, pi, "Member", c);
|
||||
AddMembers (parent, pi, "Name", c);
|
||||
AddMembers (parent, pi, "ParameterType", c);
|
||||
AddMembers (parent, pi, "Position", c);
|
||||
}
|
||||
|
||||
protected override void AddConstructorChildren (NodeInfoCollection c, NodeInfo parent, ConstructorInfo node)
|
||||
{
|
||||
AddMethodBaseChildren (parent, node, c);
|
||||
}
|
||||
|
||||
protected override void AddEventChildren (NodeInfoCollection c, NodeInfo parent, EventInfo node)
|
||||
{
|
||||
AddMemberChildren (parent, node, c);
|
||||
AddMembers (parent, node, "Attributes", c);
|
||||
AddMembers (parent, node, "EventHandlerType", c);
|
||||
AddMembers (parent, node, "IsMulticast", c);
|
||||
AddMembers (parent, node, "IsSpecialName", c);
|
||||
}
|
||||
|
||||
protected override void AddMethodChildren (NodeInfoCollection c, NodeInfo parent, MethodInfo node)
|
||||
{
|
||||
AddMethodBaseChildren (parent, node, c);
|
||||
AddMembers (parent, node, "ReturnType", c);
|
||||
AddMembers (parent, node, "ReturnTypeCustomAttributes", c);
|
||||
GetReturnValue (c, parent, node);
|
||||
}
|
||||
|
||||
private void GetReturnValue (NodeInfoCollection c, NodeInfo parent, MethodInfo method)
|
||||
{
|
||||
if (method != null && method.GetParameters().Length == 0) {
|
||||
try {
|
||||
object o = method.Invoke (parent.ReflectionInstance, null);
|
||||
c.Add (new NodeInfo (parent, NodeTypes.ReturnValue, o.GetType(), o, o));
|
||||
}
|
||||
catch (Exception e) {
|
||||
string r = string.Format ("{{method has 0 args; through exception: {0}}}", e.Message);
|
||||
c.Add (new NodeInfo (parent, NodeTypes.ReturnValue, null, null, r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AddPropertyChildren (NodeInfoCollection c, NodeInfo parent, PropertyInfo node)
|
||||
{
|
||||
AddMemberChildren (parent, node, c);
|
||||
AddMembers (parent, node, "Attributes", c);
|
||||
AddMembers (parent, node, "CanRead", c);
|
||||
AddMembers (parent, node, "CanWrite", c);
|
||||
AddMembers (parent, node, "IsSpecialName", c);
|
||||
AddMembers (parent, node, "PropertyType", c);
|
||||
GetReturnValue (c, parent, node.GetGetMethod());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
//
|
||||
// GroupingNodeFinder.cs: Groups nodes into categories, e.g. fields, methods...
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.TypeReflector.Finders
|
||||
{
|
||||
/**
|
||||
* GroupingNode is a decorator over INodeFinder that groups child nodes of
|
||||
* similar type in the resulting tree.
|
||||
*/
|
||||
public class GroupingNodeFinder : INodeFinder {
|
||||
|
||||
private static BooleanSwitch info =
|
||||
new BooleanSwitch ("grouping-node-finder", "GroupingNodeFinder messages");
|
||||
|
||||
private sealed class GroupingInfo {
|
||||
public string Group;
|
||||
public NodeInfo Info;
|
||||
|
||||
public GroupingInfo (string g, NodeInfo i)
|
||||
{
|
||||
Group = g;
|
||||
Info = i;
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return Group;
|
||||
}
|
||||
}
|
||||
|
||||
private const string baseNode = "Base:";
|
||||
private const string interfacesNode = "Interfaces:";
|
||||
private const string constructorsNode = "Constructors:";
|
||||
private const string methodsNode = "Methods:";
|
||||
private const string fieldsNode = "Fields:";
|
||||
private const string propertiesNode = "Properties:";
|
||||
private const string eventsNode = "Events:";
|
||||
private const string nestedClasses = "Nested Classes:";
|
||||
|
||||
private IDictionary nodes = null;
|
||||
|
||||
private INodeFinder finder;
|
||||
|
||||
public GroupingNodeFinder (INodeFinder finder)
|
||||
{
|
||||
this.finder = finder;
|
||||
}
|
||||
|
||||
public string Description {
|
||||
get {return finder.Description;}
|
||||
set {finder.Description = value;}
|
||||
}
|
||||
|
||||
public string FactoryKey {
|
||||
get {return finder.FactoryKey;}
|
||||
set {finder.FactoryKey = value;}
|
||||
}
|
||||
|
||||
public object Clone ()
|
||||
{
|
||||
GroupingNodeFinder g = (GroupingNodeFinder) MemberwiseClone ();
|
||||
g.finder = (INodeFinder) finder.Clone ();
|
||||
return g;
|
||||
}
|
||||
|
||||
public FindMemberTypes FindMembers {
|
||||
get {return finder.FindMembers;}
|
||||
set {finder.FindMembers = value;}
|
||||
}
|
||||
|
||||
public NodeInfoCollection GetChildren (NodeInfo root)
|
||||
{
|
||||
Trace.WriteLineIf (info.Enabled, "GroupingNodeFinder.GetChildren");
|
||||
NodeInfoCollection collection = null;
|
||||
|
||||
switch (root.NodeType) {
|
||||
case NodeTypes.Type:
|
||||
GroupChildNodes (root);
|
||||
collection = new NodeInfoCollection ();
|
||||
collection.AddRange ((NodeInfoCollection)nodes[""]);
|
||||
AddGroup (nestedClasses, collection, root);
|
||||
AddGroup (baseNode, collection, root);
|
||||
AddGroup (interfacesNode, collection, root);
|
||||
AddGroup (constructorsNode, collection, root);
|
||||
AddGroup (methodsNode, collection, root);
|
||||
AddGroup (fieldsNode, collection, root);
|
||||
AddGroup (propertiesNode, collection, root);
|
||||
AddGroup (eventsNode, collection, root);
|
||||
return collection;
|
||||
case NodeTypes.Other:
|
||||
if (root.Description is GroupingInfo) {
|
||||
Trace.WriteLineIf (info.Enabled, "Found GroupingInfo");
|
||||
GroupingInfo g = (GroupingInfo) root.Description;
|
||||
collection = (NodeInfoCollection) nodes[g.Group];
|
||||
return collection;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return finder.GetChildren (root);
|
||||
}
|
||||
|
||||
public BindingFlags BindingFlags {
|
||||
get {return finder.BindingFlags;}
|
||||
set {finder.BindingFlags = value;}
|
||||
}
|
||||
|
||||
private void GroupChildNodes (NodeInfo root)
|
||||
{
|
||||
if (nodes != null)
|
||||
return;
|
||||
|
||||
nodes = new Hashtable ();
|
||||
nodes[""] = new NodeInfoCollection();
|
||||
nodes[baseNode] = new NodeInfoCollection();
|
||||
nodes[interfacesNode] = new NodeInfoCollection();
|
||||
nodes[constructorsNode] = new NodeInfoCollection();
|
||||
nodes[methodsNode] = new NodeInfoCollection();
|
||||
nodes[fieldsNode] = new NodeInfoCollection();
|
||||
nodes[propertiesNode] = new NodeInfoCollection();
|
||||
nodes[eventsNode] = new NodeInfoCollection();
|
||||
nodes[nestedClasses] = new NodeInfoCollection();
|
||||
|
||||
foreach (NodeInfo n in finder.GetChildren (root)) {
|
||||
string c = null;
|
||||
switch (n.NodeType) {
|
||||
case NodeTypes.BaseType:
|
||||
c = baseNode;
|
||||
break;
|
||||
case NodeTypes.Interface:
|
||||
c = interfacesNode;
|
||||
break;
|
||||
case NodeTypes.Field:
|
||||
c = fieldsNode;
|
||||
break;
|
||||
case NodeTypes.Constructor:
|
||||
c = constructorsNode;
|
||||
break;
|
||||
case NodeTypes.Method:
|
||||
c = methodsNode;
|
||||
break;
|
||||
case NodeTypes.Property:
|
||||
c = propertiesNode;
|
||||
break;
|
||||
case NodeTypes.Event:
|
||||
c = eventsNode;
|
||||
break;
|
||||
case NodeTypes.Type:
|
||||
c = nestedClasses;
|
||||
break;
|
||||
default:
|
||||
c = "";
|
||||
break;
|
||||
}
|
||||
((NodeInfoCollection)nodes[c]).Add (n);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddGroup (string name, NodeInfoCollection collection, NodeInfo root)
|
||||
{
|
||||
NodeInfoCollection nic = (NodeInfoCollection) nodes[name];
|
||||
if (nic.Count > 0)
|
||||
collection.Add (CreateGroupingNode (name, root));
|
||||
}
|
||||
|
||||
private static NodeInfo CreateGroupingNode (string group, NodeInfo node)
|
||||
{
|
||||
return new NodeInfo (node, new GroupingInfo (group, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// INodeFinder.cs: Policy interface to find nodes for a type.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Mono.TypeReflector;
|
||||
|
||||
namespace Mono.TypeReflector.Finders
|
||||
{
|
||||
[Flags]
|
||||
public enum FindMemberTypes {
|
||||
Base = 1 << 1,
|
||||
Interfaces = 1 << 2,
|
||||
Fields = 1 << 3,
|
||||
Constructors = 1 << 4,
|
||||
Methods = 1 << 5,
|
||||
Properties = 1 << 6,
|
||||
Events = 1 << 7,
|
||||
TypeProperties = 1 << 8,
|
||||
VerboseOutput = 1 << 9,
|
||||
MonoBroken = 1 << 10
|
||||
}
|
||||
|
||||
public interface INodeFinder : IPolicy {
|
||||
|
||||
NodeInfoCollection GetChildren (NodeInfo root);
|
||||
|
||||
BindingFlags BindingFlags {get; set;}
|
||||
|
||||
FindMemberTypes FindMembers {get; set;}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
//
|
||||
// NodeFinder.cs: Finds sub-nodes for a given NodeInfo object.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Mono.TypeReflector.Finders
|
||||
{
|
||||
public delegate void BaseTypeEventHandler (object sender, BaseTypeEventArgs e);
|
||||
public delegate void TypeEventHandler (object sender, TypeEventArgs e);
|
||||
public delegate void InterfacesEventHandler (object sender, InterfacesEventArgs e);
|
||||
public delegate void FieldsEventHandler (object sender, FieldsEventArgs e);
|
||||
public delegate void PropertiesEventHandler (object sender, PropertiesEventArgs e);
|
||||
public delegate void EventsEventHandler (object sender, EventsEventArgs e);
|
||||
public delegate void ConstructorsEventHandler (object sender, ConstructorsEventArgs e);
|
||||
public delegate void MethodsEventHandler (object sender, MethodsEventArgs e);
|
||||
|
||||
public class NodeFoundEventArgs : EventArgs {
|
||||
private NodeInfo _node;
|
||||
|
||||
internal NodeFoundEventArgs (NodeInfo node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
public NodeInfo NodeInfo {
|
||||
get {return _node;}
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseTypeEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private Type _base;
|
||||
|
||||
internal BaseTypeEventArgs (NodeInfo node, Type type)
|
||||
: base(node)
|
||||
{
|
||||
_base = type;
|
||||
}
|
||||
|
||||
public Type BaseType {
|
||||
get {return _base;}
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private Type _type;
|
||||
|
||||
internal TypeEventArgs (NodeInfo node, Type type)
|
||||
: base(node)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public Type Type {
|
||||
get {return _type;}
|
||||
}
|
||||
}
|
||||
|
||||
public class InterfacesEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private Type[] _interfaces;
|
||||
|
||||
internal InterfacesEventArgs (NodeInfo node, Type[] interfaces)
|
||||
: base(node)
|
||||
{
|
||||
_interfaces = interfaces ;
|
||||
}
|
||||
|
||||
public Type[] Interfaces {
|
||||
get {return _interfaces;}
|
||||
}
|
||||
}
|
||||
|
||||
public class FieldsEventArgs : NodeFoundEventArgs {
|
||||
private FieldInfo[] _fields;
|
||||
|
||||
internal FieldsEventArgs (NodeInfo node, FieldInfo[] fields)
|
||||
: base(node)
|
||||
{
|
||||
_fields = fields;
|
||||
}
|
||||
|
||||
public FieldInfo[] Fields {
|
||||
get {return _fields;}
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertiesEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private PropertyInfo[] _props;
|
||||
|
||||
internal PropertiesEventArgs (NodeInfo node, PropertyInfo[] properties)
|
||||
: base(node)
|
||||
{
|
||||
_props = properties;
|
||||
}
|
||||
|
||||
public PropertyInfo[] Properties {
|
||||
get {return _props;}
|
||||
}
|
||||
}
|
||||
|
||||
public class EventsEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private EventInfo[] _events;
|
||||
|
||||
internal EventsEventArgs (NodeInfo node, EventInfo[] events)
|
||||
: base(node)
|
||||
{
|
||||
_events = events;
|
||||
}
|
||||
|
||||
public EventInfo[] Events {
|
||||
get {return _events;}
|
||||
}
|
||||
}
|
||||
|
||||
public class ConstructorsEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private ConstructorInfo[] _ctors;
|
||||
|
||||
internal ConstructorsEventArgs (NodeInfo node, ConstructorInfo[] ctors)
|
||||
: base(node)
|
||||
{
|
||||
_ctors = ctors;
|
||||
}
|
||||
|
||||
public ConstructorInfo[] Constructors {
|
||||
get {return _ctors;}
|
||||
}
|
||||
}
|
||||
|
||||
public class MethodsEventArgs : NodeFoundEventArgs {
|
||||
|
||||
private MethodInfo[] _methods;
|
||||
|
||||
internal MethodsEventArgs (NodeInfo node, MethodInfo[] methods)
|
||||
: base(node)
|
||||
{
|
||||
_methods = methods;
|
||||
}
|
||||
|
||||
public MethodInfo[] Methods {
|
||||
get {return _methods;}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class NodeFinder : Policy, INodeFinder {
|
||||
|
||||
private static BooleanSwitch info =
|
||||
new BooleanSwitch ("node-finder", "NodeFinder messages");
|
||||
|
||||
private BindingFlags bindingFlags =
|
||||
BindingFlags.DeclaredOnly |
|
||||
BindingFlags.Public |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Static;
|
||||
|
||||
private FindMemberTypes members;
|
||||
|
||||
public BindingFlags BindingFlags {
|
||||
get {return bindingFlags;}
|
||||
set {bindingFlags = value;}
|
||||
}
|
||||
|
||||
public FindMemberTypes FindMembers {
|
||||
get {return members;}
|
||||
set {members = value;}
|
||||
}
|
||||
|
||||
protected bool ShowBase {
|
||||
get {return (members & FindMemberTypes.Base) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowConstructors {
|
||||
get {return (members & FindMemberTypes.Constructors) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowEvents {
|
||||
get {return (members & FindMemberTypes.Events) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowFields {
|
||||
get {return (members & FindMemberTypes.Fields) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowInterfaces {
|
||||
get {return (members & FindMemberTypes.Interfaces) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowMethods {
|
||||
get {return (members & FindMemberTypes.Methods) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowProperties {
|
||||
get {return (members & FindMemberTypes.Properties) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowTypeProperties {
|
||||
get {return (members & FindMemberTypes.TypeProperties) != 0;}
|
||||
}
|
||||
|
||||
protected bool ShowMonoBroken {
|
||||
get {return (members & FindMemberTypes.MonoBroken) != 0;}
|
||||
}
|
||||
|
||||
protected bool VerboseOutput {
|
||||
get {return (members & FindMemberTypes.VerboseOutput) != 0;}
|
||||
}
|
||||
|
||||
public virtual NodeInfoCollection GetChildren (NodeInfo root)
|
||||
{
|
||||
Trace.WriteLineIf (info.Enabled, "NodeFinder.GetChildren");
|
||||
NodeInfoCollection c = new NodeInfoCollection ();
|
||||
|
||||
// always handle NodeTypes.Type
|
||||
if (root.NodeType == NodeTypes.Type)
|
||||
AddTypeChildren (c, root, (Type) root.ReflectionObject);
|
||||
else if (VerboseOutput) {
|
||||
switch (root.NodeType) {
|
||||
case NodeTypes.BaseType:
|
||||
AddBaseTypeChildren (c, root, (Type) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Interface:
|
||||
AddInterfaceChildren (c, root, (Type) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Field:
|
||||
AddFieldChildren (c, root, (FieldInfo) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Constructor:
|
||||
AddConstructorChildren (c, root, (ConstructorInfo) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Method:
|
||||
AddMethodChildren (c, root, (MethodInfo) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Parameter:
|
||||
AddParameterChildren (c, root, (ParameterInfo) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Property:
|
||||
AddPropertyChildren (c, root, (PropertyInfo) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.Event:
|
||||
AddEventChildren (c, root, (EventInfo) root.ReflectionObject);
|
||||
break;
|
||||
case NodeTypes.ReturnValue:
|
||||
AddReturnValueChildren (c, root);
|
||||
break;
|
||||
case NodeTypes.Other:
|
||||
case NodeTypes.Alias:
|
||||
AddOtherChildren (c, root);
|
||||
break;
|
||||
default:
|
||||
AddUnhandledChildren (c, root);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected virtual void AddTypeChildren (NodeInfoCollection c, NodeInfo root, Type type)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddBaseTypeChildren (NodeInfoCollection c, NodeInfo root, Type baseType)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddInterfaceChildren (NodeInfoCollection c, NodeInfo root, Type iface)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddFieldChildren (NodeInfoCollection c, NodeInfo root, FieldInfo field)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddConstructorChildren (NodeInfoCollection c, NodeInfo root, ConstructorInfo ctor)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddMethodChildren (NodeInfoCollection c, NodeInfo root, MethodInfo method)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddParameterChildren (NodeInfoCollection c, NodeInfo root, ParameterInfo param)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddPropertyChildren (NodeInfoCollection c, NodeInfo root, PropertyInfo property)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddEventChildren (NodeInfoCollection c, NodeInfo root, EventInfo e)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void AddReturnValueChildren (NodeInfoCollection c, NodeInfo root)
|
||||
{
|
||||
if (root.ReflectionObject != null)
|
||||
AddTypeChildren (c, root, (Type) root.ReflectionObject);
|
||||
}
|
||||
|
||||
protected virtual void AddOtherChildren (NodeInfoCollection c, NodeInfo root)
|
||||
{
|
||||
if (root.Description is NodeGroup) {
|
||||
NodeGroup g = (NodeGroup) root.Description;
|
||||
g.Invoke (c, root);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddUnhandledChildren (NodeInfoCollection c, NodeInfo root)
|
||||
{
|
||||
c.Add (new NodeInfo (root, "Unhandled child: NodeType=" + root.NodeType));
|
||||
}
|
||||
|
||||
public event TypeEventHandler Types;
|
||||
public event BaseTypeEventHandler BaseType;
|
||||
public event InterfacesEventHandler Interfaces;
|
||||
public event FieldsEventHandler Fields;
|
||||
public event PropertiesEventHandler Properties;
|
||||
public event EventsEventHandler Events;
|
||||
public event ConstructorsEventHandler Constructors;
|
||||
public event MethodsEventHandler Methods;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// ReflectionNodeFinder.cs: Uses reflection to find child nodes.
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Finders
|
||||
{
|
||||
public class ReflectionNodeFinder : NodeFinder {
|
||||
|
||||
private class Observed
|
||||
{
|
||||
private ArrayList seen = new ArrayList ();
|
||||
public void Add (object value)
|
||||
{
|
||||
seen.Add (value);
|
||||
// seen.Sort ();
|
||||
}
|
||||
|
||||
public bool Found (object value)
|
||||
{
|
||||
return seen.Contains (value);
|
||||
// return seen.BinarySearch (value) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
private Observed seenReflectionObjects = new Observed ();
|
||||
|
||||
private sealed class MemberInfoNameComparer : IComparer {
|
||||
|
||||
public int Compare (object a, object b)
|
||||
{
|
||||
if (a == null && b == null)
|
||||
return 0;
|
||||
|
||||
MemberInfo x = a as MemberInfo;
|
||||
MemberInfo y = b as MemberInfo;
|
||||
if (a == null && b == null)
|
||||
throw new ArgumentException ();
|
||||
return x.Name.CompareTo (y.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly IComparer NameComparer = new MemberInfoNameComparer ();
|
||||
|
||||
protected override void AddTypeChildren (NodeInfoCollection c, NodeInfo parent, Type type)
|
||||
{
|
||||
object instance = parent.ReflectionInstance;
|
||||
|
||||
foreach (MemberInfo mi in GetMembers (type)) {
|
||||
AddNode (c, parent, mi, instance);
|
||||
}
|
||||
}
|
||||
|
||||
private IList GetMembers (Type type)
|
||||
{
|
||||
ArrayList members = new ArrayList ();
|
||||
members.AddRange (type.GetMembers (BindingFlags));
|
||||
members.Sort (NameComparer);
|
||||
return members;
|
||||
}
|
||||
|
||||
private void AddNode (NodeInfoCollection c, NodeInfo parent, MemberInfo mi, object instance)
|
||||
{
|
||||
// FIXME: there has to be a cleaner way than this...
|
||||
// Don't add node if we don't want to display them.
|
||||
bool quit = false;
|
||||
switch (mi.MemberType) {
|
||||
case MemberTypes.Constructor:
|
||||
quit = !ShowConstructors;
|
||||
break;
|
||||
case MemberTypes.Event:
|
||||
quit = !ShowEvents;
|
||||
break;
|
||||
case MemberTypes.Field:
|
||||
quit = !ShowFields;
|
||||
break;
|
||||
case MemberTypes.Method:
|
||||
quit = !ShowMethods;
|
||||
break;
|
||||
case MemberTypes.Property:
|
||||
quit = !ShowProperties;
|
||||
break;
|
||||
case MemberTypes.TypeInfo:
|
||||
// either a Base type or an Interface
|
||||
// this is bound to produce buggy behavior...
|
||||
quit = !ShowBase && !ShowInterfaces;
|
||||
break;
|
||||
|
||||
// case MemberTypes.NestedType
|
||||
// we don't break out nested types yet
|
||||
}
|
||||
|
||||
if (quit)
|
||||
return;
|
||||
|
||||
if (!seenReflectionObjects.Found (mi)) {
|
||||
seenReflectionObjects.Add (mi);
|
||||
NodeInfo n = new NodeInfo (parent, mi, instance);
|
||||
c.Add (n);
|
||||
}
|
||||
else {
|
||||
NodeInfo n = new NodeInfo (parent, "Seen: " + mi.ToString());
|
||||
n.NodeType = NodeTypes.Alias;
|
||||
c.Add (n);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSubnodes (NodeInfoCollection c, NodeInfo parent, Type type, object instance)
|
||||
{
|
||||
foreach (MemberInfo mi in GetMembers (type)) {
|
||||
AddNode (c, parent, mi, instance);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AddFieldChildren (NodeInfoCollection c, NodeInfo parent, FieldInfo field)
|
||||
{
|
||||
AddSubnodes (c, parent, field.GetType(), field);
|
||||
}
|
||||
|
||||
protected override void AddConstructorChildren (NodeInfoCollection c, NodeInfo parent, ConstructorInfo ctor)
|
||||
{
|
||||
GetMethodBaseChildren (c, parent, ctor);
|
||||
}
|
||||
|
||||
protected override void AddMethodChildren (NodeInfoCollection c, NodeInfo parent, MethodInfo method)
|
||||
{
|
||||
GetMethodBaseChildren (c, parent, method);
|
||||
}
|
||||
|
||||
private void GetMethodBaseChildren (NodeInfoCollection c, NodeInfo parent, MethodBase mb)
|
||||
{
|
||||
AddSubnodes (c, parent, mb.GetType(), mb);
|
||||
}
|
||||
|
||||
protected override void AddParameterChildren (NodeInfoCollection c, NodeInfo parent, ParameterInfo param)
|
||||
{
|
||||
AddSubnodes (c, parent, param.GetType(), param);
|
||||
}
|
||||
|
||||
protected override void AddPropertyChildren (NodeInfoCollection c, NodeInfo parent, PropertyInfo pi)
|
||||
{
|
||||
AddSubnodes (c, parent, pi.GetType(), pi);
|
||||
}
|
||||
|
||||
protected override void AddEventChildren (NodeInfoCollection c, NodeInfo parent, EventInfo e)
|
||||
{
|
||||
AddSubnodes (c, parent, e.GetType(), e);
|
||||
}
|
||||
|
||||
protected override void AddReturnValueChildren (NodeInfoCollection c, NodeInfo parent)
|
||||
{
|
||||
if (parent.ReflectionObject != null)
|
||||
AddTypeChildren (c, parent, (Type) parent.ReflectionObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// CSharpNodeFormatter.cs: Formats nodes with C# syntax
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Formatters
|
||||
{
|
||||
public class CSharpNodeFormatter : LanguageNodeFormatter {
|
||||
|
||||
public CSharpNodeFormatter ()
|
||||
{
|
||||
}
|
||||
|
||||
protected override string LineComment {get {return "//";}}
|
||||
|
||||
protected override string PropertyFormat {get {return "{0} {1} {{{2}{3}}}";}}
|
||||
protected override string PropertyGetFormat {get {return "get{0};";}}
|
||||
protected override string PropertySet {get {return "set;";}}
|
||||
|
||||
protected override string KeywordClass {get {return "class";}}
|
||||
protected override string KeywordEnum {get {return "enum";}}
|
||||
protected override string KeywordValueType {get {return "struct";}}
|
||||
protected override string KeywordInterface {get {return "interface";}}
|
||||
protected override string KeywordInherits {get {return ":";}}
|
||||
protected override string KeywordImplements {get {return ",";}}
|
||||
protected override string KeywordMulticast {get {return "event";}}
|
||||
protected override string KeywordStatementTerminator {get {return ";";}}
|
||||
protected override string KeywordStatementSeparator {get {return ",";}}
|
||||
|
||||
protected override string QualifierPublic {get {return "public";}}
|
||||
protected override string QualifierFamily {get {return "protected";}}
|
||||
protected override string QualifierAssembly {get {return "internal";}}
|
||||
protected override string QualifierFamilyOrAssembly {get {return "protected internal";}}
|
||||
protected override string QualifierPrivate {get {return "private";}}
|
||||
protected override string QualifierFinal {get {return "sealed";}}
|
||||
protected override string QualifierStatic {get {return "static";}}
|
||||
protected override string QualifierLiteral {get {return "const";}}
|
||||
protected override string QualifierAbstract {get {return "abstract";}}
|
||||
protected override string QualifierVirtual {get {return "virtual";}}
|
||||
|
||||
private static readonly string[] attributeDelimeters = new string[]{"[", "]"};
|
||||
|
||||
protected override string[] AttributeDelimeters {
|
||||
get {return attributeDelimeters;}
|
||||
}
|
||||
|
||||
protected override string GetConstructorName (ConstructorInfo ctor)
|
||||
{
|
||||
return ctor.DeclaringType.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
2003-07-03 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* INodeFormatter.cs: It's a Policy now.
|
||||
* NodeFormatter.cs: Cope with changes.
|
||||
|
||||
2003-02-19 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* ChangeLog: Created this file
|
||||
* CSharpNodeFormatter.cs: Added new qualifier property
|
||||
* LanguageNodeFormatter.cs: Added new qualifier property for "family or
|
||||
assembly"
|
||||
* VBNodeFormatter.cs: Added new qualifier property
|
||||
|
||||
2003-01-14 Jonathan Pryor <jonpryor@vt.edu>
|
||||
* Moved the follwing files from the parent directory (part of project re-org)
|
||||
- CSharpNodeFormatter.cs
|
||||
- DefaultNodeFormatter.cs
|
||||
- INodeFormatter.cs
|
||||
- LanguageFormatter.cs
|
||||
- NodeFormatter.cs
|
||||
- VBNodeFormatter.cs
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// DefaultNodeFormatter.cs: Formats NodeInfo instances for display
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Formatters
|
||||
{
|
||||
public class DefaultNodeFormatter : NodeFormatter {
|
||||
|
||||
protected override string GetFieldDescription (FieldInfo field, object instance)
|
||||
{
|
||||
try {
|
||||
return string.Format ("{0}={1}", field.Name,
|
||||
GetValue (field.GetValue(instance)));
|
||||
} catch {
|
||||
return field.Name;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetMethodDescription (MethodInfo mb, object instance)
|
||||
{
|
||||
if (mb.GetParameters().Length == 0) {
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
AddMethodReturnValue (sb, mb.Name + "()={0}", mb, instance);
|
||||
if (sb.Length != 0)
|
||||
return sb.ToString();
|
||||
}
|
||||
return mb.Name;
|
||||
}
|
||||
|
||||
protected override string GetPropertyDescription (PropertyInfo property, object instance)
|
||||
{
|
||||
string v = "";
|
||||
try {
|
||||
// object o = property.GetGetMethod(true).Invoke(instance, null);
|
||||
object o = property.GetValue (instance, null);
|
||||
v = string.Format ("={0}", GetValue (o));
|
||||
} catch {
|
||||
}
|
||||
return string.Format ("{0}{1}", property.Name, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// INodeFormatter.cs: Formats a NodeInfo object for display
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Mono.TypeReflector;
|
||||
|
||||
namespace Mono.TypeReflector.Formatters
|
||||
{
|
||||
public interface INodeFormatter : IPolicy {
|
||||
|
||||
string GetDescription (NodeInfo value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,502 @@
|
|||
//
|
||||
// LanguageNodeFormatter.cs:
|
||||
// Common NodeInfo formatting code for Language-specific output
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Formatters
|
||||
{
|
||||
public abstract class LanguageNodeFormatter : NodeFormatter {
|
||||
|
||||
protected abstract string LineComment {get;}
|
||||
|
||||
// [0] is open, [1] is close
|
||||
protected abstract string[] AttributeDelimeters {get;}
|
||||
|
||||
// Format for Property descriptions generated by GetPropertyDescription
|
||||
// {0}: Property Type
|
||||
// {1}: Property Name
|
||||
// {2}: The Get Accessor. This will be generated from PropertyGetFormat,
|
||||
// if appropriate.
|
||||
// {3}: The Set Accessor. This will be generated from PropertySet, if
|
||||
// appropriate
|
||||
protected abstract string PropertyFormat {get;}
|
||||
|
||||
// Format for the `get' property accessor
|
||||
// {0}: The return value of the property, if present
|
||||
protected abstract string PropertyGetFormat {get;}
|
||||
|
||||
protected abstract string PropertySet {get;}
|
||||
|
||||
protected abstract string KeywordClass {get;}
|
||||
protected abstract string KeywordEnum {get;}
|
||||
protected abstract string KeywordValueType {get;}
|
||||
protected abstract string KeywordInterface {get;}
|
||||
protected abstract string KeywordInherits {get;}
|
||||
protected abstract string KeywordImplements {get;}
|
||||
protected abstract string KeywordMulticast {get;}
|
||||
protected abstract string KeywordStatementTerminator {get;}
|
||||
protected abstract string KeywordStatementSeparator {get;}
|
||||
|
||||
protected abstract string QualifierPublic {get;}
|
||||
protected abstract string QualifierFamily {get;}
|
||||
protected abstract string QualifierAssembly {get;}
|
||||
protected abstract string QualifierFamilyOrAssembly {get;}
|
||||
protected abstract string QualifierPrivate {get;}
|
||||
protected abstract string QualifierStatic {get;}
|
||||
protected abstract string QualifierFinal {get;}
|
||||
protected abstract string QualifierAbstract {get;}
|
||||
protected abstract string QualifierVirtual {get;}
|
||||
protected abstract string QualifierLiteral {get;}
|
||||
|
||||
protected override string GetTypeDescription (Type type, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
AddAttributes (sb, type);
|
||||
AddTypeQualifiers (sb, type);
|
||||
sb.AppendFormat ("{0} {1}", GetTypeKeyword(type), type.FullName);
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
protected void AddAttribute (StringBuilder sb, string attribute)
|
||||
{
|
||||
sb.AppendFormat ("{0}{1}{2}",
|
||||
AttributeDelimeters[0], attribute, AttributeDelimeters[1]);
|
||||
}
|
||||
|
||||
protected void AddAttributes (StringBuilder sb, MemberInfo m)
|
||||
{
|
||||
AddAttributes (sb, m, true);
|
||||
}
|
||||
|
||||
protected void AddAttributes (StringBuilder sb, MemberInfo m, bool newline)
|
||||
{
|
||||
AddCilAttributes (sb, m, newline);
|
||||
AddCustomAttributes (sb, m, "", newline);
|
||||
}
|
||||
|
||||
private void AddCilAttributes (StringBuilder sb, MemberInfo m, bool newline)
|
||||
{
|
||||
Type t = m as Type;
|
||||
MethodBase mb = m as MethodBase;
|
||||
if (t != null)
|
||||
AddCilAttributes (sb, t, newline);
|
||||
else if (mb != null)
|
||||
AddCilAttributes (sb, mb, newline);
|
||||
}
|
||||
|
||||
private void AddCilAttributes (StringBuilder sb, Type t, bool newline)
|
||||
{
|
||||
if (t.IsSerializable) {
|
||||
AddAttribute (sb, "Serializable");
|
||||
if (newline)
|
||||
sb.Append ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void AddCilAttributes (StringBuilder sb, MethodBase m, bool newline)
|
||||
{
|
||||
MethodImplAttributes attr = m.GetMethodImplementationFlags ();
|
||||
if ((attr & MethodImplAttributes.InternalCall) != 0) {
|
||||
AddAttribute (sb, "MethodImplAttribute(MethodImplOptions.InternalCall)");
|
||||
if (newline)
|
||||
sb.Append ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
protected void AddTypeQualifiers (StringBuilder sb, Type type)
|
||||
{
|
||||
if (type.IsPublic)
|
||||
sb.Append (QualifierPublic + " ");
|
||||
if (type.IsSealed && !type.IsValueType)
|
||||
sb.Append (QualifierFinal + " ");
|
||||
if (type.IsAbstract && !type.IsInterface)
|
||||
sb.Append (QualifierAbstract + " ");
|
||||
}
|
||||
|
||||
new protected string GetTypeKeyword (Type type)
|
||||
{
|
||||
if (type.IsClass)
|
||||
return KeywordClass;
|
||||
if (type.IsEnum)
|
||||
return KeywordEnum;
|
||||
if (type.IsValueType)
|
||||
return KeywordValueType;
|
||||
if (type.IsInterface)
|
||||
return KeywordInterface;
|
||||
|
||||
// unknown type
|
||||
return "type";
|
||||
}
|
||||
|
||||
protected override string GetBaseTypeDescription (Type type, object instance)
|
||||
{
|
||||
if (type != null)
|
||||
return string.Format ("{0} {1}", KeywordInherits, type.Name);
|
||||
return string.Format ("{0} No Base Type", LineComment);
|
||||
}
|
||||
|
||||
protected override string GetInterfaceDescription (Type type, object instance)
|
||||
{
|
||||
return string.Format ("{0} {1}", KeywordImplements, type.Name);
|
||||
}
|
||||
|
||||
protected override string GetConstructorDescription (ConstructorInfo ctor, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
AddAttributes (sb, ctor);
|
||||
AddMethodQualifiers (sb, ctor);
|
||||
sb.AppendFormat ("{0} ", GetConstructorName (ctor));
|
||||
AddMethodArgs (sb, ctor);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected void AddMethodQualifiers (StringBuilder sb, MethodBase m)
|
||||
{
|
||||
if (m.IsPublic)
|
||||
sb.AppendFormat ("{0} ", QualifierPublic);
|
||||
if (m.IsFamily)
|
||||
sb.AppendFormat ("{0} ", QualifierFamily);
|
||||
if (m.IsAssembly)
|
||||
sb.AppendFormat ("{0} ", QualifierAssembly);
|
||||
if (m.IsFamilyOrAssembly)
|
||||
sb.AppendFormat ("{0} ", QualifierFamilyOrAssembly);
|
||||
if (m.IsPrivate)
|
||||
sb.AppendFormat ("{0} ", QualifierPrivate);
|
||||
if (m.IsStatic)
|
||||
sb.AppendFormat ("{0} ", QualifierStatic);
|
||||
if (m.IsFinal)
|
||||
sb.AppendFormat ("{0} ", QualifierFinal);
|
||||
if (m.IsAbstract)
|
||||
sb.AppendFormat ("{0} ", QualifierAbstract);
|
||||
else if (m.IsVirtual)
|
||||
sb.AppendFormat ("{0} ", QualifierVirtual);
|
||||
}
|
||||
|
||||
protected abstract string GetConstructorName (ConstructorInfo ctor);
|
||||
|
||||
protected void AddMethodArgs (StringBuilder sb, MethodBase m)
|
||||
{
|
||||
sb.Append ("(");
|
||||
ParameterInfo[] parms = m.GetParameters ();
|
||||
if (parms.Length != 0) {
|
||||
int cur = 0;
|
||||
foreach (ParameterInfo pi in parms) {
|
||||
sb.Append (GetParameterDescription (pi, pi));
|
||||
if (cur++ != (parms.Length-1))
|
||||
sb.Append (", ");
|
||||
}
|
||||
}
|
||||
sb.Append (")");
|
||||
}
|
||||
|
||||
protected override string GetEventDescription (EventInfo e, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
AddMethodQualifiers (sb, e.GetAddMethod(true));
|
||||
return string.Format ("{0}{1}{2} {3}",
|
||||
sb.ToString (),
|
||||
e.IsMulticast ? KeywordMulticast + " " : "",
|
||||
e.EventHandlerType,
|
||||
e.Name);
|
||||
}
|
||||
|
||||
protected override string GetFieldDescription (FieldInfo field, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
AddAttributes (sb, field);
|
||||
|
||||
if (!field.DeclaringType.IsEnum || field.IsSpecialName) {
|
||||
AddFieldQualifiers (sb, field);
|
||||
sb.AppendFormat ("{0} ", field.FieldType);
|
||||
}
|
||||
|
||||
sb.Append (field.Name);
|
||||
|
||||
try {
|
||||
sb.AppendFormat (" = {0}", GetValue (field.GetValue (instance)));
|
||||
}
|
||||
catch {
|
||||
}
|
||||
|
||||
if (!field.DeclaringType.IsEnum || field.IsSpecialName)
|
||||
sb.Append (KeywordStatementTerminator);
|
||||
else
|
||||
sb.Append (KeywordStatementSeparator);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected void AddFieldQualifiers (StringBuilder sb, FieldInfo field)
|
||||
{
|
||||
if (field.IsPublic)
|
||||
sb.AppendFormat ("{0} ", QualifierPublic);
|
||||
if (field.IsPrivate)
|
||||
sb.AppendFormat ("{0} ", QualifierPrivate);
|
||||
if (field.IsAssembly)
|
||||
sb.AppendFormat ("{0} ", QualifierAssembly);
|
||||
if (field.IsFamily)
|
||||
sb.AppendFormat ("{0} ", QualifierFamily);
|
||||
if (field.IsLiteral)
|
||||
sb.AppendFormat ("{0} ", QualifierLiteral);
|
||||
else if (field.IsStatic)
|
||||
sb.AppendFormat ("{0} ", QualifierStatic);
|
||||
}
|
||||
|
||||
protected override string GetMethodDescription (MethodInfo method, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
|
||||
if (method.IsSpecialName)
|
||||
sb.AppendFormat ("{0} Method is a specially named method:\n", LineComment);
|
||||
|
||||
AddAttributes (sb, method);
|
||||
if (method.ReturnTypeCustomAttributes != null)
|
||||
AddCustomAttributes (sb, method.ReturnTypeCustomAttributes, "return: ", true);
|
||||
|
||||
AddMethodQualifiers (sb, method);
|
||||
|
||||
AddMethodDeclaration (sb, method);
|
||||
|
||||
AddMethodReturnValue (sb, " " + LineComment + " = {0}", method, instance);
|
||||
|
||||
string str = sb.ToString();
|
||||
|
||||
if (method.IsSpecialName)
|
||||
return str.Replace ("\n", "\n" + LineComment + "\t");
|
||||
return str;
|
||||
}
|
||||
|
||||
protected virtual void AddMethodDeclaration (StringBuilder sb, MethodInfo method)
|
||||
{
|
||||
sb.AppendFormat ("{0} {1} ", method.ReturnType, method.Name);
|
||||
|
||||
AddMethodArgs (sb, method);
|
||||
}
|
||||
|
||||
protected override string GetParameterDescription (ParameterInfo param, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
|
||||
AddCustomAttributes (sb, param, "", false);
|
||||
AddParameterAttributes (sb, param.Attributes);
|
||||
|
||||
sb.AppendFormat ("{0} {1}", param.ParameterType, param.Name);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected void AddParameterAttributes (StringBuilder sb, ParameterAttributes attrs)
|
||||
{
|
||||
if ((attrs & ParameterAttributes.In) != 0)
|
||||
sb.Append ("in");
|
||||
if ((attrs & ParameterAttributes.Out) != 0)
|
||||
sb.Append ("out");
|
||||
if ((attrs & ParameterAttributes.Lcid) != 0)
|
||||
sb.Append ("lcid");
|
||||
if ((attrs & ParameterAttributes.Retval) != 0)
|
||||
sb.Append ("retval");
|
||||
if ((attrs & ParameterAttributes.Optional) != 0)
|
||||
sb.Append ("optional");
|
||||
if ((attrs & ParameterAttributes.HasDefault) != 0)
|
||||
sb.Append ("hasdefault");
|
||||
if ((attrs & ParameterAttributes.HasFieldMarshal) != 0)
|
||||
sb.Append ("hasfieldmarshal");
|
||||
if ((attrs & ParameterAttributes.ReservedMask) != 0)
|
||||
sb.Append ("reservedmask");
|
||||
if ((attrs & ParameterAttributes.Reserved3) != 0)
|
||||
sb.Append ("reserved3");
|
||||
if ((attrs & ParameterAttributes.Reserved4) != 0)
|
||||
sb.Append ("reserved4");
|
||||
}
|
||||
|
||||
protected override string GetPropertyDescription (PropertyInfo property, object instance)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
AddAttributes (sb, property);
|
||||
AddMethodQualifiers (sb, property.GetAccessors(true)[0]);
|
||||
|
||||
string getter = null;
|
||||
if (property.CanRead) {
|
||||
string v = null;
|
||||
try {
|
||||
v = string.Format (" /* = {0} */", GetValue (property.GetValue (instance, null)));
|
||||
}
|
||||
catch {
|
||||
}
|
||||
getter = string.Format (PropertyGetFormat, v);
|
||||
}
|
||||
|
||||
string setter = null;
|
||||
if (property.CanWrite)
|
||||
setter = PropertySet;
|
||||
|
||||
sb.AppendFormat (PropertyFormat, property.PropertyType, property.Name, getter, setter);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected override string GetReturnValueDescription (NodeInfo n)
|
||||
{
|
||||
return string.Format ("{0} ReturnValue={1}",
|
||||
LineComment, GetOtherDescription (n));
|
||||
}
|
||||
|
||||
protected override string GetOtherDescription (NodeInfo node)
|
||||
{
|
||||
if (node.Description != null)
|
||||
return node.Description.ToString();
|
||||
return "<null other description/>";
|
||||
}
|
||||
|
||||
protected void AddCustomAttributes (StringBuilder sb, ICustomAttributeProvider m, string attributeType, bool newLine)
|
||||
{
|
||||
object[] attrs = m.GetCustomAttributes (true);
|
||||
|
||||
foreach (object a in attrs) {
|
||||
|
||||
AddCustomAttribute (sb, a, attributeType);
|
||||
|
||||
if (newLine)
|
||||
sb.Append ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddCustomAttribute (StringBuilder sb, object attribute, string attributeType)
|
||||
{
|
||||
Type type = attribute.GetType();
|
||||
sb.AppendFormat ("{0}{1}{2}", AttributeDelimeters[0], attributeType, type.FullName);
|
||||
|
||||
PropertyInfo[] props = type.GetProperties();
|
||||
FieldInfo[] fields = type.GetFields();
|
||||
|
||||
if (props.Length > 0 || fields.Length > 0) {
|
||||
sb.Append ("(");
|
||||
if (props.Length > 0) {
|
||||
AddPropertyValues (sb, props, attribute);
|
||||
if (fields.Length > 0)
|
||||
sb.Append (", ");
|
||||
}
|
||||
if (fields.Length > 0)
|
||||
AddFieldValues (sb, fields, attribute);
|
||||
sb.Append (")");
|
||||
}
|
||||
sb.Append (AttributeDelimeters[1]);
|
||||
}
|
||||
|
||||
private void AddPropertyValues (StringBuilder sb, PropertyInfo[] props, object instance)
|
||||
{
|
||||
int len = props.Length;
|
||||
for (int i = 0; i != len; ++i) {
|
||||
sb.Append (props[i].Name);
|
||||
sb.Append ("=");
|
||||
try {
|
||||
sb.Append (GetEncodedValue (props[i].GetValue (instance, null)));
|
||||
} catch {
|
||||
sb.Append ("<exception/>");
|
||||
}
|
||||
if (i != (len-1))
|
||||
sb.Append (", ");
|
||||
}
|
||||
}
|
||||
|
||||
private void AddFieldValues (StringBuilder sb, FieldInfo[] fields, object instance)
|
||||
{
|
||||
int len = fields.Length;
|
||||
for (int i = 0; i != len; ++i) {
|
||||
sb.Append (fields[i].Name);
|
||||
sb.Append ("=");
|
||||
sb.Append (GetEncodedValue (fields[i].GetValue (instance)));
|
||||
if (i != (len-1))
|
||||
sb.Append (", ");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedValue (object value)
|
||||
{
|
||||
if (value == null)
|
||||
return "null";
|
||||
|
||||
switch (Type.GetTypeCode(value.GetType())) {
|
||||
case TypeCode.Char:
|
||||
return GetEncodedCharValue (value);
|
||||
case TypeCode.Decimal:
|
||||
return GetEncodedDecimalValue (value);
|
||||
case TypeCode.Double:
|
||||
return GetEncodedDoubleValue (value);
|
||||
case TypeCode.Int64:
|
||||
return GetEncodedInt64Value (value);
|
||||
case TypeCode.Single:
|
||||
return GetEncodedSingleValue (value);
|
||||
case TypeCode.String:
|
||||
return GetEncodedStringValue (value);
|
||||
case TypeCode.UInt32:
|
||||
return GetEncodedUInt32Value (value);
|
||||
case TypeCode.UInt64:
|
||||
return GetEncodedUInt64Value (value);
|
||||
case TypeCode.Object:
|
||||
return GetEncodedObjectValue (value);
|
||||
}
|
||||
// not special-cased; just return it's value
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedCharValue (object value)
|
||||
{
|
||||
return String.Format ("'{0}'", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedDecimalValue (object value)
|
||||
{
|
||||
return String.Format ("{0}m", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedDoubleValue (object value)
|
||||
{
|
||||
return String.Format ("{0}d", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedInt64Value (object value)
|
||||
{
|
||||
return String.Format ("{0}L", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedSingleValue (object value)
|
||||
{
|
||||
return String.Format ("{0}f", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedStringValue (object value)
|
||||
{
|
||||
return String.Format ("\"{0}\"", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedUInt32Value (object value)
|
||||
{
|
||||
return String.Format ("{0}U", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedUInt64Value (object value)
|
||||
{
|
||||
return String.Format ("{0}UL", value.ToString());
|
||||
}
|
||||
|
||||
protected virtual string GetEncodedObjectValue (object value)
|
||||
{
|
||||
return String.Format ("typeof({0})", value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
//
|
||||
// NodeFormatter.cs: Formats NodeInfo instances for display
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002-2003 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Formatters
|
||||
{
|
||||
public class NodeFormatter : Policy, INodeFormatter {
|
||||
|
||||
private bool invokeMethods = false;
|
||||
|
||||
public bool InvokeMethods {
|
||||
get {return invokeMethods;}
|
||||
set {invokeMethods = value;}
|
||||
}
|
||||
|
||||
public string GetDescription (NodeInfo node)
|
||||
{
|
||||
string r = "";
|
||||
switch (node.NodeType) {
|
||||
case NodeTypes.Type:
|
||||
r = GetTypeDescription ((Type)node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.BaseType:
|
||||
r = GetBaseTypeDescription ((Type)node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Interface:
|
||||
r = GetInterfaceDescription ((Type)node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Field:
|
||||
r = GetFieldDescription ((FieldInfo)node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Constructor:
|
||||
r = GetConstructorDescription ((ConstructorInfo)node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Method:
|
||||
r = GetMethodDescription ((MethodInfo) node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Parameter:
|
||||
r = GetParameterDescription ((ParameterInfo) node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Property:
|
||||
r = GetPropertyDescription ((PropertyInfo) node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
case NodeTypes.Event:
|
||||
r = GetEventDescription ((EventInfo) node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
/*
|
||||
case NodeTypes.CustomAttributeProvider:
|
||||
r = GetCustomAttributeProviderDescription ((ICustomAttributeProvider) node.ReflectionObject, node.ReflectionInstance);
|
||||
break;
|
||||
*/
|
||||
case NodeTypes.Other:
|
||||
case NodeTypes.Alias:
|
||||
r = GetOtherDescription (node);
|
||||
break;
|
||||
case NodeTypes.ReturnValue:
|
||||
r = GetReturnValueDescription (node);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert (false,
|
||||
String.Format ("Unhandled NodeInfo value: {0}", node.NodeType));
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static string GetValue (object o)
|
||||
{
|
||||
if (o == null)
|
||||
return "null";
|
||||
if (o.GetType().IsEnum)
|
||||
return GetEnumValue (o.GetType(), o);
|
||||
return o.ToString();
|
||||
}
|
||||
|
||||
public static string GetEnumValue (Type enumType, object value)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
sb.Append (Enum.Format(enumType, value, "f"));
|
||||
sb.Append (" (");
|
||||
sb.Append (String.Format ("0x{0}", Enum.Format (enumType, value, "x")));
|
||||
sb.Append (")");
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
public static string GetTypeKeyword (Type type)
|
||||
{
|
||||
string t = null;
|
||||
|
||||
if (type.IsClass)
|
||||
t = "class";
|
||||
else if (type.IsEnum)
|
||||
t = "enum";
|
||||
else if (type.IsValueType)
|
||||
t = "struct";
|
||||
else if (type.IsInterface)
|
||||
t = "interface";
|
||||
else
|
||||
t = "type";
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
protected virtual string GetTypeDescription (Type type, object instance)
|
||||
{
|
||||
return string.Format ("{0} {1}",
|
||||
GetTypeKeyword(type), type.FullName);
|
||||
}
|
||||
|
||||
protected virtual string GetBaseTypeDescription (Type type, object instance)
|
||||
{
|
||||
if (type != null)
|
||||
return type.Name;
|
||||
return "No Base Type";
|
||||
}
|
||||
|
||||
protected virtual string GetInterfaceDescription (Type type, object instance)
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
|
||||
protected virtual string GetConstructorDescription (ConstructorInfo ctor, object instance)
|
||||
{
|
||||
return ctor.Name;
|
||||
}
|
||||
|
||||
protected virtual string GetEventDescription (EventInfo e, object instance)
|
||||
{
|
||||
return e.Name;
|
||||
}
|
||||
|
||||
protected virtual string GetFieldDescription (FieldInfo field, object instance)
|
||||
{
|
||||
return field.Name;
|
||||
}
|
||||
|
||||
protected virtual string GetMethodDescription (MethodInfo method, object instance)
|
||||
{
|
||||
return method.Name;
|
||||
}
|
||||
|
||||
protected void AddMethodReturnValue (StringBuilder sb, string format, MethodInfo method, object instance)
|
||||
{
|
||||
// Only invoke the function if:
|
||||
// 1. Function has no parameters
|
||||
// - AND -
|
||||
// 2. It's a static function
|
||||
// - OR -
|
||||
// 3. We have a `this' pointer for the instance function
|
||||
|
||||
bool is_static = method.IsStatic;
|
||||
bool have_instance = instance != null;
|
||||
|
||||
if (InvokeMethods && method.GetParameters().Length == 0 && (is_static || have_instance)) {
|
||||
try {
|
||||
object r = method.Invoke (instance, null);
|
||||
string s = GetValue (r);
|
||||
sb.AppendFormat (format, s);
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual string GetParameterDescription (ParameterInfo param, object instance)
|
||||
{
|
||||
return param.Name;
|
||||
}
|
||||
|
||||
protected virtual string GetPropertyDescription (PropertyInfo property, object instance)
|
||||
{
|
||||
return property.Name;
|
||||
}
|
||||
|
||||
protected virtual string GetOtherDescription (NodeInfo node)
|
||||
{
|
||||
if (node.Description != null)
|
||||
return node.Description.ToString();
|
||||
return string.Format (
|
||||
"(** Error: Invalid NodeInfo.Description or unhandled type; " +
|
||||
"NodeType={0}, ReflectionObject={1}, " +
|
||||
"ReflectionInstance={2}}}\n{3})",
|
||||
node.NodeType,
|
||||
node.ReflectionObject,
|
||||
node.ReflectionInstance,
|
||||
new StackTrace());
|
||||
}
|
||||
|
||||
protected virtual string GetReturnValueDescription (NodeInfo node)
|
||||
{
|
||||
return "ReturnValue=" + GetOtherDescription (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// VBNodeFormatter.cs: Formats nodes with VB.NET syntax
|
||||
//
|
||||
// Author: Jonathan Pryor (jonpryor@vt.edu)
|
||||
//
|
||||
// (C) 2002 Jonathan Pryor
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mono.TypeReflector.Formatters
|
||||
{
|
||||
public class VBNodeFormatter : LanguageNodeFormatter {
|
||||
|
||||
public VBNodeFormatter ()
|
||||
{
|
||||
}
|
||||
|
||||
protected override string LineComment {get {return "'";}}
|
||||
|
||||
protected override string PropertyFormat {get {return "Property {1} As {0}\n{2}{3}End Property";}}
|
||||
protected override string PropertyGetFormat {get {return "\tGet\n\t\t' Return {0}\n\tEnd Get\n";}}
|
||||
protected override string PropertySet {get {return "\tSet\n\tEnd Set\n";}}
|
||||
|
||||
protected override string KeywordClass {get {return "Class";}}
|
||||
protected override string KeywordEnum {get {return "Enum";}}
|
||||
protected override string KeywordValueType {get {return "Struct";}}
|
||||
protected override string KeywordInterface {get {return "Interface";}}
|
||||
protected override string KeywordInherits {get {return "Inherits";}}
|
||||
protected override string KeywordImplements {get {return "Implements";}}
|
||||
protected override string KeywordMulticast {get {return "Event";}}
|
||||
protected override string KeywordStatementTerminator {get {return "";}}
|
||||
protected override string KeywordStatementSeparator {get {return ",";}}
|
||||
|
||||
protected override string QualifierPublic {get {return "Public";}}
|
||||
protected override string QualifierFamily {get {return "Family";}}
|
||||
protected override string QualifierAssembly {get {return "Internal";}}
|
||||
protected override string QualifierFamilyOrAssembly {get {return "Internal Family";}}
|
||||
protected override string QualifierPrivate {get {return "Private";}}
|
||||
protected override string QualifierFinal {get {return "Final";}}
|
||||
protected override string QualifierStatic {get {return "Shared";}}
|
||||
protected override string QualifierLiteral {get {return "Const";}}
|
||||
protected override string QualifierAbstract {get {return "Abstract";}}
|
||||
protected override string QualifierVirtual {get {return "Overridable";}}
|
||||
|
||||
private static readonly string[] attributeDelimeters = new string[]{"<", ">"};
|
||||
|
||||
protected override string[] AttributeDelimeters {
|
||||
get {return attributeDelimeters;}
|
||||
}
|
||||
|
||||
protected override string GetConstructorName (ConstructorInfo ctor)
|
||||
{
|
||||
return "Sub New";
|
||||
}
|
||||
|
||||
protected override void AddMethodDeclaration (StringBuilder sb, MethodInfo method)
|
||||
{
|
||||
string type = "Function";
|
||||
|
||||
bool sub = method.ReturnType == typeof (void);
|
||||
|
||||
if (sub) {
|
||||
type = "Sub";
|
||||
}
|
||||
|
||||
sb.AppendFormat ("{0} {1}", type, method.Name);
|
||||
AddMethodArgs (sb, method);
|
||||
|
||||
if (!sub)
|
||||
sb.AppendFormat (" As {0}", method.ReturnType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
# Starts a CIL program whose name is patterned after the filename of this
|
||||
# script. The CIL program executed is "$0".exe.
|
||||
|
||||
file="$0"
|
||||
|
||||
# If file is a symlink, find where it's pointing to
|
||||
if [ -L "$file" ] ; then
|
||||
if ! (readlink -f "$file") > /dev/null 2>&1; then
|
||||
echo `basename "$0"` ": missing required program readlink!"
|
||||
exit -1
|
||||
fi
|
||||
file=`readlink -f "$file"`
|
||||
fi
|
||||
|
||||
exec mono "$file.exe" "$@"
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="type-reflector" default="linux">
|
||||
<target name="linux">
|
||||
<csc target="exe" output="./type-reflector.exe" debug="true">
|
||||
<sources>
|
||||
<includes name="*.cs" />
|
||||
</sources>
|
||||
</csc>
|
||||
</target>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section
|
||||
name="displayers"
|
||||
type="System.Configuration.DictionarySectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<section
|
||||
name="finders"
|
||||
type="System.Configuration.DictionarySectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<section
|
||||
name="formatters"
|
||||
type="System.Configuration.DictionarySectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
</configSections>
|
||||
<system.diagnostics>
|
||||
<switches>
|
||||
<add name="console" value="1"/>
|
||||
<add name="explicit-node-finder" value="0"/>
|
||||
<add name="grouping-node-finder" value="0"/>
|
||||
<add name="indenting-text-writer" value="0"/>
|
||||
<add name="indenter" value="0"/>
|
||||
<add name="node-finder" value="0"/>
|
||||
<add name="type-loader" value="0"/>
|
||||
<add name="type-factory" value="1"/>
|
||||
<add name="gtk-displayer" value="4"/>
|
||||
</switches>
|
||||
<!--
|
||||
<trace>
|
||||
<listeners>
|
||||
<add
|
||||
name="debug-txt-writer"
|
||||
type="System.Diagnostics.TextWriterTraceListener, System"
|
||||
initializeData="debug.txt"/>
|
||||
</listeners>
|
||||
</trace>
|
||||
<assert assertuienabled="false" logfilename="debug-messages.txt"/>
|
||||
-->
|
||||
</system.diagnostics>
|
||||
<displayers>
|
||||
<add key="console:Console"
|
||||
value="Mono.TypeReflector.Displayers.ConsoleTypeDisplayer" />
|
||||
<add key="gtk:Gtk#"
|
||||
value="Mono.TypeReflector.Displayers.gtk.GtkTypeDisplayer" />
|
||||
<add key="swf:Windows Forms"
|
||||
value="Mono.TypeReflector.Displayers.Swf.SwfTypeDisplayer" />
|
||||
</displayers>
|
||||
<finders>
|
||||
<add key="explicit"
|
||||
value="Mono.TypeReflector.Finders.ExplicitNodeFinder" />
|
||||
<add key="reflection"
|
||||
value="Mono.TypeReflector.Finders.ReflectionNodeFinder" />
|
||||
</finders>
|
||||
<formatters>
|
||||
<add key="default:Reflection"
|
||||
value="Mono.TypeReflector.Formatters.DefaultNodeFormatter" />
|
||||
<add key="csharp:C#"
|
||||
value="Mono.TypeReflector.Formatters.CSharpNodeFormatter" />
|
||||
<add key="vb:Visual Basic"
|
||||
value="Mono.TypeReflector.Formatters.VBNodeFormatter" />
|
||||
</formatters>
|
||||
<appSettings>
|
||||
<!--
|
||||
Sort of hackish...
|
||||
Specify the order that displayers should be loaded. This would
|
||||
permit a default displayer other than the console.
|
||||
-->
|
||||
<add key="displayer-order" value="gtk swf console" />
|
||||
</appSettings>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
PREFIX=@PREFIX@
|
||||
exec mono "$PREFIX/share/type-reflector/type-reflector.exe" "$@"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
-o type-reflector.exe
|
||||
ConsoleOutput.cs
|
||||
CSharpTypeDisplayer.cs
|
||||
ExplicitTypeDisplayer.cs
|
||||
IndentingTextWriter.cs
|
||||
IndentingTypeDisplayer.cs
|
||||
ProgramOptions.cs
|
||||
ReflectionTypeDisplayer.cs
|
||||
TestTypes.cs
|
||||
TextFormatter.cs
|
||||
TypeDisplayer.cs
|
||||
TypeDisplayerFactory.cs
|
||||
TypeLoader.cs
|
||||
TypeReflectorOptions.cs
|