-
-
Notifications
You must be signed in to change notification settings - Fork 221
/
MessageCreator.php
132 lines (122 loc) · 5.84 KB
/
MessageCreator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
declare(strict_types=1);
namespace Neos\Fusion\Core\ObjectTreeParser\ExceptionMessage;
/*
* This file is part of the Neos.Fusion package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/
/**
* Creates exception messages for the Fusion parser
* @internal
*/
class MessageCreator
{
protected const VALID_OBJECT_PATH = "A valid object path is by '.' delimited path segments: alphanumeric and [:_-], prototype(Foo:Bar), in quotes, or a meta path starting with '@'.";
public static function forParseStatement(MessageLinePart $next, MessageLinePart $prev): string
{
switch ($next->char()) {
case '/':
if ($next->char(1) === '*') {
return "Unclosed comment.";
}
return "Unexpected single {$next->charPrint()}. You can start a comment with '//' or '/*' or '#'.";
case '"':
case '\'':
return "Unclosed quoted path.";
case '{':
return "Unexpected block start. The opening brace must be on the same line with its declaration, like: 'path {' or 'prototype(Foo:Bar) {'.";
case '}':
return "Unexpected block end. Check your number of curly braces.";
}
return "Unexpected statement starting with: {$next->charPrint()}. " . self::VALID_OBJECT_PATH;
}
public static function forParseEndOfStatement(MessageLinePart $next, MessageLinePart $prev): string
{
switch ($next->char()) {
case '/':
if ($next->char(1) === '*') {
return "Unclosed comment.";
}
return "Unexpected single {$next->charPrint()}. You can start a comment with '//' or '/*' or '#'.";
}
return "Expected end of a statement but found {$next->linePrint()}.";
}
public static function forParsePathSegment(MessageLinePart $next, MessageLinePart $prev): string
{
switch ($next->char()) {
case '"':
case '\'':
return "A quoted object path starting with {$next->charPrint()} was not closed.";
case ' ':
if ($prev->char(-1) === '.') {
return "No <space> is allowed after a separating '.' in an object path.";
}
return "Unexpected {$next->charPrint()} in object path.";
}
return "Unexpected object path starting with: {$next->charPrint()}. " . self::VALID_OBJECT_PATH;
}
public static function forPathSegmentPrototypeName(MessageLinePart $next, MessageLinePart $prev): string
{
if (preg_match('/^[a-zA-Z0-9.]++(?!:)/', $next->line()) === 1) {
return "Prototype name without namespace starting with {$next->charPrint()} - Default namespaces were removed. You might want to add 'Neos.Fusion:' in front.";
}
if (str_starts_with(trim($next->line()), ')')) {
return "A prototype name must be set. Unexpected char {$next->charPrint()}.";
}
return "Unexpected prototype name starting with: {$next->linePrint()}.";
}
public static function forParsePathOrOperator(MessageLinePart $next, MessageLinePart $prev): string
{
if (preg_match('/.*namespace\s*:\s*$/', $prev->line()) === 1) {
return "It looks like you want to declare a namespace alias. The feature to alias namespaces was removed.";
}
if (preg_match('/.*include\s*$/', $prev->line()) === 1) {
return "Did you want to include a Fusion file? 'include: FileName.fusion'.";
}
if ($prev->char(-1) === ' ' && $next->char() === '.') {
return "Nested paths, separated by {$next->charPrint()} cannot contain spaces.";
}
if ($prev->char(-1) === ' ') {
// it might be an operator since there was space
return "Unknown operator starting with {$next->charPrint()}. (Or you have unwanted spaces in your object path).";
}
if ($next->char() === '(') {
return "An unquoted path segment cannot contain {$next->charPrint()}. Did you want to declare a prototype? 'prototype(Foo:Bar)'.";
}
if ($next->char() === '') {
return "Object path without operator or block start. Found: {$next->charPrint()}.";
}
return "Unknown operator or path segment at {$next->charPrint()}. Unquoted paths can contain only alphanumerics and [:_-]. Otherwise, put them in quotes.";
}
public static function forParseDslExpression(MessageLinePart $next, MessageLinePart $prev): string
{
return "A dsl expression starting with {$next->linePrint(1)} was not closed.";
}
public static function forParsePathValue(MessageLinePart $next, MessageLinePart $prev): string
{
if (preg_match('/^[a-zA-Z0-9.]++(?!:)/', $next->line()) === 1) {
return "Unexpected {$next->linePrint()} in value assignment - It looks like an object without namespace. Default namespaces were removed. You might want to add 'Neos.Fusion:' in front.";
}
switch ($next->char()) {
case '':
return "No value specified in assignment.";
case '"':
return "Unclosed quoted string.";
case '\'':
return "Unclosed char sequence.";
case '`':
return "Template literals without DSL identifier are not supported.";
case '$':
if ($next->char(1) === '{') {
return "Unclosed eel expression.";
}
return "Did you want to start an eel expression: '\${...}'?";
}
return "Unexpected character in assignment starting with {$next->charPrint()}.";
}
}