Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #292 Error poco claro cuando se omite el receptor de un mensaje #295

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { log } from 'console'
import Parsimmon, { alt as alt_parser, any, Index, index, lazy, makeSuccess, newline, notFollowedBy, of, Parser, regex, seq, seqObj, string, whitespace } from 'parsimmon'
import Parsimmon, { alt as alt_parser, any, Index, index, lazy, makeSuccess, newline, notFollowedBy, of, Parser, regex, seq, seqObj, string, succeed, whitespace } from 'parsimmon'

Check warning on line 2 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

'succeed' is defined but never used

Check warning on line 2 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

'succeed' is defined but never used
import unraw from 'unraw'
import { ASSIGNATION_OPERATORS, INFIX_OPERATORS, KEYWORDS, LIST_MODULE, PREFIX_OPERATORS, SET_MODULE } from './constants'
import { discriminate, hasWhitespace, is, List, mapObject } from './extensions'
Expand All @@ -19,6 +19,7 @@
export const MALFORMED_ENTITY = 'malformedEntity'
export const MALFORMED_MEMBER = 'malformedMember'
export const MALFORMED_SENTENCE = 'malformedSentence'
export const MALFORMED_MESSAGE_SEND = 'malformedMessageSend'
PalumboN marked this conversation as resolved.
Show resolved Hide resolved

export class ParseError implements BaseProblem {
constructor(public code: Name, public sourceMap: SourceMap) { }
Expand Down Expand Up @@ -103,6 +104,11 @@
const comment = (position: 'start' | 'end' | 'inner') => lazy('comment', () => regex(/\/\*(.|[\r\n])*?\*\/|\/\/.*/)).map(text => new Annotation('comment', { text, position }))
const sameLineComment: Parser<Annotation> = spaces.then(comment('end'))

const withSameLineComment = <T extends Node>(result: T): Parser<T> =>

Check warning on line 107 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 107 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed
optional(sameLineComment).map(comment => comment
? result.copy({ metadata: result.metadata.concat(comment) })

Check warning on line 109 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Expected indentation of 4 spaces but found 6

Check warning on line 109 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Expected indentation of 4 spaces but found 6
: result)

Check warning on line 110 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Expected indentation of 4 spaces but found 6

Check warning on line 110 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Expected indentation of 4 spaces but found 6

export const sanitizeWhitespaces = (originalFrom: SourceIndex, originalTo: SourceIndex, input: string): [SourceIndex, SourceIndex] => {
const EOL = input.includes('\r\n') ? '\r\n' : '\n'
const hasLineBreaks = (aString: string) => aString.includes(EOL)
Expand Down Expand Up @@ -227,7 +233,8 @@
sentences: alt(
Sentence.skip(__),
comment('inner').wrap(_, _),
sentenceError).many(),
sentenceError
).many(),
}).wrap(key('{'), lastKey('}')).map(recover)
)

Expand Down Expand Up @@ -452,12 +459,35 @@

const postfixMessageChain: Parser<ExpressionNode> = lazy(() =>
messageChain(
primaryExpression,
postfixMessageChainInitialReceiver,
key('.').then(name),
alt(unamedArguments, Closure.times(1))
)
)

const postfixMessageChainInitialReceiver: Parser<ExpressionNode & { problems?: List<BaseProblem> }> = lazy(() =>

Check warning on line 468 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 468 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed
alt(
primaryExpression,
obj({
markedMessage: name.mark(),
args: alt(unamedArguments, Closure.times(1)),
}).mark().chain(({
start,
end,
value: {

Check warning on line 477 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 477 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed
markedMessage: { value: message, start: errorStart, end: errorEnd },

Check warning on line 478 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 478 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed
args

Check warning on line 479 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 479 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Missing trailing comma

Check warning on line 479 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 479 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Missing trailing comma
},
}) => Parsimmon((input: string, i: number) => makeSuccess(i, new SendNode({
receiver: new LiteralNode({ value: null }),
message,

Check warning on line 483 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed

Check warning on line 483 in src/parser.ts

View workflow job for this annotation

GitHub Actions / build

Trailing spaces not allowed
args,
problems: [new ParseError(MALFORMED_MESSAGE_SEND, buildSourceMap(errorStart, errorEnd))],
sourceMap: buildSourceMap(...sanitizeWhitespaces(start, end, input))
}))))
).chain(withSameLineComment)
)

