tfpt review "/shelveset:MethodBinder23;REDMOND\tomat"
------------
Ruby changes
------------
This change significantly affects Ruby method definitions in C# libraries:
1) CodeContext hidden parameter is replaced with RubyScope or RubyContext hidden
parameters depending on what the method needs.
CodeContext is still supported but will eventually be dropped. Methods
shouldn''t use any special parameters if they don''t need to.
Methods should use RubyContext if they only need to get the current runtime
context (note that you can get to the runtime context also from non-null
BlockParam, RubyClass, RubyModule, and other runtime-bound Ruby objects).
Currently we have 2 contexts: RubyExecutionContext and RubyContext.
RubyExecutionContext is going to be merged into RubyContext soon. For now you
can get it from RubyContext using ExecutionContext property. Methods that need
to access the current scope or need to call a dynamic site need RubyScope.
RubyScope holds on RubyContext/RubyExecutionContext so it is not necessary for a
method to take both RubyScope and RubyContext parameters. In future dynamic
sites will be passed in a special hidden parameter(s).
2) The shelveset introduces DefaultProtocol attribute that can be applied on
parameters of type MutableString and Int32 (more types will be supported in
future). This feature removes the need to explicitly call Protocols.CastToString
and Protocols.CastToFixnum as the binder performs the conversions for you. The
only method that uses the attribute so far is String#center. However, most of
the methods that use CastToString/Fixnum will be switched to DefaultProtocol
eventually.
3) BlockParam parameter now precedes self parameter and [NotNull] attribute is
used for overload resolution if applied on BlockParam. A method that
doesn''t include BlockParam can still be called with a block. The block
is ignored in this case.
If the method overload doesn''t have a BlockParam parameter, we inject
MissingBlockParam parameter and arg builder.
The parameter is treated as a regular explicit mandatory parameter.
The argument builder provides no value for the actual argument expression, which
makes the default binder to skip it
when emitting a tree for the actual method call (this is necessary since the
method doesn''t in fact have the parameter).
By injecting the missing block parameter we achieve that all overloads have
either BlockParam, [NotNull]BlockParam or
MissingBlockParam parameter. MissingBlockParam (MBP) and BlockParam (BP) are
convertible to each other. Default binder prefers
those overloads where no conversion needs to happen, which ensures the desired
semantics:
Conversions with desired priority (the less number the higher priority):
Parameters: call w/o block call with non-null block
call with null block
(implicit, MBP, ... ) MBP -> MBP (1) BP -> MBP (3)
BP -> MBP (2)
(implicit, BP, ... ) MBP -> BP (2) BP -> BP (2)
BP -> BP (1)
(implicit, BP!, ... ) N/A BP -> BP! (1)
N/A
4) Methods designated by RubyConstructor attribute must have RubyClass self
parameter. The class object being instantiated is passed in it.
5) A RubyConstant attribute can now be applied on a method. The method is
called during class initialization to produce the value of the constant.
Many library methods were adjusted to match the binder changes.
Adds more checks to class-init generator to enforce correct method signatures.
Also adds library data dictionary to RubyContext - libraries can add objects to
the dictionary that should be associated with the context.
Fixes bugs in Struct:
- Struct defines a singleton method "new" that is used to create new
structures (classes).
- If Singleton(Struct)#new method is removed, Class#new is invoked instead,
which raises missing allocator error.
- A class created by Singleton(Struct)#new is a structure class that defines
accessors specified in struct constructor and its singleton class defines
"[]", "members" and "new" methods. "new"
create an instance of the structure given values for the struct''s
attributes.
- Structures can be derived from and duplicated.
-----------
DLR changes
-----------
Renames MethodBinderContext to ParameterBinder and removes a dependency on
CodeContext from it. A subclass of ParameterBinder,
ParameterBinderWithCodeContext adds CodeContext expression to ParameterBinder.
The idea is that this class will eventually move to Python and become
PythonParameterBinder and the default binder won''t depend on
CodeContext. Methods on ActionBinder that deal with parameters could also be
moved to ParameterBinder then (e.g. GetByRefArrayExpression,
ParametersEquivalent, CanConvertFrom, BindSpecialArgument,
PrepareArgumentBinding). These methods cannot be moved now since the parameter
binder is not flown to all places where it would be needed. Adds
RubyParameterBinder which implements custom parameter conversions for Ruby
library methods.
Adds more methods to ActionBinder (should move on ParameterBinder in future):
- PrepareArgumentBinding, BindSpecialArgument - used in MethodBinder when
the method candidates are built up. These extension points enable to preprocess
parameter infos and produce language specific ParameterWrappers and ArgBuilders
and skip initial language specific hidden arguments. Ruby uses this to process
hidden arguments of types RubyScope, RubyContext and CodeContext (which is
deprecated and will be gradually removed from libraries). Also passing blocks to
library methods are handled in a special way: Most of the library methods can
accept a block even though they ignore it. It would be tedious to use the block
parameter when not needed and therefore the Ruby binder injects it automatically
to the ParameterWrappers and ArgBuilders if not specified. The injected
parameter is of type MissingBlockParam and implicit conversions are defined from
BlockParam to MissingBlockParam and vice versa. Therefore, for the purpose of
overload resolution, each method has a block parameter. If no block is specified
at call-site overloads with MissingBlockParam are preferred, followed by
nullable BlockParam ([NotNull]BlockParam overloads are not applicable). If a
block is specified but is null then nullable BlockParam has precedence over
MissingBlockParam ([NotNull]BlockParam overloads are not applicable). If a block
is specified and is not null then the order is [NotNull]BlockParam >
BlockParam > MissingBlockParam.
- CanConvertFrom - moved here from ParameterWrapper and changed the
parameter to ParameterWrappers instead of Type. This allows to customize
conversions based upon attributes and other modifiers applied on the parameters
in addition to the type of the parameter.
- ParametersEquivalent - used from ParameterWrapper to detect whether
parameters are equivalent in parameter ordering used for overload resolution.
Adds Candidate enum with values { Equivalent, One, Two} and refactors various
CompareTo, PreferConvert, SelectBestConversionFrom methods to return values of
Candidate enum instead of integers.
Adds ParameterInfo property to both ParameterWrapper and ArgBuilder. The value
is optional and some kinds of parameters and arg builders might not be
associated with parameter-info. The purpose is to allow parameter comparison and
conversion methods to make decisions based upon parameter-info properties when
available.
Deletes Dynamic class. It''s not used anywhere.
Minor changes:
- Refactored MethodTarget.MakeExpression.
- Renamed PrepareArgumentBinding to PrepareParameterBinding,
BindSpecialArgument to BindSpecialParameter.
- Renamed CompareTo methods on ParameterWrapper to
GetPreferredParameter(s), made them static and renamed their arguments so that
the value of Candidate enum expresses the preference that is made by the method.
- Refactored usage of nullable Candidate enum, replaced it by
Candidate.Ambiguous enum value. I''ve also added extension methods for
the enum that makes the code working with Candidate enum more readable.
- Removed type parameter from *ArgBuilder ctors where possible, add ctor
overloads for callers that pass no parameter info.
- Removed #if BUG - I forgot that in the source code.
- Added comments where missing.
In addition, I''ve moved classes that are related to overload resolution
implementation in default binder from Generation into Actions.Calls namespace.
--------------
Python changes
--------------
Pass parameter binder with code context to default binder instead of code
context.
Tomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MethodBinder23.diff
Type: application/octet-stream
Size: 903123 bytes
Desc: MethodBinder23.diff
URL:
<http://rubyforge.org/pipermail/ironruby-core/attachments/20080910/aea141e2/attachment-0001.obj>