diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-02-02 16:28:19 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-02-02 17:36:24 +0100 |
commit | 2dfcb286216419976368ad926f8ac7f018aa2bf9 (patch) | |
tree | b9d235ebf2049e42e58126e743c782333d64681a /subprojects/frontend | |
parent | refactor: serialize solutions as modules (diff) | |
download | refinery-2dfcb286216419976368ad926f8ac7f018aa2bf9.tar.gz refinery-2dfcb286216419976368ad926f8ac7f018aa2bf9.tar.zst refinery-2dfcb286216419976368ad926f8ac7f018aa2bf9.zip |
refactor(language): name disambiguation
* Use fully qualified names starting with :: (as in C++) to unambiguously refer
to an element.
* Name shadowing within modules.
Diffstat (limited to 'subprojects/frontend')
-rw-r--r-- | subprojects/frontend/src/editor/EditorTheme.ts | 4 | ||||
-rw-r--r-- | subprojects/frontend/src/language/problem.grammar | 11 | ||||
-rw-r--r-- | subprojects/frontend/src/language/problemLanguageSupport.ts | 4 | ||||
-rw-r--r-- | subprojects/frontend/src/language/tokens.ts | 46 | ||||
-rw-r--r-- | subprojects/frontend/src/xtext/ContentAssistService.ts | 8 | ||||
-rw-r--r-- | subprojects/frontend/types/grammar.d.ts | 6 |
6 files changed, 71 insertions, 8 deletions
diff --git a/subprojects/frontend/src/editor/EditorTheme.ts b/subprojects/frontend/src/editor/EditorTheme.ts index f499b0d9..4978c7f7 100644 --- a/subprojects/frontend/src/editor/EditorTheme.ts +++ b/subprojects/frontend/src/editor/EditorTheme.ts | |||
@@ -40,7 +40,9 @@ function createTypeHashStyles( | |||
40 | export default styled('div', { | 40 | export default styled('div', { |
41 | name: 'EditorTheme', | 41 | name: 'EditorTheme', |
42 | shouldForwardProp: (propName) => | 42 | shouldForwardProp: (propName) => |
43 | propName !== 'showLineNumbers' && propName !== 'showActiveLine', | 43 | propName !== 'showLineNumbers' && |
44 | propName !== 'showActiveLine' && | ||
45 | propName !== 'colorIdentifiers', | ||
44 | })<{ | 46 | })<{ |
45 | showLineNumbers: boolean; | 47 | showLineNumbers: boolean; |
46 | showActiveLine: boolean; | 48 | showActiveLine: boolean; |
diff --git a/subprojects/frontend/src/language/problem.grammar b/subprojects/frontend/src/language/problem.grammar index ac451e7a..e39ce102 100644 --- a/subprojects/frontend/src/language/problem.grammar +++ b/subprojects/frontend/src/language/problem.grammar | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -22,6 +22,9 @@ | |||
22 | @top Problem { statement* } | 22 | @top Problem { statement* } |
23 | 23 | ||
24 | statement { | 24 | statement { |
25 | ImportStatement { | ||
26 | kw<"import"> QualifiedName (kw<"as"> identifier)? "." | ||
27 | } | | ||
25 | Assertion { | 28 | Assertion { |
26 | kw<"default">? (NotOp | UnknownOp)? RelationName | 29 | kw<"default">? (NotOp | UnknownOp)? RelationName |
27 | ParameterList<AssertionArgument> | 30 | ParameterList<AssertionArgument> |
@@ -170,7 +173,7 @@ VariableName[@dynamicPrecedence=10] { QualifiedName ~name } | |||
170 | 173 | ||
171 | NodeName { QualifiedName } | 174 | NodeName { QualifiedName } |
172 | 175 | ||
173 | QualifiedName[implicitCompletion=true] { identifier ("::" identifier)* } | 176 | QualifiedName[implicitCompletion=true] { "::"? identifier (QualifiedNameSeparator "::" identifier)* } |
174 | 177 | ||
175 | kw<term> { @specialize[@name={term},implicitCompletion=true]<identifier, term> } | 178 | kw<term> { @specialize[@name={term},implicitCompletion=true]<identifier, term> } |
176 | 179 | ||
@@ -184,6 +187,10 @@ sep1<separator, content> { content (separator content)* } | |||
184 | 187 | ||
185 | @skip { LineComment | BlockComment | whitespace } | 188 | @skip { LineComment | BlockComment | whitespace } |
186 | 189 | ||
190 | @external tokens qualifiedNameSeparator from "./tokens" { | ||
191 | QualifiedNameSeparator | ||
192 | } | ||
193 | |||
187 | @tokens { | 194 | @tokens { |
188 | whitespace { std.whitespace+ } | 195 | whitespace { std.whitespace+ } |
189 | 196 | ||
diff --git a/subprojects/frontend/src/language/problemLanguageSupport.ts b/subprojects/frontend/src/language/problemLanguageSupport.ts index 2483c2e3..aebccfa4 100644 --- a/subprojects/frontend/src/language/problemLanguageSupport.ts +++ b/subprojects/frontend/src/language/problemLanguageSupport.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -28,7 +28,7 @@ const parserWithMetadata = parser.configure({ | |||
28 | LineComment: t.lineComment, | 28 | LineComment: t.lineComment, |
29 | BlockComment: t.blockComment, | 29 | BlockComment: t.blockComment, |
30 | 'module problem class enum pred fn scope': t.definitionKeyword, | 30 | 'module problem class enum pred fn scope': t.definitionKeyword, |
31 | 'declare atom multi': t.definitionKeyword, | 31 | 'import as declare atom multi': t.definitionKeyword, |
32 | 'abstract extends refers contains container opposite': t.modifier, | 32 | 'abstract extends refers contains container opposite': t.modifier, |
33 | 'default error contained containment': t.modifier, | 33 | 'default error contained containment': t.modifier, |
34 | 'true false unknown error': t.keyword, | 34 | 'true false unknown error': t.keyword, |
diff --git a/subprojects/frontend/src/language/tokens.ts b/subprojects/frontend/src/language/tokens.ts new file mode 100644 index 00000000..b5d022f1 --- /dev/null +++ b/subprojects/frontend/src/language/tokens.ts | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2018-2024 by Marijn Haverbeke <marijnh@gmail.com> and others | ||
3 | * Copyright (C) 2024 The Refinery Authors <https://refinery.tools/> | ||
4 | * | ||
5 | * SPDX-License-Identifier: MIT AND EPL-2.0 | ||
6 | * | ||
7 | * Based on the CSS tokenizer at | ||
8 | * https://github.com/lezer-parser/css/blob/790568c968a660a94bf0fbd97a86c66da1c529e5/src/tokens.js | ||
9 | */ | ||
10 | |||
11 | import { ExternalTokenizer } from '@lezer/lr'; | ||
12 | |||
13 | /* eslint-disable-next-line import/no-unresolved -- | ||
14 | Synthetic import from `@lezer/generator/rollup` cannot be found by ESLint. | ||
15 | */ | ||
16 | import { QualifiedNameSeparator } from './problem.grammar.terms'; | ||
17 | |||
18 | const colon = 58; | ||
19 | const underscore = 95; | ||
20 | |||
21 | function isAlpha(ch: number) { | ||
22 | return (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122) || ch >= 161; | ||
23 | } | ||
24 | |||
25 | function isDigit(ch: number) { | ||
26 | return ch >= 48 && ch <= 57; | ||
27 | } | ||
28 | |||
29 | function isIdentifier(ch: number) { | ||
30 | return isAlpha(ch) || isDigit(ch) || ch === underscore; | ||
31 | } | ||
32 | |||
33 | /* eslint-disable-next-line import/prefer-default-export -- | ||
34 | Lezer requires a named export. | ||
35 | */ | ||
36 | export const qualifiedNameSeparator = new ExternalTokenizer((input) => { | ||
37 | if (input.peek(0) === colon && input.peek(1) === colon) { | ||
38 | const previous = input.peek(-1); | ||
39 | if (isIdentifier(previous)) { | ||
40 | // Inject an extra 0-length token into the token stream to let Lezer | ||
41 | // consume the `::` on its own. Explicitly consuming 2 characters here | ||
42 | // leads to inconsistent highlighting of qualified names. | ||
43 | input.acceptToken(QualifiedNameSeparator); | ||
44 | } | ||
45 | } | ||
46 | }); | ||
diff --git a/subprojects/frontend/src/xtext/ContentAssistService.ts b/subprojects/frontend/src/xtext/ContentAssistService.ts index ac8ab36a..d42dde14 100644 --- a/subprojects/frontend/src/xtext/ContentAssistService.ts +++ b/subprojects/frontend/src/xtext/ContentAssistService.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -108,7 +108,11 @@ function createCompletion(entry: ContentAssistEntry): Completion { | |||
108 | boost = -90; | 108 | boost = -90; |
109 | break; | 109 | break; |
110 | default: | 110 | default: |
111 | { | 111 | if (entry.proposal.startsWith('::')) { |
112 | // Move absolute names below relative names, | ||
113 | // they should only be preferred if no relative name is available. | ||
114 | boost = -60; | ||
115 | } else { | ||
112 | // Penalize qualified names (vs available unqualified names). | 116 | // Penalize qualified names (vs available unqualified names). |
113 | const extraSegments = entry.proposal.match(/::/g)?.length || 0; | 117 | const extraSegments = entry.proposal.match(/::/g)?.length || 0; |
114 | boost = Math.max(-5 * extraSegments, -50); | 118 | boost = Math.max(-5 * extraSegments, -50); |
diff --git a/subprojects/frontend/types/grammar.d.ts b/subprojects/frontend/types/grammar.d.ts index 92f99ec3..c7848e33 100644 --- a/subprojects/frontend/types/grammar.d.ts +++ b/subprojects/frontend/types/grammar.d.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others | 2 | * Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others |
3 | * Copyright (C) 2021-2023 The Refinery Authors <https://refinery.tools/> | 3 | * Copyright (C) 2021-2024 The Refinery Authors <https://refinery.tools/> |
4 | * | 4 | * |
5 | * SPDX-License-Identifier: MIT | 5 | * SPDX-License-Identifier: MIT |
6 | */ | 6 | */ |
@@ -10,3 +10,7 @@ declare module '*.grammar' { | |||
10 | 10 | ||
11 | export const parser: LRParser; | 11 | export const parser: LRParser; |
12 | } | 12 | } |
13 | |||
14 | declare module '*.terms' { | ||
15 | export const QualifiedNameSeparator: number; | ||
16 | } | ||