Parcourir la source

fix diagnostic for overriding not exported method

Vladislav Folts il y a 10 ans
Parent
commit
891dab367e

BIN
bin/compiled.zip


+ 15 - 1
src/eberon/EberonRecord.ob

@@ -92,6 +92,15 @@ BEGIN
     RETURN result;
 END;
 
+PROCEDURE doesBaseHasNotExportedMethod(r: Record; id :STRING): BOOLEAN;
+BEGIN
+    type <- r.base(PRecord);
+    WHILE (type # NIL) & (type.nonExportedMethods.indexOf(id) = -1) DO
+        type := type.base(PRecord);
+    END;
+    RETURN type # NIL;
+END;
+
 PROCEDURE ensureMethodDefinitionsForEach(key: STRING; ids: ARRAY OF STRING; r: PRecord; VAR result: ARRAY * OF STRING);
 VAR
     report: ARRAY * OF STRING;
@@ -278,6 +287,9 @@ BEGIN
     IF findMethodDeclaration(SELF(POINTER), id) # NIL THEN
         Errors.raise(
             "cannot declare field, record already has method '" + id +"'");
+    ELSIF doesBaseHasNotExportedMethod(SELF, id) THEN
+        Errors.raise(
+            "cannot declare field, record already has method '" + id +"' in the base record (was not exported)");
     END;
 
     type <- f.type();
@@ -306,6 +318,9 @@ BEGIN
             msg := "cannot declare method, record already has field '" + id + "'";
         END;
         Errors.raise(msg);
+    ELSIF doesBaseHasNotExportedMethod(SELF, id) THEN
+        Errors.raise("cannot declare a new method '" + id + "': "
+                   + "method already was declared in the base record (but was not exported)");
     END;
 
     SELF.declaredMethods[id] := NEW RecordFieldAsMethod(methodId, type);
@@ -471,7 +486,6 @@ BEGIN
     FOR i <- 0 TO LEN(SELF.nonExportedMethods) - 1 DO
         SELF.declaredMethods.remove(SELF.nonExportedMethods[i]);
     END;
-    SELF.nonExportedMethods.clear();
 
     checkIfFieldsInited(SELF);
 

+ 0 - 2
src/ob/ContextExpression.ob

@@ -20,7 +20,6 @@ TYPE
         PROCEDURE Factor(parent: PFactor);
 
         PROCEDURE handleConst(type: Types.PType; value: ConstValue.PType; code: STRING);
-        PROCEDURE handleLiteral(s: STRING);
         PROCEDURE handleLogicalNot();
 
         factorParent: PFactor;
@@ -41,7 +40,6 @@ TYPE
     PTerm = POINTER TO Term;
 
     MulOperator* = RECORD(ContextHierarchy.Node)
-        PROCEDURE handleLiteral(s: STRING);
     END;
 
     Const = RECORD(ContextHierarchy.Node)

+ 1 - 1
src/ob/ContextHierarchy.ob

@@ -28,7 +28,7 @@ TYPE
         PROCEDURE handleMessage(VAR msg: Message): PMessageResult;
         PROCEDURE codeGenerator(): CodeGenerator.PIGenerator;
         PROCEDURE qualifyScope(scope: Scope.PType): STRING;
-        PROCEDURE handleLiteral(s: STRING);
+        PROCEDURE handleLiteral*(s: STRING);
         PROCEDURE genTypeName(): STRING;
 
         mParent: PNode;

+ 12 - 0
test/test_unit_eberon.js

@@ -175,6 +175,18 @@ exports.suite = {
           "cannot declare field, record already has method 'm'"]
          )
     ),
+"method is not exported in base record": testWithModule(
+      "MODULE test;"    
+    + "TYPE Base* = RECORD PROCEDURE method(); END;"
+    + "END test.",
+    pass(),
+    fail(["MODULE m; IMPORT test; TYPE D = RECORD(test.Base) PROCEDURE method(); END; END m.", 
+          "cannot declare a new method 'method': method already was declared in the base record (but was not exported)"],
+         ["MODULE m; IMPORT test; TYPE D = RECORD(test.Base) method: INTEGER; END; END m.", 
+          "cannot declare field, record already has method 'method' in the base record (was not exported)"],
+         ["MODULE m; IMPORT test; TYPE D = RECORD(test.Base) END; PROCEDURE D.method(); END; END m.", 
+          "'D' has no declaration for method 'method'"])
+    ),
 "overridden method declaration": testWithContext(
     context(grammar.declarationSequence,
               "TYPE Base = RECORD PROCEDURE p() END; T = RECORD (Base) END;"