generated from SAP/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(binding): Detect global formatter notation in bindings
Reuse UI5 runtime Binding- and ExpressionParser to extract formatter definition and other information from bindings defined in JS or XML.
- Loading branch information
1 parent
48aeab0
commit 0845caf
Showing
23 changed files
with
2,814 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import LinterContext, {PositionInfo, ResourcePath} from "../LinterContext.js"; | ||
import {MESSAGE} from "../messages.js"; | ||
import {RequireDeclaration} from "../xmlTemplate/Parser.js"; | ||
import BindingParser, {BindingInfo} from "./lib/BindingParser.js"; | ||
|
||
export default class BindingLinter { | ||
#resourcePath: string; | ||
#context: LinterContext; | ||
|
||
constructor(resourcePath: ResourcePath, context: LinterContext) { | ||
this.#resourcePath = resourcePath; | ||
this.#context = context; | ||
} | ||
|
||
#parseBinding(binding: string): BindingInfo { | ||
const bindingInfo = BindingParser.complexParser(binding, null, true, true, true, true); | ||
return bindingInfo; | ||
} | ||
|
||
#analyzeBinding(bindingInfo: BindingInfo, requireDeclarations: RequireDeclaration[], position: PositionInfo) { | ||
const {formatter, events} = bindingInfo; | ||
if (formatter) { | ||
this.#checkForGlobalReference(formatter, requireDeclarations, position); | ||
} | ||
if (events && typeof events === "object") { | ||
for (const eventHandler of Object.values(events)) { | ||
this.#checkForGlobalReference(eventHandler, requireDeclarations, position); | ||
} | ||
} | ||
} | ||
|
||
#checkForGlobalReference(ref: string, requireDeclarations: RequireDeclaration[], position: PositionInfo) { | ||
if (ref.startsWith(".")) { | ||
// Ignore empty reference or reference to the controller (as indicated by the leading dot) | ||
return false; | ||
} | ||
const parts = ref.split("."); | ||
let variableName; | ||
if (parts.length) { | ||
variableName = parts[0]; | ||
} else { | ||
variableName = ref; | ||
} | ||
const requireDeclaration = requireDeclarations.find((decl) => decl.variableName === variableName); | ||
if (requireDeclaration) { | ||
return false; | ||
} | ||
|
||
// Global reference detected | ||
this.#context.addLintingMessage(this.#resourcePath, MESSAGE.NO_GLOBALS, { | ||
variableName, | ||
namespace: ref, | ||
}, position); | ||
} | ||
|
||
lintPropertyBinding(bindingDefinition: string, requireDeclarations: RequireDeclaration[], position: PositionInfo) { | ||
try { | ||
const bindingInfo = this.#parseBinding(bindingDefinition); | ||
if (bindingInfo) { | ||
this.#analyzeBinding(bindingInfo, requireDeclarations, position); | ||
} | ||
} catch (err) { | ||
const message = err instanceof Error ? err.message : String(err); | ||
this.#context.addLintingMessage(this.#resourcePath, MESSAGE.PARSING_ERROR, {message}, position); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* This is a copy of the sap/ui/model/BindingMode.js module of the OpenUI5 project | ||
* https://github.com/SAP/openui5/blob/a4507f0d4f8a56cc881e8983479c8f9b21bfb96b/src/sap.ui.core/src/sap/ui/model/BindingMode.js | ||
*/ | ||
|
||
/** | ||
* Binding type definitions. | ||
* | ||
* @enum {string} | ||
* @public | ||
* @alias sap.ui.model.BindingMode | ||
*/ | ||
var BindingMode = { | ||
|
||
/** | ||
* BindingMode default means that the binding mode of the model is used | ||
* @public | ||
*/ | ||
Default: "Default", | ||
|
||
/** | ||
* BindingMode one time means value is only read from the model once | ||
* @public | ||
*/ | ||
OneTime: "OneTime", | ||
|
||
/** | ||
* BindingMode one way means from model to view | ||
* @public | ||
*/ | ||
OneWay: "OneWay", | ||
|
||
/** | ||
* BindingMode two way means from model to view and vice versa | ||
* @public | ||
*/ | ||
TwoWay: "TwoWay", | ||
|
||
}; | ||
|
||
export default BindingMode; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export interface BindingInfo { | ||
path?: string; | ||
model?: string; | ||
formatter?: string; | ||
events?: Record<string, string>; | ||
} | ||
|
||
interface BindingParser { | ||
complexParser: ( | ||
sString: string, | ||
oContext: object | null, | ||
bUnescape?: boolean, | ||
bTolerateFunctionsNotFound?: boolean, | ||
bStaticContext?: boolean, | ||
bPreferContext?: boolean, | ||
mLocals?: Record<string, string>, | ||
bResolveTypesAsync?: boolean | ||
) => BindingInfo; | ||
} | ||
|
||
declare const BindingParser: BindingParser; | ||
|
||
export default BindingParser; |
Oops, something went wrong.