[svn] r6261: nemerle/trunk: macros/core.n ncc/Makefile
ncc/external/LibrariesLoader.n ncc/hierarchy/Builti...
malekith
svnadmin at nemerle.org
Sat May 13 12:55:41 CEST 2006
Log:
Totally reimplement the way extension methods are handled. Extension methods on interfaces should work now. We could get rid of special array types, but maybe there will be useful for something else?
Author: malekith
Date: Sat May 13 12:55:39 2006
New Revision: 6261
Removed:
nemerle/trunk/ncc/hierarchy/ExtensionMethod.n
Modified:
nemerle/trunk/macros/core.n
nemerle/trunk/ncc/Makefile
nemerle/trunk/ncc/external/LibrariesLoader.n
nemerle/trunk/ncc/hierarchy/BuiltinMethod.n
nemerle/trunk/ncc/hierarchy/ClassMembers.n
nemerle/trunk/ncc/hierarchy/TypeInfo.n
nemerle/trunk/ncc/testsuite/negative/extension-methods.n
nemerle/trunk/ncc/typing/OverloadPossibility.n
nemerle/trunk/ncc/typing/Typer-DelayedTyping.n
nemerle/trunk/ncc/typing/Typer-OverloadSelection.n
nemerle/trunk/ncc/typing/Typer.n
Modified: nemerle/trunk/macros/core.n
==============================================================================
--- nemerle/trunk/macros/core.n (original)
+++ nemerle/trunk/macros/core.n Sat May 13 12:55:39 2006
@@ -707,16 +707,10 @@
else if (!((mb.Attributes %&& NemerleAttributes.Public) &&
(mb.Attributes %&& NemerleAttributes.Static)))
Message.Error ("extension methods need to be marked public static")
- else
- match (p.ty.Fix ()) {
- | Class (tc, _)
- | Array (_, n) with tc = InternalType.GetArrayType (n) =>
+ else {
add_attr (tb.GetModifiers ());
add_attr (mb.GetModifiers ());
- tc.AddExtensionMethod (mb);
- | t =>
- Message.Error ($ "extension methods not yet supported on non-class "
- "types like $t")
+ LibraryReferenceManager.AddExtensionMethod (mb);
}
}
}
Modified: nemerle/trunk/ncc/Makefile
==============================================================================
--- nemerle/trunk/ncc/Makefile (original)
+++ nemerle/trunk/ncc/Makefile Sat May 13 12:55:39 2006
@@ -91,7 +91,6 @@
generation/DecisionTreeCompiler.n \
generation/Typer3.n \
generation/Typer4.n \
- hierarchy/ExtensionMethod.n \
hierarchy/BuiltinMethod.n \
hierarchy/ClassMembers.n \
hierarchy/CustomAttribute.n \
Modified: nemerle/trunk/ncc/external/LibrariesLoader.n
==============================================================================
--- nemerle/trunk/ncc/external/LibrariesLoader.n (original)
+++ nemerle/trunk/ncc/external/LibrariesLoader.n Sat May 13 12:55:39 2006
@@ -84,6 +84,7 @@
AllowLoadingExtensions = false;
}
_construct_right_away = [];
+ _extension_methods.Clear ();
}
@@ -149,6 +150,25 @@
_lib_path = name :: _lib_path;
}
+ public GetExtensionMethods (name : string, env : GlobalEnv) : list [IMethod]
+ {
+ if (_extension_methods.Contains (name))
+ _extension_methods [name].FoldLeft ([], fun (meth, acc) {
+ if (env.IsOpenNamespace (meth.DeclaringType.NamespaceNode.Parent))
+ meth :: acc
+ else acc
+ })
+ else []
+ }
+
+ public AddExtensionMethod (m : IMethod) : void
+ {
+ if (_extension_methods.Contains (m.Name))
+ _extension_methods [m.Name] ::= m;
+ else
+ _extension_methods [m.Name] = [m];
+ }
+
/**
* Remove assembly file name from URL returned by Assembly.CodeBase.
*/
@@ -302,6 +322,8 @@
private namespace_nodes : Hashtable [string, NamespaceTree.Node] = Hashtable (300);
private mutable _construct_right_away : list [NamespaceTree.Node] = [];
+ // extension method name -> list of extension methods
+ private _extension_methods : Hashtable [string, list [IMethod]] = Hashtable ();
/* -- TYPE CACHE ----- */
@@ -1312,12 +1334,7 @@
when (system_type.IsDefined (t, false)) {
foreach (m is IMethod in GetMembers ())
when (m.IsStatic && m.GetHandle ().IsDefined (t, false))
- match (m.GetParameters ().Head.ty.Fix ()) {
- | Class (tc, _)
- | Array (_, n) with tc = InternalType.GetArrayType (n) =>
- tc.AddExtensionMethod (m);
- | _ => Util.ice ()
- }
+ LibraryReferenceManager.AddExtensionMethod (m);
}
}
}
@@ -1904,11 +1921,6 @@
get { is_var_args }
}
- public IsExtensionMethod : bool
- {
- get { false }
- }
-
public GetMethodBase () : SR.MethodBase
{
handle
Modified: nemerle/trunk/ncc/hierarchy/BuiltinMethod.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/BuiltinMethod.n (original)
+++ nemerle/trunk/ncc/hierarchy/BuiltinMethod.n Sat May 13 12:55:39 2006
@@ -179,11 +179,6 @@
set { ignore (value); }
}
- public virtual IsExtensionMethod : bool
- {
- get { false }
- }
-
public virtual Attributes : NemerleAttributes {
get {
NemerleAttributes.Static |
Modified: nemerle/trunk/ncc/hierarchy/ClassMembers.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/ClassMembers.n (original)
+++ nemerle/trunk/ncc/hierarchy/ClassMembers.n Sat May 13 12:55:39 2006
@@ -706,11 +706,6 @@
get { is_var_args }
}
- public IsExtensionMethod : bool
- {
- get { false }
- }
-
public this (par : TypeBuilder, f : PT.ClassMember.Function)
{
this (par, f, false)
Modified: nemerle/trunk/ncc/hierarchy/TypeInfo.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/TypeInfo.n (original)
+++ nemerle/trunk/ncc/hierarchy/TypeInfo.n Sat May 13 12:55:39 2006
@@ -120,7 +120,6 @@
GetConstructorInfo () : System.Reflection.ConstructorInfo;
IsVarArgs : bool { get; }
IsFinal : bool { get; }
- IsExtensionMethod : bool { get; }
BuiltinKind : BuiltinMethodKind { get; }
/// Obtains list of parameters of typed method
@@ -513,20 +512,6 @@
res.Rev ()
}
- protected mutable extension_methods : Hashtable [string, list [IMember]];
- public AddExtensionMethod (based_on : IMethod) : void
- {
- when (extension_methods == null)
- extension_methods = Hashtable ();
-
- def meth = ExtensionMethod (this, based_on);
-
- if (extension_methods.Contains (meth.Name))
- extension_methods [meth.Name] ::= meth
- else
- extension_methods [meth.Name] = [meth]
- }
-
/** Look for specified member.
Semantics of returning base class member is the same as for
@@ -542,16 +527,8 @@
else if (special_members.Contains (name))
special_members [name]
else {
- def lookup_impl (ti) {
- if (ti.extension_methods == null ||
- !ti.extension_methods.Contains (name))
- ti.LookupMemberImpl (name)
- else
- ti.LookupMemberImpl (name) + ti.extension_methods [name]
- }
-
def loop (acc, ti : TypeInfo) {
- def res = lookup_impl (ti);
+ def res = ti.LookupMemberImpl (name);
// filter out members with override specified
// def res = res.RevFilterWhenNeeded (aint_override);
@@ -561,7 +538,7 @@
if (ti.IsInterface)
match (ti.GetDirectSuperTypes ()) {
| [] =>
- lookup_impl (InternalType.Object_tc) :: acc
+ InternalType.Object_tc.LookupMemberImpl (name) :: acc
| ifaces =>
ifaces.Map (fun (c) {
c.tycon.LookupMember (name)
Modified: nemerle/trunk/ncc/testsuite/negative/extension-methods.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/extension-methods.n (original)
+++ nemerle/trunk/ncc/testsuite/negative/extension-methods.n Sat May 13 12:55:39 2006
@@ -15,10 +15,3 @@
public foo (p : int, this a : A) : void // E: 'this' modifier \(for extension method\) can only be used on the first parameter
Write ($"foo($(a.v),$p)\n")
-class D[X]
- public static foo (this a : A, p : int) : void // E: cannot define extension methods in generic types
- ()
-
-class D2
- public static foo[A,B] (this a : D[B]) : void // E: type parameters.*extension method
- ()
Modified: nemerle/trunk/ncc/typing/OverloadPossibility.n
==============================================================================
--- nemerle/trunk/ncc/typing/OverloadPossibility.n (original)
+++ nemerle/trunk/ncc/typing/OverloadPossibility.n Sat May 13 12:55:39 2006
@@ -223,6 +223,7 @@
mutable generic_specifier : list [TyVar];
public mutable IsBaseCall : bool;
public mutable VarArgs : bool;
+ public mutable ExtensionMethodObject : TExpr;
public mutable IsConstantObject : bool;
public mutable UsedDefaultParms : bool;
public mutable UsedLastTime : bool;
Modified: nemerle/trunk/ncc/typing/Typer-DelayedTyping.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer-DelayedTyping.n (original)
+++ nemerle/trunk/ncc/typing/Typer-DelayedTyping.n Sat May 13 12:55:39 2006
@@ -402,6 +402,9 @@
overload.UsedLastTime = false;
def try_type (overload : OverloadPossibility, final) {
+ def parms =
+ if (overload.ExtensionMethodObject == null) parms
+ else Parm (overload.ExtensionMethodObject) :: parms;
def ct = CallTyper (typer, overload.Compile (), parms, expected);
ct.overload_possibility = overload;
ct.is_final = final;
@@ -494,7 +497,7 @@
def loop (ti : TypeInfo) {
foreach (meth is IMethod in ti.LookupMember (name))
when (meth.IsStatic)
- res = typer.ConstructMethodOverload (meth) :: res;
+ res = typer.ConstructMethodOverload (meth) + res;
match (ti.GetTydecl ()) {
| TypeDeclaration.Interface =>
loop (InternalType.Object_tc)
@@ -605,7 +608,7 @@
mutable res = [];
foreach (meth is IMethod in globals)
when (meth.IsStatic)
- res = typer.ConstructMethodOverload (meth) :: res;
+ res = typer.ConstructMethodOverload (meth) + res;
match ((operators, res)) {
| (x, []) => x
Modified: nemerle/trunk/ncc/typing/Typer-OverloadSelection.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer-OverloadSelection.n (original)
+++ nemerle/trunk/ncc/typing/Typer-OverloadSelection.n Sat May 13 12:55:39 2006
@@ -154,10 +154,7 @@
static AintExtension (o : OverloadPossibility) : bool
{
- match (o.Member) {
- | meth is IMethod => ! meth.IsExtensionMethod
- | _ => true
- }
+ o.ExtensionMethodObject == null
}
Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n (original)
+++ nemerle/trunk/ncc/typing/Typer.n Sat May 13 12:55:39 2006
@@ -555,7 +555,7 @@
match (OverloadPossibility.OnlyPossible (res, expected)) {
| [] => TExpr.Error ()
- | [o] =>
+ | [o] when o.ExtensionMethodObject == null =>
def expr = o.Compile ();
_ = Expect (expected, expr.Type, "overloaded symbol");
expr
@@ -786,7 +786,7 @@
match (res) {
| [one] =>
- def overload = ConstructMethodOverload (one);
+ def overload = ConstructMethodOverload (one).Head;
method = overload.Compile () :> TExpr.StaticRef;
def ok = method.Type.Require (needed);
Util.cassert (ok);
@@ -2101,9 +2101,12 @@
}
- ConstructMethodOverload (m : IMethod, pt_from : PT.PExpr = null) : OverloadPossibility
+ ConstructMethodOverload (m : IMethod, pt_from : PT.PExpr = null,
+ maybe_varargs = false) : list [OverloadPossibility]
{
def bounds = m.GetHeader ().typarms.Map (fun (tv) { tv.LowerBound });
+
+ def make_overload () {
def from = ConstructEnclosingType (pt_from, m, bounds);
def (ty, vars) = from.TypeOfMethodWithTyparms (m);
@@ -2111,6 +2114,16 @@
method_typarms = vars)
}
+ if (maybe_varargs && m.IsVarArgs) {
+ def o1 = make_overload ();
+ def o2 = make_overload ();
+ o2.VarArgs = true;
+ [o1, o2]
+ } else {
+ [make_overload ()]
+ }
+ }
+
InterpretGlobal (pt_from : PT.PExpr, symbol : IMember) : list [OverloadPossibility]
{
@@ -2152,14 +2165,7 @@
TypeToConstructor (pt_from, t)
| MemberKind.Method (m) =>
- if (m.IsVarArgs) {
- def o1 = ConstructMethodOverload (m, pt_from);
- def o2 = ConstructMethodOverload (m, pt_from);
- o2.VarArgs = true;
- [o1, o2]
- } else {
- [ConstructMethodOverload (m, pt_from)]
- }
+ ConstructMethodOverload (m, pt_from, maybe_varargs = true)
| MemberKind.Property
| MemberKind.Field =>
@@ -2333,16 +2339,11 @@
lookup (possible_type);
}
- res = res.Filter (fun (_) {
- | OverloadPossibility where (Member = meth is IMethod)
- when meth.IsExtensionMethod =>
- match (meth.BuiltinKind) {
- | ExtensionMethod (impl) =>
- name.GetEnv (env).IsOpenNamespace (impl.DeclaringType.NamespaceNode.Parent)
- | _ => Util.ice ()
+ foreach (meth in LibraryReferenceManager.GetExtensionMethods (name.Id, name.GetEnv (env)))
+ foreach (over in ConstructMethodOverload (meth, maybe_varargs = true)) {
+ over.ExtensionMethodObject = obj;
+ res ::= over;
}
- | _ => true
- });
Some (res)
}
More information about the svn
mailing list