Skip to content

Commit

Permalink
Merge branch 'master' into 292-error-poco-claro-cuando-se-omite-el-re…
Browse files Browse the repository at this point in the history
…ceptor-de-un-mensaje
  • Loading branch information
PalumboN authored Jan 10, 2025
2 parents 1bbb5e8 + 8c08698 commit ac6adb4
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 107 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
14 changes: 8 additions & 6 deletions src/interpreter/interpreter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { linkSentenceInNode } from '../linker'
import { Entity, Environment, Import, Method, Module, Name, Node, Reference, Sentence } from '../model'
import WRENatives from '../wre/wre.natives'
import { Evaluation, Execution, ExecutionDefinition, Natives, RuntimeObject, RuntimeValue, WollokException } from './runtimeModel'
import { Evaluation, Execution, ExecutionDefinition, Frame, Natives, RuntimeObject, RuntimeValue, WollokException } from './runtimeModel'
import * as parse from '../parser'
import { notEmpty } from '../extensions'
import { WOLLOK_EXTRA_STACK_TRACE_HEADER } from '../constants'
Expand Down Expand Up @@ -116,25 +116,27 @@ export class Interpreter extends AbstractInterpreter {

}

export function interprete(interpreter: Interpreter, line: string): ExecutionResult {
export function interprete(interpreter: AbstractInterpreter, line: string, frame?: Frame): ExecutionResult {
try {
const sentenceOrImport = parse.Import.or(parse.Variable).or(parse.Assignment).or(parse.Expression).tryParse(line)
const error = [sentenceOrImport, ...sentenceOrImport.descendants].flatMap(_ => _.problems ?? []).find(_ => _.level === 'error')
if (error) throw error

if (sentenceOrImport.is(Sentence)) {
const environment = interpreter.evaluation.environment
linkSentenceInNode(sentenceOrImport, environment.replNode())
linkSentenceInNode(sentenceOrImport, frame ? frame.node.parentPackage! : interpreter.evaluation.environment.replNode())
const unlinkedNode = [sentenceOrImport, ...sentenceOrImport.descendants].find(_ => _.is(Reference) && !_.target)

if (unlinkedNode) {
if (unlinkedNode.is(Reference)) {
if (!interpreter.evaluation.currentFrame.get(unlinkedNode.name))
if (!(frame ?? interpreter.evaluation.currentFrame).get(unlinkedNode.name))
return failureResult(`Unknown reference ${unlinkedNode.name}`)
} else return failureResult(`Unknown reference at ${unlinkedNode.sourceInfo}`)
}

const result = interpreter.exec(sentenceOrImport)
const result = frame ?
interpreter.do(function () { return interpreter.evaluation.exec(sentenceOrImport, frame) }) :
interpreter.exec(sentenceOrImport)

const stringResult = !result || isVoid(result)
? ''
: result.showShortValue(interpreter)
Expand Down
5 changes: 3 additions & 2 deletions src/linker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { v4 as uuid } from 'uuid'
import { divideOn, is, List } from './extensions'
import { BaseProblem, Entity, Environment, Field, Id, Import, Level, Module, Name, Node, Package, Parameter, ParameterizedType, Reference, Scope, Sentence, SourceMap, Variable } from './model'
import { REPL } from './constants'
const { assign } = Object


Expand Down Expand Up @@ -67,7 +68,7 @@ export class LocalScope implements Scope {

register(...contributions: [Name, Node][]): void {
const shouldBeOverrided = (older: Node, newer: Node) => // Override wtest files with same name than wlk
older.is(Package) && newer.is(Package) && older.isTestFile && !newer.isTestFile
older.is(Package) && newer.is(Package) && !newer.isTestFile
for (const [name, node] of contributions) {
const alreadyRegistered = this.contributions.get(name)
if (!alreadyRegistered || shouldBeOverrided(alreadyRegistered, node)) {
Expand Down Expand Up @@ -134,7 +135,7 @@ export default (newPackages: List<Package>, baseEnvironment?: Environment): Envi
const environment = new Environment({
id: uuid(),
scope: undefined,
members: newPackages.reduce(mergePackage, baseEnvironment?.members ?? []) as List<Package>,
members: newPackages.reduce(mergePackage, baseEnvironment?.members ?? [new Package({ name: REPL })]) as List<Package>,
}).transform(node => node.copy({ id: uuid() }))

const nodeCache = new Map<Id, Node>()
Expand Down
2 changes: 1 addition & 1 deletion src/validator/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@
"shouldUseOverrideKeyword": "Method should be marked as override, since it overrides a superclass method",
"shouldUseSelfAndNotSingletonReference": "Don't use the name within the object. Use 'self' instead.",
"superclassShouldBeLastInLinearization": "Bad Linearization: superclass should be last in linearization"
}
}
2 changes: 1 addition & 1 deletion src/validator/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@
"shouldUseOverrideKeyword": "Debería marcarse el método con 'override', ya que sobrescribe el de sus superclases",
"shouldUseSelfAndNotSingletonReference": "No debe usar el nombre del objeto dentro del mismo. Use 'self'.",
"superclassShouldBeLastInLinearization": "Linearización: la superclase debería estar última en linearización"
}
}
2 changes: 1 addition & 1 deletion src/wre/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const game: Natives = {
// Avoid to invoke method position() for optimisation reasons.
// -> If method isSynthetic then it is a getter, we can access to the field directly
const method = visual.module.lookupMethod('position', 0)!
const otherPosition = method.isSynthetic ? visual.get('position') :yield* this.invoke(method, visual)
const otherPosition = method.isSynthetic ? visual.get('position') : yield* this.invoke(method, visual)

const otherX = otherPosition?.get('x')?.innerNumber
const otherY = otherPosition?.get('y')?.innerNumber
Expand Down
4 changes: 2 additions & 2 deletions test/assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { join } from 'path'
import { buildEnvironment as buildEnv, print } from '../src'
import { List } from '../src/extensions'
import link from '../src/linker'
import { Environment, Environment as EnvironmentType, Name, Node, Package, Reference, SourceIndex } from '../src/model'
import { Environment as EnvironmentType, Name, Node, Package, Reference, SourceIndex } from '../src/model'
import { ParseError } from '../src/parser'
import validate, { Validation } from '../src/validator'

Expand Down Expand Up @@ -145,7 +145,7 @@ export const linkerAssertions: Chai.ChaiPlugin = ({ Assertion }) => {
Assertion.addMethod('linkedInto', function (expected: List<Package>) {
const dropLinkedFields = dropKeys('id', 'scope')
const actualEnvironment = link(this._obj)
const expectedEnvironment = new Environment({ members: expected })
const expectedEnvironment = link(expected)

new Assertion(dropLinkedFields(actualEnvironment)).to.deep.equal(dropLinkedFields(expectedEnvironment))
})
Expand Down
30 changes: 13 additions & 17 deletions test/dynamicDiagram.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { BOOLEAN_MODULE, buildEnvironment, CLOSURE_MODULE, DATE_MODULE, DICTIONA
import { DynamicDiagramElement, DynamicDiagramNode, DynamicDiagramReference } from '../src/interpreter/dynamicDiagram'
import { interprete, Interpreter } from '../src/interpreter/interpreter'
import linker from '../src/linker'
import { WREEnvironment } from './utils'
import { environmentWithREPLInitializedFile, INIT_PACKAGE_NAME, WREEnvironment } from './utils'

describe('Dynamic diagram', () => {

Expand Down Expand Up @@ -245,8 +245,7 @@ describe('Dynamic diagram', () => {
})

it('should include bidirectional relationships', () => {
const replEnvironment = buildEnvironment([{
name: REPL, content: `
const replEnvironment = environmentWithREPLInitializedFile(`
class Ave {
var property amigue = null
method tieneEnergia() = energia > 0
Expand All @@ -255,8 +254,7 @@ describe('Dynamic diagram', () => {
object pepita inherits Ave {
override method tieneEnergia() = true
}
`,
}])
`)
interpreter = new Interpreter(Evaluation.build(replEnvironment, WRENatives))
interprete(interpreter, 'const pepona = new Ave(amigue = pepita)')
interprete(interpreter, 'pepita.amigue(pepona)')
Expand All @@ -265,36 +263,34 @@ describe('Dynamic diagram', () => {
referenceLabel: 'pepona',
targetLabel: 'Ave',
targetType: 'object',
targetModule: 'REPL.Ave',
targetModule: INIT_PACKAGE_NAME + '.Ave',
})
checkConnection(elements, {
sourceLabel: 'Ave',
referenceLabel: 'amigue',
targetLabel: 'pepita',
targetType: 'object',
sourceModule: 'REPL.Ave',
targetModule: 'REPL.pepita',
sourceModule: INIT_PACKAGE_NAME + '.Ave',
targetModule: INIT_PACKAGE_NAME + '.pepita',
})
checkConnection(elements, {
sourceLabel: 'pepita',
referenceLabel: 'amigue',
targetLabel: 'Ave',
targetType: 'object',
sourceModule: 'REPL.pepita',
targetModule: 'REPL.Ave',
sourceModule: INIT_PACKAGE_NAME + '.pepita',
targetModule: INIT_PACKAGE_NAME + '.Ave',
})
checkNoConnectionToREPL(elements, 'pepita')
})

it('should include recursive relationships', () => {
const replEnvironment = buildEnvironment([{
name: REPL, content: `
const replEnvironment = environmentWithREPLInitializedFile(`
class Ave {
var property amigue = null
override method tieneEnergia() = true
}
`,
}])
`)
interpreter = new Interpreter(Evaluation.build(replEnvironment, WRENatives))
interprete(interpreter, 'const pepita = new Ave()')
interprete(interpreter, 'pepita.amigue(pepita)')
Expand All @@ -303,15 +299,15 @@ describe('Dynamic diagram', () => {
referenceLabel: 'pepita',
targetLabel: 'Ave',
targetType: 'object',
targetModule: 'REPL.Ave',
targetModule: INIT_PACKAGE_NAME + '.Ave',
})
checkConnection(elements, {
sourceLabel: 'Ave',
referenceLabel: 'amigue',
targetLabel: 'Ave',
targetType: 'object',
sourceModule: 'REPL.Ave',
targetModule: 'REPL.Ave',
sourceModule: INIT_PACKAGE_NAME + '.Ave',
targetModule: INIT_PACKAGE_NAME + '.Ave',
})

})
Expand Down
16 changes: 7 additions & 9 deletions test/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect, should, use } from 'chai'
import sinonChai from 'sinon-chai'
import { BOOLEAN_MODULE, Body, Class, Describe, Environment, Evaluation, Field, Import, Interpreter, isError, LIST_MODULE, Literal, Method, methodByFQN, NUMBER_MODULE, New, OBJECT_MODULE, Package, Parameter, Reference, STRING_MODULE, Self, Send, Singleton, Test, Variable, WRENatives, allAvailableMethods, allScopedVariables, allVariables, implicitImport, isNamedSingleton, isNotImportedIn, link, linkSentenceInNode, literalValueToClass, mayExecute, parentModule, parse, projectPackages, hasNullValue, hasBooleanValue, projectToJSON, getNodeDefinition, ParameterizedType, sendDefinitions, Super, SourceMap, isVoid, VOID_WKO, REPL, buildEnvironment, assertNotVoid, showParameter, getMethodContainer, Program, getExpressionFor, Expression, If, Return } from '../src'
import { WREEnvironment, environmentWithEntities } from './utils'
import { WREEnvironment, environmentWithEntities, environmentWithREPLInitializedFile } from './utils'
import { RuntimeObject } from '../src/interpreter/runtimeModel'

use(sinonChai)
Expand Down Expand Up @@ -131,10 +131,10 @@ describe('Wollok helpers', () => {

it('should return the right package from an environment', () => {
const environment = basicEnvironmentWithSingleClass()
const mainPackage = environment.getNodeByFQN('aves')
projectPackages(environment).should.deep.equal([mainPackage])
const mainPackage = environment.getNodeByFQN<Package>('aves')
projectPackages(environment).includes(mainPackage)
projectPackages(environment).includes(environment.replNode())
})

})

describe('isNotImportedIn', () => {
Expand Down Expand Up @@ -894,8 +894,7 @@ describe('Wollok helpers', () => {
})

describe('getExpression', () => {
const replEnvironment = buildEnvironment([{
name: REPL, content: `
const replEnvironment = environmentWithREPLInitializedFile(`
object pajarito {
energia = 100
contenta = false
Expand All @@ -916,9 +915,8 @@ describe('Wollok helpers', () => {
method bad() {
throw new Exception(message = "Do not call me!")
}
}`,
},
])
}`
)

it('should show if expression', () => {
const birdSingleton = replEnvironment.getNodeByFQN(REPL + '.pajarito') as Singleton
Expand Down
Loading

0 comments on commit ac6adb4

Please sign in to comment.