[svn] r5928: nemerle/trunk/ncc: hierarchy/GlobalEnv.n hierarchy/TypeBuilder.n hierarchy/TypeInfo.n testsui...

malekith svnadmin at nemerle.org
Fri Nov 11 13:21:50 CET 2005


Log:
Employ new, C#-compatible rules for nested type access. I guess the LookupType stuff also needs rewrite.

Author: malekith
Date: Fri Nov 11 13:21:47 2005
New Revision: 5928

Modified:
   nemerle/trunk/ncc/hierarchy/GlobalEnv.n
   nemerle/trunk/ncc/hierarchy/TypeBuilder.n
   nemerle/trunk/ncc/hierarchy/TypeInfo.n
   nemerle/trunk/ncc/testsuite/negative/calling.n
   nemerle/trunk/ncc/testsuite/negative/type-access.n
   nemerle/trunk/ncc/testsuite/negative/wrong-args.n
   nemerle/trunk/ncc/testsuite/positive/basic-macros.n
   nemerle/trunk/ncc/testsuite/positive/generic-specifier.n
   nemerle/trunk/ncc/testsuite/positive/matching.n
   nemerle/trunk/ncc/typing/TyVarEnv.n

Modified: nemerle/trunk/ncc/hierarchy/GlobalEnv.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/GlobalEnv.n	(original)
+++ nemerle/trunk/ncc/hierarchy/GlobalEnv.n	Fri Nov 11 13:21:47 2005
@@ -267,7 +267,10 @@
         if (List.ContainsRef(visited, t))
           acc
         else {
-          def members = t.LookupMember (the_name, for_completion);
+          def members = 
+            if (t.LookupMemberAvailable)
+              t.LookupMember (the_name, for_completion)
+            else [];
           visited = t :: visited;
           def acc = members.FoldLeft (acc, list.Cons);
           match (t.GetTydecl ()) {

Modified: nemerle/trunk/ncc/hierarchy/TypeBuilder.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/TypeBuilder.n	(original)
+++ nemerle/trunk/ncc/hierarchy/TypeBuilder.n	Fri Nov 11 13:21:47 2005
@@ -69,6 +69,8 @@
   mutable attributes : NemerleAttributes;
   accessibility : Accessibility;
   
+  typarms_count : int;
+
   mutable pt_tydecl : PT.TopDeclaration;
   mutable additional_decls : list [PT.ClassMember] = [];
   mutable partial_parts : list [PT.TopDeclaration] = [];
@@ -134,6 +136,11 @@
     };
     ++Passes.tyinfo_counter;
 
+    when (pt_tydecl.typarms != null)
+      typarms_count = pt_tydecl.typarms.tyvars.Length;
+    when (par != null)
+      typarms_count += par.TyparmsCount;
+
     if (this.pt_tydecl is PT.TopDeclaration.Interface)
       this.tydecl = TypeDeclaration.Interface ();
     else
@@ -356,10 +363,8 @@
   public override TyparmsCount : int
   {
     get {
-      // we return number from parsetree if we can, because it is more accurate
-      // (at least before we finish initializing all tyenvs)
-      if (pt_tydecl != null && pt_tydecl.typarms != null)
-        pt_tydecl.typarms.tyvars.Length
+      if (typarms is [])
+        typarms_count
       else
         base.TyparmsCount
     }
@@ -606,6 +611,11 @@
     tydecl
   }
 
+  public override LookupMemberAvailable : bool
+  {
+    get { member_map != null }
+  }
+
   public override LookupMemberImpl (name : string) : list [IMember]
   {
     match (member_map.Get (name)) {

Modified: nemerle/trunk/ncc/hierarchy/TypeInfo.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/TypeInfo.n	(original)
+++ nemerle/trunk/ncc/hierarchy/TypeInfo.n	Fri Nov 11 13:21:47 2005
@@ -422,6 +422,10 @@
 
   public abstract LookupMemberImpl (name : string) : list [IMember];
 
+  public virtual LookupMemberAvailable : bool
+  {
+    get { true }
+  }
   
   GetSignature (mem : IMember) : option [MType]
   {
@@ -505,13 +509,6 @@
     res.Rev ()
   }
   
-  /*
-  static aint_override (mem : IMember) : bool
-  {
-    ! (mem.Attributes %&& NemerleAttributes.Override)
-  }
-  */
-
   /** Look for specified member. 
 
       Semantics of returning base class member is the same as for 
@@ -679,10 +676,19 @@
     self_type
   }
 
-  public virtual TyparmsCount : int {
+  public virtual TyparmsCount : int
+  {
     get { typarms.Length }
   }
 
+  public virtual SourceTyparmsCount : int
+  {
+    get {
+      if (DeclaringType == null) TyparmsCount
+      else TyparmsCount - DeclaringType.TyparmsCount
+    }
+  }
+
   public virtual Typarms : list [StaticTyVar]
   {
     get { typarms }

Modified: nemerle/trunk/ncc/testsuite/negative/calling.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/calling.n	(original)
+++ nemerle/trunk/ncc/testsuite/negative/calling.n	Fri Nov 11 13:21:47 2005
@@ -69,10 +69,10 @@
 
 
 module M42 {
-  class B {}
+  class B2 {}
   class C {}
   
-  foo (_ : B) : string { "" }
+  foo (_ : B2) : string { "" }
   foo (_ : C) : int { 42 }
   
   Mai () : void

Modified: nemerle/trunk/ncc/testsuite/negative/type-access.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/type-access.n	(original)
+++ nemerle/trunk/ncc/testsuite/negative/type-access.n	Fri Nov 11 13:21:47 2005
@@ -5,5 +5,5 @@
 }
 
 module M2 {
-  f (_ : M1.C) : void {} // E: unbound type name `M1.C'
+  f (_ : M1.C) : void {} // E: inaccessible type `M1.C'
 }

Modified: nemerle/trunk/ncc/testsuite/negative/wrong-args.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/wrong-args.n	(original)
+++ nemerle/trunk/ncc/testsuite/negative/wrong-args.n	Fri Nov 11 13:21:47 2005
@@ -1,3 +1,3 @@
 class A ['a, 'b] {}
-class B ['a] : A ['a] {} // E: type `A' takes 2 argument.* while 1 were supplied
-class C : A {} // E: type `A' takes 2 argument.* while 0 were supplied
+class B ['a] : A ['a] {} // E: wrong number of type parameters to `A'
+class C : A {} // E: wrong number of type parameters to `A'

Modified: nemerle/trunk/ncc/testsuite/positive/basic-macros.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/basic-macros.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/basic-macros.n	Fri Nov 11 13:21:47 2005
@@ -209,7 +209,7 @@
     foreach (x in [77, 88, 99]) { print ("$x ") }
     printf ("\n");
 
-    foreach (x in ([0] : list.Cons [int])) { print ("$x ") }
+    foreach (x in ([0] : list [int].Cons)) { print ("$x ") }
     printf ("\n");
 
     def a = array .[3] [ [ [1, 2], [3, 4] ], [ [5, 6], [7, 8] ] ];

Modified: nemerle/trunk/ncc/testsuite/positive/generic-specifier.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/generic-specifier.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/generic-specifier.n	Fri Nov 11 13:21:47 2005
@@ -25,18 +25,18 @@
   }
 }
 
-_ = null : C.D[int];
+// _ = null : C.D[int];
 _ = null : C[int].D;
-_ = null : C.D.[int];
+// _ = null : C.D.[int];
 _ = null : C.[int].D;
 WriteLine (C[int].D.x);
-WriteLine (C.D[int].x);
+// WriteLine (C.D[int].x);
 
 WriteLine (C[int].X[Foo].x);
-WriteLine (C.X[int, Foo].x);
+// WriteLine (C.X[int, Foo].x);
 
 WriteLine (C.[int].X.[Foo].x);
-WriteLine (C.X.[int, Foo].x);
+// WriteLine (C.X.[int, Foo].x);
 
 WriteLine (C[Foo].y.y);
 C[Foo].X[string].Test ();
@@ -51,9 +51,6 @@
 /*
 BEGIN-OUTPUT
 0
-0
-(0, Foo)
-(0, Foo)
 (0, Foo)
 (0, Foo)
 Foo

Modified: nemerle/trunk/ncc/testsuite/positive/matching.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/matching.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/matching.n	Fri Nov 11 13:21:47 2005
@@ -1203,6 +1203,7 @@
 }
 
 
+namespace Something {
 variant MType {
   | Class { tc : MType; args : list[MType]; }
   | Void
@@ -1226,6 +1227,7 @@
       }
    }
 }
+}
 
 public enum Fruit { | Apple | Orange };
 
@@ -1440,7 +1442,7 @@
     NullMatch.run ();
     Variants.Run ();
     M8.Mn ();
-    M9.Run ();
+    Something.M9.Run ();
 
     System.Console.WriteLine(System.Convert.ToInt64((
       match ( Fruit.Orange) { 

Modified: nemerle/trunk/ncc/typing/TyVarEnv.n
==============================================================================
--- nemerle/trunk/ncc/typing/TyVarEnv.n	(original)
+++ nemerle/trunk/ncc/typing/TyVarEnv.n	Fri Nov 11 13:21:47 2005
@@ -77,6 +77,153 @@
       t.Fix ()
     }
     
+
+    bind_simple_named_type (env : GlobalEnv, curtc : TypeBuilder,
+                            name : Name, idl : list [string],
+                            args : list [TyVar]) : TyVar
+    {
+      match (tyvars.Find (name)) {
+        | Some (tv) when idl is [_] =>
+          when (!args.IsEmpty)
+            ReportError (messenger,
+                         $ "type variable `$(name.Id)' supplied with "
+                           "arguments");
+
+          MType.TyVarRef (tv)
+          
+        | _ =>
+          def env = name.GetEnv (env);
+          assert (env != null);
+
+          mutable wrong_parms = false;
+          mutable add_info = "unbound type name";
+          mutable exact_hit = null;
+
+          def symbols = env.LookupSymbol (idl, curtc);
+          def typeinfos = symbols.FoldLeft ([], fun (m, acc) {
+            match (m) {
+              | ti is TypeInfo =>
+                if (curtc == null || ti.CanAccess (curtc))
+                  if (args.Length == ti.SourceTyparmsCount) {
+                    when (ti.FullName == name.Id)
+                      exact_hit = ti;
+                    ti :: acc
+                  } else { 
+                    wrong_parms = true;
+                    add_info = "wrong number of type parameters to";
+                    acc
+                  }
+                else {
+                  when (! wrong_parms)
+                    add_info = "inaccessible type";
+                  acc
+                }
+              | _ => acc
+            }
+          });
+
+          match (typeinfos) {
+            | [ti]
+            | _ when exact_hit != null with ti = exact_hit =>
+              if (ti.TyparmsCount == args.Length)
+                MType.Class (ti, args)
+              else {
+                def find_nesting (nesting : TypeInfo) {
+                  if (nesting == null) null
+                  else if (ti.DeclaringType.Equals (nesting))
+                    nesting.GetMemType ()
+                  else if (nesting.LookupMemberAvailable && 
+                           nesting.LookupMember (ti.Name).Contains (ti))
+                    nesting.SubtypingSubst (ti)
+                      .Apply (ti.DeclaringType.GetMemType ())
+                  else find_nesting (nesting.DeclaringType)
+                }
+                match (find_nesting (curtc)) {
+                  | null =>
+                    ReportError (messenger,
+                                 $ "cannot determine nested type parameters "
+                                   "for `$(idl.ToString (\".\"))', please use the fully "
+                                   "qualified name");
+                    InternalType.Object
+                    
+                  | MType.Class (_, args') =>
+                    def args = args' + args;
+                    Util.cassert (args.Length == ti.TyparmsCount);
+                    MType.Class (ti, args)
+                    
+                  | _ => Util.ice ()
+                }
+              }
+              
+            | [] =>
+              ReportError (messenger, $ "$add_info `$(idl.ToString (\".\"))'");
+              InternalType.Object
+              
+            | _ =>
+              ReportError (messenger,
+                           $ "type name `$(idl.ToString (\".\"))' is ambiguous, it could be:");
+              when (messenger.NeedMessage)
+                foreach (ti in typeinfos)
+                  Message.Error (ti.Location, $"   this declaration `$ti'");
+              InternalType.Object
+          }
+      }
+    }
+    
+
+    static poors_man_lookup_member (ti : TypeInfo, name : string) : list [IMember]
+    {
+      def loop (acc = [name], ti = ti) {
+        if (ti == null) acc
+        else loop (ti.Name :: acc, ti.DeclaringType)
+      }
+      match (NamespaceTree.LookupExactType (loop ())) {
+        | Some (t) => [t]
+        | None => []
+      }
+    }
+    
+
+    bind_nested_type (curtc : TypeInfo, base_type : TyVar, name : string, args : list [TyVar]) : TyVar
+    {
+      match (base_type.Fix ()) {
+        | MType.Class (ti, args') =>
+          mutable seen_typeinfo = "";
+          
+          def symbols =
+            if (ti.LookupMemberAvailable)
+              ti.LookupMember (name)
+            else
+              poors_man_lookup_member (ti, name);
+
+          def types =
+            symbols.Filter (fun (m) {
+              | m is TypeInfo when curtc == null || m.CanAccess (curtc) =>
+                seen_typeinfo = "with this number of type parameters";
+                m.SourceTyparmsCount == args.Length
+              | _ => false
+            });
+            
+          match (types) {
+            | [m is TypeInfo] =>
+              MType.Class (m, args' + args)
+
+            | [] =>
+              ReportError (messenger,
+                           $ "the type `$base_type' does not contain "
+                             "a nested type named `$name' $seen_typeinfo");
+              InternalType.Object
+
+            | l => Util.ice ($ "$l");
+          }
+        | t =>
+          ReportError (messenger,
+                       $ "won't lookup nested types in $t");
+          InternalType.Object
+      }
+    }
+
+    
     /** Perform typing of Parsetree type to Typedtree type, looking up
         type constructors in given global environment (with accessibility
         information implied by given current TypeInfo) and type variables
@@ -93,30 +240,6 @@
                  allow_tyvars : bool,
                  check_parms : bool) : TyVar
     {
-      // FIXME: check if correct number of arguments is given
-      def collect_name_and_types (names, types, expr) {
-        match (expr) {
-          | <[ $name . [ .. $args ] ]>
-          | <[ $name [ .. $args ] ]> =>
-            when (args.IsEmpty) {
-              ReportError (messenger, $"$name[] is not a valid type, use just $name");
-              when (messenger.NeedMessage)
-                Message.HintOnce ("if you had array type on mind, its syntax is `array [SomeType]'");
-            }
-            collect_name_and_types (names, args + types, name)
-            
-          | <[ $ns . $(fld : dyn) ]> =>
-            collect_name_and_types (fld :: names, types, ns)
-            
-          | <[ $(name : name) ]> =>
-            (name.idl :: names, types, name)
-            
-          | x =>
-            ReportError (messenger, $ "$x is not a legal type expression");
-            (names, types, null)
-        }
-      }
-      
       def f (t) {
         f2 (t, false)
       } and f2 (t, allow_ref) {
@@ -150,7 +273,7 @@
           | PExpr.GenericSpecifier
           | PExpr.Member
           | PExpr.Ref =>
-            type_class (collect_name_and_types ([], [], t))
+            type_class (t)
 
           | PExpr.TypedType (body) =>
             body
@@ -179,58 +302,41 @@
             ReportError (messenger, $ "$x is not a legal type expression");
             InternalType.Void
         }
-      } and type_class (names, args, nm) : TyVar {
-        if (nm == null)
-          InternalType.Void
-        else
-          match (tyvars.Find (nm)) {
-            | Some (tv) when names.Length == 1 =>
-              when (!args.IsEmpty)
-                ReportError (messenger,
-                             $ "type variable `$(nm.Id)' supplied with "
-                               "arguments");
-
-              MType.TyVarRef (tv)
-            | _ =>
-              def env = nm.GetEnv (env);
-              assert (env != null);
+      } and type_class (tyexpr) : TyVar {
+        def res =
+          match (tyexpr) {
+            | <[ $t [] ]> =>
+              ReportError (messenger, $"$t[] is not a valid type, use just $t");
+              when (messenger.NeedMessage)
+                Message.HintOnce ("if you had array type on mind, its syntax is `array [SomeType]'");
+              f (t)
               
+            | <[ $(name : name) ]> with args = []
+            | <[ $(name : name) [ .. $args ] ]>
+            | <[ $(name : name) . [ .. $args ] ]> =>
+              bind_simple_named_type (env, curtc, name, [name.Id], args.Map (f))
+              
+            | <[ $t . [ .. $args ] ]>
+            | <[ $t [ .. $args ] ]>
+            | <[ $t ]> with args = [] =>
+              match (Util.qidl_of_expr (t)) {
+                | Some ((idl, name)) =>
+                  bind_simple_named_type (env, curtc, name, idl, args.Map (f))
 
-              def (ti, need_args_tweak) =
-                match (env.LookupType (names, curtc, args.Length)) {
-                  | Some (ti) =>
-                    (ti, false)
                   | None =>
-                    match (env.LookupType (names, curtc, -1)) {
-                      | Some (ti) =>
-                        def is_nested_in_curtc (ti) {
-                          if (ti == null) false
-                          else
-                            ti.Equals (curtc) || is_nested_in_curtc (ti.DeclaringType)
+                  match (t) {
+                    | <[ $ns . $(fld : dyn) ]> =>
+                      bind_nested_type (curtc, f (ns), fld, args.Map (f))
+                    | _ =>
+                      ReportError (messenger, $ "$t is not a legal type expression");
+                      InternalType.Void
                         }
-                        (ti, is_nested_in_curtc (ti))
-                      | None =>
-                        // this will print out error message
-                        (env.GetType (names, curtc, -1), false)
                     }
                 }
-              def args = List.Map (args, f);
               
+        match (res.Fix ()) {
+          | MType.Class (ti, args) =>
               ti.HasBeenUsed = true;
-
-              def find_proper_enclosing_type (t : TypeInfo) {
-                if (t == null || args.Length + t.TyparmsCount == ti.TyparmsCount) t
-                else find_proper_enclosing_type (t.DeclaringType)
-              }
-
-              def args =
-                if (need_args_tweak) {
-                  def ti' = find_proper_enclosing_type (curtc);
-                  if (ti' != null)
-                    ti'.GetMemType ().args + args
-                  else []
-                } else args;
-
               match (ti.GetTydecl ()) {
                 | Typedtree.TypeDeclaration.Alias (t) =>
                   def subst = ti.MakeSubst (args);
@@ -241,6 +347,7 @@
                     _ = ti.MakeSubst (args);
                   MType.Class (ti, args)
               }
+          | t => t
           }
       }
 



More information about the svn mailing list