From 5118fef7d7967d32ecb96880f745cec77597b43e Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 10 Nov 2024 11:33:29 -0300 Subject: [PATCH 1/4] reproducing error --- test/interpreter.test.ts | 64 +++++++++++++++++++++++++++++++++++++++- test/linker.test.ts | 61 +++++++++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/test/interpreter.test.ts b/test/interpreter.test.ts index a514b68c..63529de5 100644 --- a/test/interpreter.test.ts +++ b/test/interpreter.test.ts @@ -2,7 +2,7 @@ import { expect, should, use } from 'chai' import { restore } from 'sinon' import sinonChai from 'sinon-chai' import { EXCEPTION_MODULE, Evaluation, REPL, WRENatives, buildEnvironment } from '../src' -import { DirectedInterpreter, interprete, Interpreter, getStackTraceSanitized } from '../src/interpreter/interpreter' +import { DirectedInterpreter, getStackTraceSanitized, interprete, Interpreter } from '../src/interpreter/interpreter' import link from '../src/linker' import { Body, Class, Field, Literal, Method, Package, ParameterizedType, Reference, Return, Send, Singleton, SourceIndex, SourceMap } from '../src/model' import { WREEnvironment } from './utils' @@ -270,6 +270,68 @@ describe('Wollok Interpreter', () => { it('for closure', () => { checkSuccessfulResult('{1 + 2}', '{1 + 2}') }) + + it('should be able to execute sentences related to a hierarchy defined in different packages', () => { + const replEnvironment = buildEnvironment([{ + name: 'jefeDeDepartamento.wlk', content: ` + import medico.* + + // con ésto falla + class Jefe inherits Medico { + // si comento la línea de arriba y utilizo ésto no falla + // class Jefe { + const subordinados = #{} + + override method atenderA(unaPersona) { + subordinados.anyOne().atenderA(unaPersona) + } + } + `, + }, { + name: 'medico.wlk', content: ` + import persona.* + + class Medico inherits Persona { + const dosis + + override method contraerEnfermedad(unaEnfermedad) { + super(unaEnfermedad) + self.atenderA(self) + } + method atenderA(unaPersona) { + unaPersona.recibirMedicamento(dosis) + } + + } + `, + }, { + name: 'persona.wlk', content: ` + class Persona { + const enfermedades = [] + + method contraerEnfermedad(unaEnfermedad) { + + enfermedades.add(unaEnfermedad) + } + + method saludar() = "hola" + } + `, + }, { + name: REPL, content: ` + import medico.* + + object testit { + method test() = new Medico(dosis = 200).saludar() + } + `, + }]) + interpreter = new Interpreter(Evaluation.build(replEnvironment, WRENatives)) + const { error } = interprete(interpreter, 'testit.test()') + console.info(error) + expect(error).to.be.undefined + }) + }) describe('sanitize stack trace', () => { diff --git a/test/linker.test.ts b/test/linker.test.ts index 922da80e..120a07f2 100644 --- a/test/linker.test.ts +++ b/test/linker.test.ts @@ -2,7 +2,7 @@ import { expect, should, use } from 'chai' import { GAME_MODULE, OBJECT_MODULE } from '../src' import { getPotentiallyUninitializedLazy } from '../src/decorators' import link, { canBeReferenced, linkSentenceInNode } from '../src/linker' -import { Body, Class, Closure, Describe, Environment, Field, Import, Method, Mixin, NamedArgument, Node, Package, Parameter, ParameterizedType, Reference, Return, Sentence, Singleton, Test, Variable } from '../src/model' +import { Body, Class, Closure, Describe, Environment, Field, Import, Method, Mixin, NamedArgument, Node, Package, Parameter, ParameterizedType, Reference, Return, Sentence, Singleton, Test, Variable, Literal } from '../src/model' import * as parse from '../src/parser' import { linkerAssertions } from './assertions' import { environmentWithEntities, WREEnvironment } from './utils' @@ -464,6 +464,65 @@ describe('Wollok linker', () => { C.methods[0].sentences[0].should.target(C.fields[0]) }) + it('should target references to members inherited from superclass in different packages', () => { + const environment = link([ + new Package({ + name: 'aaa', + imports: [ + new Import({ isGeneric: true, entity: new Reference({ name: 'bbb' }) }), + ], + members: [ + new Class({ + name: 'C', + supertypes: [new ParameterizedType({ reference: new Reference({ name: 'bbb.B' }) })], + members: [ + new Method({ + name: 'm2', + body: new Body({ sentences: [new Literal({ value: '2' })] }), + }), + ], + }), + ], + }), + new Package({ + name: 'bbb', + imports: [ + new Import({ isGeneric: true, entity: new Reference({ name: 'zzz' }) }), + ], + members: [ + new Class({ + name: 'B', + supertypes: [new ParameterizedType({ reference: new Reference({ name: 'zzz.A' }) })], + members: [ + new Method({ + name: 'm', + body: new Body({ sentences: [new Reference({ name: 'x' })] }), + }), + ], + }), + ], + }), + new Package({ + name: 'zzz', + members: [ + new Class({ + name: 'A', members: [ + new Field({ name: 'x', isConstant: false }), + ], + }), + ], + }), + ], WREEnvironment) + + const C = environment.getNodeByFQN('aaa.C') + const B = environment.getNodeByFQN('bbb.B') + const A = environment.getNodeByFQN('zzz.A') + + C.supertypes[0].reference.should.target(B) + B.supertypes[0].reference.should.target(A) + B.methods[0].sentences[0].should.target(A.fields[0]) + }) + it('should target references overriden on mixins to members inherited from superclass', () => { const environment = link([ new Package({ From 006cbd3690e0d968722f0a468c980073270e0841 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 11 Nov 2024 20:23:03 -0300 Subject: [PATCH 2/4] WIP: add some console logs --- package.json | 2 +- src/linker.ts | 4 ++++ test/interpreter.test.ts | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 178fbeee..aae51826 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "test:game": "mocha --parallel -r ts-node/register/transpile-only test/**/game.test.ts", "test:dynamicDiagram": "mocha --parallel -r ts-node/register/transpile-only test/dynamicDiagram.test.ts", "test:helpers": "mocha --parallel -r ts-node/register/transpile-only test/helpers.test.ts", - "test:interpreter": "mocha --parallel -r ts-node/register/transpile-only test/interpreter.test.ts", + "test:interpreter": "mocha -r ts-node/register/transpile-only test/interpreter.test.ts", "test:linker": "mocha --parallel -r ts-node/register/transpile-only test/linker.test.ts", "test:messageReporter": "mocha --parallel -r ts-node/register/transpile-only test/messageReporter.test.ts", "test:model": "mocha --parallel -r ts-node/register/transpile-only test/model.test.ts", diff --git a/src/linker.ts b/src/linker.ts index 75dfe767..56329f02 100644 --- a/src/linker.ts +++ b/src/linker.ts @@ -93,6 +93,10 @@ export const assignScopes = (root: Node): void => { : parent?.scope assign(node, { scope: new LocalScope(containerScope) }) + if (node.name === 'Medico') { + console.info(canBeReferenced(node), node.name, node.scope) + } + parent?.scope?.register(...scopeContribution(node)) }) diff --git a/test/interpreter.test.ts b/test/interpreter.test.ts index 63529de5..35c9e5a6 100644 --- a/test/interpreter.test.ts +++ b/test/interpreter.test.ts @@ -271,7 +271,7 @@ describe('Wollok Interpreter', () => { checkSuccessfulResult('{1 + 2}', '{1 + 2}') }) - it('should be able to execute sentences related to a hierarchy defined in different packages', () => { + it.only('should be able to execute sentences related to a hierarchy defined in different packages', () => { const replEnvironment = buildEnvironment([{ name: 'jefeDeDepartamento.wlk', content: ` import medico.* @@ -328,7 +328,7 @@ describe('Wollok Interpreter', () => { }]) interpreter = new Interpreter(Evaluation.build(replEnvironment, WRENatives)) const { error } = interprete(interpreter, 'testit.test()') - console.info(error) + // console.info(error) expect(error).to.be.undefined }) From f518b3a7ff54ee90f117b964f55928cdf010ac54 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 12 Nov 2024 20:01:36 -0300 Subject: [PATCH 3/4] Fix #308 --- package.json | 2 +- src/linker.ts | 7 ++-- test/interpreter.test.ts | 77 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index aae51826..178fbeee 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "test:game": "mocha --parallel -r ts-node/register/transpile-only test/**/game.test.ts", "test:dynamicDiagram": "mocha --parallel -r ts-node/register/transpile-only test/dynamicDiagram.test.ts", "test:helpers": "mocha --parallel -r ts-node/register/transpile-only test/helpers.test.ts", - "test:interpreter": "mocha -r ts-node/register/transpile-only test/interpreter.test.ts", + "test:interpreter": "mocha --parallel -r ts-node/register/transpile-only test/interpreter.test.ts", "test:linker": "mocha --parallel -r ts-node/register/transpile-only test/linker.test.ts", "test:messageReporter": "mocha --parallel -r ts-node/register/transpile-only test/messageReporter.test.ts", "test:model": "mocha --parallel -r ts-node/register/transpile-only test/model.test.ts", diff --git a/src/linker.ts b/src/linker.ts index 56329f02..c23ac82d 100644 --- a/src/linker.ts +++ b/src/linker.ts @@ -92,11 +92,6 @@ export const assignScopes = (root: Node): void => { ? parent?.parent.scope : parent?.scope assign(node, { scope: new LocalScope(containerScope) }) - - if (node.name === 'Medico') { - console.info(canBeReferenced(node), node.name, node.scope) - } - parent?.scope?.register(...scopeContribution(node)) }) @@ -120,7 +115,9 @@ export const assignScopes = (root: Node): void => { node.scope.include(new LocalScope(undefined, ...contributions)) } } + }) + root.forEach((node, _parent) => { if (node.is(Module)) { node.scope.include(...node.hierarchy.slice(1).map(supertype => supertype.scope)) } diff --git a/test/interpreter.test.ts b/test/interpreter.test.ts index 35c9e5a6..294a1138 100644 --- a/test/interpreter.test.ts +++ b/test/interpreter.test.ts @@ -271,15 +271,13 @@ describe('Wollok Interpreter', () => { checkSuccessfulResult('{1 + 2}', '{1 + 2}') }) - it.only('should be able to execute sentences related to a hierarchy defined in different packages', () => { + it('should be able to execute sentences related to a hierarchy defined in different packages', () => { const replEnvironment = buildEnvironment([{ name: 'jefeDeDepartamento.wlk', content: ` import medico.* // con ésto falla class Jefe inherits Medico { - // si comento la línea de arriba y utilizo ésto no falla - // class Jefe { const subordinados = #{} override method atenderA(unaPersona) { @@ -327,9 +325,78 @@ describe('Wollok Interpreter', () => { `, }]) interpreter = new Interpreter(Evaluation.build(replEnvironment, WRENatives)) - const { error } = interprete(interpreter, 'testit.test()') - // console.info(error) + const { error, result } = interprete(interpreter, 'testit.test()') expect(error).to.be.undefined + expect(result).to.equal('"hola"') + }) + + it('should be able to execute sentences related to a hierarchy defined in different packages - 2', () => { + const replEnvironment = buildEnvironment([{ + name: 'medico.wlk', content: ` + import persona.* + + class Medico inherits Persona { + const dosis + + override method contraerEnfermedad(unaEnfermedad) { + super(unaEnfermedad) + self.atenderA(self) + } + + method atenderA(unaPersona) { + unaPersona.recibirMedicamento(dosis) + } + + } + `, + }, { + name: 'pediatra.wlk', content: ` + import jefeDeDepartamento.* + + class Pediatra inherits Jefe { + const property fechaIngreso = new Date() + + method esNuevo() = fechaIngreso.year() < 2022 + } + `, + }, { + name: 'jefeDeDepartamento.wlk', content: ` + import medico.* + + class Jefe inherits Medico { + const subordinados = #{} + + override method atenderA(unaPersona) { + subordinados.anyOne().atenderA(unaPersona) + } + } + `, + }, { + name: 'persona.wlk', content: ` + class Persona { + const enfermedades = [] + + method contraerEnfermedad(unaEnfermedad) { + + enfermedades.add(unaEnfermedad) + } + + method saludar() = "hola" + } + `, + }, { + name: REPL, content: ` + import pediatra.* + + object testit { + method test() = new Pediatra(dosis = 200).saludar() + } + `, + }]) + interpreter = new Interpreter(Evaluation.build(replEnvironment, WRENatives)) + const { error, result } = interprete(interpreter, 'testit.test()') + expect(error).to.be.undefined + expect(result).to.equal('"hola"') }) }) From 99e5cb0cbbb854be93a7e8fc753ed60733d9b29c Mon Sep 17 00:00:00 2001 From: Nahuel Palumbo Date: Tue, 19 Nov 2024 22:15:30 +0100 Subject: [PATCH 4/4] Improve tests --- test/interpreter.test.ts | 1 - test/linker.test.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/interpreter.test.ts b/test/interpreter.test.ts index 294a1138..a9d9b7e2 100644 --- a/test/interpreter.test.ts +++ b/test/interpreter.test.ts @@ -276,7 +276,6 @@ describe('Wollok Interpreter', () => { name: 'jefeDeDepartamento.wlk', content: ` import medico.* - // con ésto falla class Jefe inherits Medico { const subordinados = #{} diff --git a/test/linker.test.ts b/test/linker.test.ts index 120a07f2..c960b66e 100644 --- a/test/linker.test.ts +++ b/test/linker.test.ts @@ -474,7 +474,7 @@ describe('Wollok linker', () => { members: [ new Class({ name: 'C', - supertypes: [new ParameterizedType({ reference: new Reference({ name: 'bbb.B' }) })], + supertypes: [new ParameterizedType({ reference: new Reference({ name: 'B' }) })], members: [ new Method({ name: 'm2', @@ -492,7 +492,7 @@ describe('Wollok linker', () => { members: [ new Class({ name: 'B', - supertypes: [new ParameterizedType({ reference: new Reference({ name: 'zzz.A' }) })], + supertypes: [new ParameterizedType({ reference: new Reference({ name: 'A' }) })], members: [ new Method({ name: 'm',