Forráskód Böngészése

do not use procedure NEW for records with parameterized constructors

Vladislav Folts 10 éve
szülő
commit
d21d3137ca
5 módosított fájl, 26 hozzáadás és 1 törlés
  1. BIN
      bin/compiled.zip
  2. 8 0
      src/eberon/EberonRecord.ob
  3. 1 1
      src/ob/Procedure.ob
  4. 5 0
      src/ob/Types.ob
  5. 12 0
      test/test_unit_eberon.js

BIN
bin/compiled.zip


+ 8 - 0
src/eberon/EberonRecord.ob

@@ -274,6 +274,14 @@ BEGIN
     END;
     END;
 END;
 END;
 
 
+PROCEDURE Record.codeForNew(cx: Context.Type): STRING;
+BEGIN
+    IF hasParameterizedConstructor(SELF) THEN
+        Errors.raise("cannot use procedure NEW for '" + SELF.name + "' because it has constructor with parameters, use operator NEW instead");
+    END;
+    RETURN SUPER(cx);
+END;
+
 PROCEDURE Record.initializer(cx: Context.Type): STRING;
 PROCEDURE Record.initializer(cx: Context.Type): STRING;
 BEGIN
 BEGIN
     ensureCanBeInstantiated(cx, SELF(POINTER), instantiateForNew);
     ensureCanBeInstantiated(cx, SELF(POINTER), instantiateForNew);

+ 1 - 1
src/ob/Procedure.ob

@@ -358,7 +358,7 @@ PROCEDURE makeNew(): Symbols.PSymbol;
             Errors.raise("non-exported RECORD type cannot be used in NEW");
             Errors.raise("non-exported RECORD type cannot be used in NEW");
         END;
         END;
         RETURN Code.makeSimpleExpression(
         RETURN Code.makeSimpleExpression(
-                arg.code() + " = " + baseType.initializer(cx^),
+                arg.code() + " = " + baseType.codeForNew(cx^),
                 NIL)
                 NIL)
     END CallImpl.make;
     END CallImpl.make;
 BEGIN
 BEGIN

+ 5 - 0
src/ob/Types.ob

@@ -160,6 +160,7 @@ TYPE
         PROCEDURE setBase*(type: PRecord);
         PROCEDURE setBase*(type: PRecord);
         PROCEDURE addField*(f: PField);
         PROCEDURE addField*(f: PField);
         PROCEDURE findSymbol*(id: STRING): PField;
         PROCEDURE findSymbol*(id: STRING): PField;
+        PROCEDURE codeForNew*(cx: Context.Type): STRING;
         PROCEDURE finalize*();
         PROCEDURE finalize*();
 
 
         fields: JsMap.Type;
         fields: JsMap.Type;
@@ -209,6 +210,10 @@ BEGIN
     closure(PRecord).finalize();
     closure(PRecord).finalize();
 END finalizeRecord;
 END finalizeRecord;
 
 
+PROCEDURE Record.codeForNew(cx: Context.Type): STRING;
+    RETURN SELF.initializer(cx);
+END;
+
 PROCEDURE Record.finalize();
 PROCEDURE Record.finalize();
 BEGIN
 BEGIN
     FOR i <- 0 TO LEN(SELF.notExported) - 1 DO
     FOR i <- 0 TO LEN(SELF.notExported) - 1 DO

+ 12 - 0
test/test_unit_eberon.js

@@ -1250,6 +1250,18 @@ exports.suite = {
              ["VAR a: ARRAY 3 OF WithParams;", "cannot use 'WithParams' as an element of static array because it has constructor with parameters"]
              ["VAR a: ARRAY 3 OF WithParams;", "cannot use 'WithParams' as an element of static array because it has constructor with parameters"]
             )
             )
         ),
         ),
+    "NEW": testWithContext(
+        context(grammar.statement,
+                "TYPE WithParams = RECORD PROCEDURE WithParams(i: INTEGER); END;"
+              + "DerivedWithParams = RECORD(WithParams) END;"
+              + "VAR p: POINTER TO WithParams; pd: POINTER TO DerivedWithParams;"
+              + "PROCEDURE WithParams.WithParams(i: INTEGER); END;"
+              ),
+        pass(),
+        fail(["NEW(p)", "cannot use procedure NEW for 'WithParams' because it has constructor with parameters, use operator NEW instead"],
+             ["NEW(pd)", "cannot use procedure NEW for 'DerivedWithParams' because it has constructor with parameters, use operator NEW instead"]
+            )
+        ),
     "export": testWithModule(
     "export": testWithModule(
           "MODULE test;"
           "MODULE test;"
         + "TYPE Exported* = RECORD PROCEDURE Exported*(); END;"
         + "TYPE Exported* = RECORD PROCEDURE Exported*(); END;"