const messageChain = (receiver: Parser<ExpressionNode>, message: Parser<Name>, args: Parser<List<ExpressionNode>>): Parser<ExpressionNode> => lazy(() =>
seq(
index,
Expand Down Expand Up @@ -498,7 +528,6 @@
)
})


export const Self: Parser<SelfNode> = node(SelfNode)(() =>
key(KEYWORDS.SELF).result({})
)
Expand Down
71 changes: 66 additions & 5 deletions test/parser.test.ts
PalumboN marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ describe('Wollok parser', () => {
}))
})

it('comments after malformed sends should be parsed', () => {
'vola() //some comment'
.should.be.parsedBy(parse.Send)
.recoveringFrom(parse.MALFORMED_MESSAGE_SEND, 0, 4)
.into(new Send({
receiver: new Literal({ value: null }),
message: 'vola',
metadata: [new Annotation('comment', { text: '//some comment', position: 'end' })],
}))
})

it('comments after variable should be parsed', () => {
'const a = 1 //some comment'
.should.be.parsedBy(parse.Variable).into(new Variable({
Expand Down Expand Up @@ -2723,16 +2734,66 @@ class c {}`
'a.'.should.not.be.parsedBy(parser)
})

it('should not parse a call to a method without the reference that is calling', () => {
'm(p,q)'.should.not.be.parsedBy(parser)
})

it('should not parse an expression with a "." at the start', () => {
'.m'.should.not.be.parsedBy(parser)
})

})
it('should recover from malformed message send without arguments', () => {
`m()`.should.be.parsedBy(parser)
.recoveringFrom(parse.MALFORMED_MESSAGE_SEND, 0, 1)
Comment on lines +2741 to +2743
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Y qué onda con una chain onda m1().m2()? Entiendo que era el caso del TODO anterior, no?

.into(new Send({
receiver: new Literal({ value: null }),
message: 'm',
args: [],
}))
})

it('should recover from malformed message send with one argument', () => {
`m(p)`.should.be.parsedBy(parser)
.recoveringFrom(parse.MALFORMED_MESSAGE_SEND, 0, 1)
.into(new Send({
receiver: new Literal({ value: null }),
message: 'm',
args: [ new Reference({ name: 'p' }) ],
}))
})

it('should recover from malformed message send with multiple arguments', () => {
'm(p,q)'.should.be.parsedBy(parser)
.recoveringFrom(parse.MALFORMED_MESSAGE_SEND, 0, 1)
.into(new Send({
receiver: new Literal({ value: null }),
message: 'm',
args: [
new Reference({ name: 'p' }),
new Reference({ name: 'q' })
],
}))
})

it('should parse malformed message sends with a closure as an argument', () => {
'm1 {p => p}'.should.be.parsedBy(parser)
.recoveringFrom(parse.MALFORMED_MESSAGE_SEND, 0, 2)
.into(
new Send({
receiver: new Literal({ value: null }),
message: 'm1',
args: [
Closure({
parameters: [new Parameter({ name: 'p' })],
sentences: [new Return({ value: new Reference({ name: 'p' }) })],
code: '{p => p}',
}),
],
})
)
.and.exist.tracedTo(0,11)
.and.have.nested.property('args.0').tracedTo(3, 11)
.and.also.have.nested.property('args.0.members.0.parameters.0').tracedTo(4, 5)
.and.also.have.nested.property('args.0.members.0.body.sentences.0.value').tracedTo(9, 10)
})

})

describe('New', () => {

Expand Down
Loading