svn path=/old-code/; revision=157322
This commit is contained in:
Miguel de Icaza 2010-05-13 21:00:39 +00:00
Родитель 780148ada6
Коммит 30e96e3731
67 изменённых файлов: 9128 добавлений и 0 удалений

Просмотреть файл

@ -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("")]

24
type-reflector/COPYRIGHT Normal file
Просмотреть файл

@ -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.

422
type-reflector/ChangeLog Normal file
Просмотреть файл

@ -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

121
type-reflector/DESIGN Normal file
Просмотреть файл

@ -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 ();
}
}

20
type-reflector/IPolicy.cs Normal file
Просмотреть файл

@ -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;}
}
}

24
type-reflector/LICENSE Normal file
Просмотреть файл

@ -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.

240
type-reflector/Makefile Normal file
Просмотреть файл

@ -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

83
type-reflector/Node.cs Normal file
Просмотреть файл

@ -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;
}
}
}

177
type-reflector/NodeInfo.cs Normal file
Просмотреть файл

@ -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
}
}

41
type-reflector/Policy.cs Normal file
Просмотреть файл

@ -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');}
}
}
}

128
type-reflector/README Normal file
Просмотреть файл

@ -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 .

16
type-reflector/TODO Normal file
Просмотреть файл

@ -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. :-(

168
type-reflector/TestTypes.cs Normal file
Просмотреть файл

@ -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);
}
}
}

Двоичные данные
type-reflector/displayers/art/abstract.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 517 B

Двоичные данные
type-reflector/displayers/art/class.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 517 B

Двоичные данные
type-reflector/displayers/art/constructor.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 585 B

Двоичные данные
type-reflector/displayers/art/enum.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 284 B

Двоичные данные
type-reflector/displayers/art/event.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 651 B

Двоичные данные
type-reflector/displayers/art/field.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 332 B

Двоичные данные
type-reflector/displayers/art/interface.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 708 B

Двоичные данные
type-reflector/displayers/art/method.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 461 B

Двоичные данные
type-reflector/displayers/art/prop-read-only.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 344 B

Двоичные данные
type-reflector/displayers/art/prop-read-write.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 348 B

Двоичные данные
type-reflector/displayers/art/prop-write-only.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 350 B

Двоичные данные
type-reflector/displayers/art/sealed.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 516 B

Двоичные данные
type-reflector/displayers/art/transparent.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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);
}
}
}

17
type-reflector/type-reflector Executable file
Просмотреть файл

@ -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" "$@"

14
type-reflector/unix.args Normal file
Просмотреть файл

@ -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