dylan-lang / opendylan

Open Dylan compiler and IDE
http://opendylan.org/
Other
458 stars 69 forks source link

warning about invalid clause in class decl misses source location #1001

Open waywardmonkeys opened 9 years ago

waywardmonkeys commented 9 years ago

You get a warning without a correct source location when you compile this:

define class <foo> (<object>);
end class <foo>;

(Note the extra ; at the end of the first line.)

waywardmonkeys commented 9 years ago

The exact warning is:

Warning - Unrecognized clause in the definition of class <foo> - ignoring.
waywardmonkeys commented 9 years ago

There is this code in sources/dfmc/definitions/parse-class-clauses.dylan:

             { ?other:* }
               => note(<invalid-define-class-clause>,
                       source-location: fragment-source-location(other),
                       variable-name:   class-name);

This is part of a block that starts:

      { ?clause:*; ... }
        => macro-case (clause)

So, clause is empty here, so there's apparently no source location. I'm not sure how to get the source location of the ; so that we can rewrite the first block above as:

             { ?other:* }
               => note(<invalid-define-class-clause>,
                       source-location:
                         fragment-source-location(other) |
                           fragment-source-location(semicolon),
                       variable-name:   class-name);

Just using fragment-source-location(clauses) doesn't seem to work.

The best idea that I have so far (which isn't optimal) is:

diff --git a/sources/dfmc/definitions/define-class.dylan b/sources/dfmc/definitions/define-class.dylan
index 91dcfa1..33d8ab3 100644
--- a/sources/dfmc/definitions/define-class.dylan
+++ b/sources/dfmc/definitions/define-class.dylan
@@ -109,7 +109,7 @@ end &definition;
 define method do-define-class (fragment, mods, name, supers, slots)
   let (initargs, adjectives) = parse-class-adjectives(name, mods);
   let (slot-specs, inherited-slot-specs, keyword-specs, metaclass-spec)
-    = parse-class-clauses(name, slots);
+    = parse-class-clauses(fragment, name, slots);
   let super-exprs = parse-class-superclasses(supers);
   let super-exprs
     = if (empty?(super-exprs) & ~compiling-dylan-library?())
diff --git a/sources/dfmc/definitions/parse-class-clauses.dylan b/sources/dfmc/definitions/parse-class-clauses.dylan
index d222905..e2c14cb 100644
--- a/sources/dfmc/definitions/parse-class-clauses.dylan
+++ b/sources/dfmc/definitions/parse-class-clauses.dylan
@@ -22,7 +22,7 @@ define program-warning <invalid-define-class-clause>
 end program-warning;

 define function parse-class-clauses
-    (class-name, clauses)
+    (form, class-name, clauses)
       => (slot-specs, inherited-slot-specs, initarg-specs, metaclass-spec)
   collecting (slot-specs, inherited-slot-specs, initargs-specs)
     // use collect-first, since macro pattern-matching runs right-hand sides
@@ -62,7 +62,9 @@ define function parse-class-clauses
                      := parse-metaclass-clause(class-name, adjectives, spec);
              { ?other:* }
                => note(<invalid-define-class-clause>,
-                       source-location: fragment-source-location(other),
+                       source-location:
+                         fragment-source-location(other) |
+                           fragment-source-location(form),
                        variable-name:   class-name);
            end macro-case;
     end macro-case;
waywardmonkeys commented 9 years ago

@housel Any thoughts on this?