Skip to content

Commit

Permalink
feat: semantic highlighting support (#640)
Browse files Browse the repository at this point in the history
* feat: add semantic token

* fix: custom token and enhancment

* fix: unit tests

* fix: coverage

* chore: change set

* fix: no semantic for none xml view files
  • Loading branch information
marufrasully authored Jul 25, 2023
1 parent 0fe9a18 commit 2c71dfa
Show file tree
Hide file tree
Showing 35 changed files with 1,752 additions and 292 deletions.
8 changes: 8 additions & 0 deletions .changeset/curvy-worms-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@ui5-language-assistant/vscode-ui5-language-assistant-bas-ext": patch
"vscode-ui5-language-assistant": patch
"@ui5-language-assistant/binding-parser": patch
"@ui5-language-assistant/binding": patch
---

add semantic highlighting support
3 changes: 2 additions & 1 deletion packages/binding-parser/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export {
isBindingExpression,
isMetadataPath,
isModel,
isPropertyBindingInfo,
isBindingAllowed,
extractBindingSyntax,
} from "./utils";

import {
Expand Down
2 changes: 1 addition & 1 deletion packages/binding-parser/src/lexer/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const colon = createToken({
});
const stringValue = createToken({
name: STRING_VALUE,
pattern: /(?:'|"|'|")(?:.*?)(?:'|"|'|")/,
pattern: /(?:'|"|'|")(\\'|\\"|.)*?(?:'|"|'|")/,
});

const booleanValue = createToken({
Expand Down
6 changes: 6 additions & 0 deletions packages/binding-parser/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
export * as BindingParserTypes from "./binding-parser";

export interface ExtractBindingSyntax {
startIndex: number;
endIndex: number;
expression: string;
}
69 changes: 67 additions & 2 deletions packages/binding-parser/src/utils/expression.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ExtractBindingSyntax } from "../types";
import type {
ParseResultErrors,
StructureValue,
Expand Down Expand Up @@ -92,7 +93,7 @@ export const isMetadataPath = (
};

/**
* An input is considered property binding syntax when
* An input is considered as an allowed binding when
*
* a. is empty curly bracket e.g `{}` or `{ }`
*
Expand All @@ -104,7 +105,7 @@ export const isMetadataPath = (
*
* e. is not OData path e.g {/path/to/...} or {path/to/...}
*/
export const isPropertyBindingInfo = (
export const isBindingAllowed = (
input: string,
binding?: StructureValue,
errors?: ParseResultErrors
Expand Down Expand Up @@ -146,3 +147,67 @@ export const isPropertyBindingInfo = (
}
return false;
};

/**
* Regular expression to extract binding syntax.
*
* Also handles escaping of '{' and '}'.
*/
// eslint-disable-next-line no-useless-escape
const start = /(\\[\\\{\}])|(\{)/g;
// eslint-disable-next-line no-useless-escape
const end = /(\\[\\\{\}])|(\})/g;

export const extractBindingSyntax = (input: string): ExtractBindingSyntax[] => {
const result: ExtractBindingSyntax[] = [];
let startRegResult: RegExpExecArray | null;
let endRegResult: RegExpExecArray | null;
// resetting
start.lastIndex = 0;
let startIndex = 0;
let lastIndex = 0;
let endIndex = 0;
const text = input;
if (text.trim() === "") {
return [{ startIndex, endIndex, expression: input }];
}
while ((startRegResult = start.exec(input)) !== null) {
// scape special chars
if (startRegResult[1]) {
continue;
}
const startInput = input.slice(startRegResult.index);
// collect all closing bracket(s)
end.lastIndex = 0;
while ((endRegResult = end.exec(startInput)) !== null) {
// scape special chars
if (endRegResult[1]) {
break;
}
lastIndex = endRegResult.index;
}
if (lastIndex === startRegResult.index) {
// missing closing bracket
const expression = startInput.slice(0, input.length);
result.push({
startIndex: startRegResult.index,
endIndex: input.length,
expression,
});
input = startInput.slice(input.length);
} else {
const expression = startInput.slice(0, lastIndex + 1);
startIndex = endIndex + startRegResult.index;
endIndex = startIndex + lastIndex + 1;
result.push({
startIndex,
endIndex,
expression,
});
input = startInput.slice(lastIndex + 1);
// resetting
start.lastIndex = 0;
}
}
return result;
};
3 changes: 2 additions & 1 deletion packages/binding-parser/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export {
isBindingExpression,
isMetadataPath,
isModel,
isPropertyBindingInfo,
isBindingAllowed,
extractBindingSyntax,
} from "./expression";
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"bindings": [
{
"leftCurly": {
"type": "left-curly",
"text": "{",
"range": "[(0,0)..(0,1)]"
},
"elements": [
{
"key": {
"type": "key",
"text": "$filter",
"range": "[(1,4)..(1,11)]",
"originalText": "$filter"
},
"colon": {
"type": "colon",
"text": ":",
"range": "[(1,12)..(1,13)]"
},
"value": {
"type": "string-value",
"text": "\"TravelStatus_code eq \\\"O\\\" and IsActiveEntity eq false or SiblingEntity/IsActiveEntity eq null\"",
"range": "[(1,14)..(1,110)]"
},
"range": "[(1,4)..(1,110)]",
"type": "structure-element"
}
],
"rightCurly": {
"type": "right-curly",
"text": "}",
"range": "[(2,0)..(2,1)]"
},
"range": "[(0,0)..(2,1)]",
"commas": [],
"type": "structure-value"
}
],
"spaces": [
{
"type": "white-space",
"text": "\n ",
"range": "[(0,1)..(1,4)]"
},
{
"type": "white-space",
"text": " ",
"range": "[(1,11)..(1,12)]"
},
{
"type": "white-space",
"text": " ",
"range": "[(1,13)..(1,14)]"
},
{
"type": "white-space",
"text": "\n",
"range": "[(1,110)..(1,111)]"
}
],
"type": "template"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"name": "template",
"children": {
"object": [
{
"name": "object",
"children": {
"left-curly": [
{
"image": "{",
"startColumn": 1,
"endColumn": 1,
"tokenTypeName": "left-curly"
}
],
"object-item": [
{
"name": "object-item",
"children": {
"key": [
{
"image": "$filter",
"startColumn": 5,
"endColumn": 11,
"tokenTypeName": "key"
}
],
"colon": [
{
"image": ":",
"startColumn": 13,
"endColumn": 13,
"tokenTypeName": "colon"
}
],
"value": [
{
"name": "value",
"children": {
"string-value": [
{
"image": "\"TravelStatus_code eq \\\"O\\\" and IsActiveEntity eq false or SiblingEntity/IsActiveEntity eq null\"",
"startColumn": 15,
"endColumn": 110,
"tokenTypeName": "string-value"
}
]
},
"location": {
"startColumn": 15,
"endColumn": 110
}
}
]
},
"location": {
"startColumn": 5,
"endColumn": 110
}
}
],
"right-curly": [
{
"image": "}",
"startColumn": 1,
"endColumn": 1,
"tokenTypeName": "right-curly"
}
]
},
"location": {
"startColumn": 1,
"endColumn": 1
}
}
]
},
"location": {
"startColumn": 1,
"endColumn": 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
$filter : "TravelStatus_code eq \"O\" and IsActiveEntity eq false or SiblingEntity/IsActiveEntity eq null"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"bindings": [
{
"leftCurly": {
"type": "left-curly",
"text": "{",
"range": "[(0,0)..(0,1)]"
},
"elements": [
{
"key": {
"type": "key",
"text": "$filter",
"range": "[(1,4)..(1,11)]",
"originalText": "$filter"
},
"colon": {
"type": "colon",
"text": ":",
"range": "[(1,12)..(1,13)]"
},
"value": {
"type": "string-value",
"text": "'TravelStatus_code eq \\'O\\' and IsActiveEntity eq false or SiblingEntity/IsActiveEntity eq null'",
"range": "[(1,14)..(1,110)]"
},
"range": "[(1,4)..(1,110)]",
"type": "structure-element"
}
],
"rightCurly": {
"type": "right-curly",
"text": "}",
"range": "[(2,0)..(2,1)]"
},
"range": "[(0,0)..(2,1)]",
"commas": [
{
"type": "comma",
"text": ",",
"range": "[(1,110)..(1,111)]"
}
],
"type": "structure-value"
}
],
"spaces": [
{
"type": "white-space",
"text": "\n ",
"range": "[(0,1)..(1,4)]"
},
{
"type": "white-space",
"text": " ",
"range": "[(1,11)..(1,12)]"
},
{
"type": "white-space",
"text": " ",
"range": "[(1,13)..(1,14)]"
},
{
"type": "white-space",
"text": "\n",
"range": "[(1,111)..(1,112)]"
}
],
"type": "template"
}
Loading

0 comments on commit 2c71dfa

Please sign in to comment.