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: Add type support for "byId" in controllers (#423)
This feature adds type definitions for `byId` within controllers so that the usage of deprecated functionality can be detected when controls or elements from the view are accessed by their ID. Previously, only the base element class was known, which is still the case as a fallback. JIRA: CPOUI5FOUNDATION-843
- Loading branch information
Showing
23 changed files
with
1,089 additions
and
81 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Multiple views/fragments can use the same ID and link to the same controller, | ||
// so we need to store a set of module names for each ID. | ||
export type IdModulesMap = Map<string, Set<string>>; | ||
|
||
type ControllerElementsMap = Map<string, IdModulesMap>; | ||
|
||
export default class ControllerByIdInfo { | ||
private map: ControllerElementsMap = new Map(); | ||
|
||
private getControllerMapping(controllerName: string) { | ||
let controllerMap = this.map.get(controllerName); | ||
if (!controllerMap) { | ||
controllerMap = new Map(); | ||
this.map.set(controllerName, controllerMap); | ||
} | ||
return controllerMap; | ||
} | ||
|
||
public addMappings(controllerName: string, idModuleMap: Map<string, string>) { | ||
// Do not add empty mappings | ||
if (!idModuleMap.size) { | ||
return; | ||
} | ||
const controllerMapping = this.getControllerMapping(controllerName); | ||
for (const [id, module] of idModuleMap) { | ||
let existingModules = controllerMapping.get(id); | ||
if (!existingModules) { | ||
existingModules = new Set(); | ||
controllerMapping.set(id, existingModules); | ||
} | ||
existingModules.add(module); | ||
} | ||
} | ||
|
||
public getMappings() { | ||
return this.map; | ||
} | ||
} |
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
70 changes: 70 additions & 0 deletions
70
src/linter/xmlTemplate/generator/ControllerByIdDtsGenerator.ts
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,70 @@ | ||
import ControllerByIdInfo, {IdModulesMap} from "../ControllerByIdInfo.js"; | ||
|
||
export class ControllerByIdDtsGenerator { | ||
// Maps module names to local names | ||
private imports = new Map<string, string>(); | ||
|
||
generate(controllerByIdInfo: ControllerByIdInfo) { | ||
const mappings = controllerByIdInfo.getMappings(); | ||
if (!mappings.size) { | ||
return null; | ||
} | ||
this.imports = new Map<string, string>(); | ||
this.addImport("sap/ui/core/mvc/View"); // View is needed for interface ControllerView | ||
this.addImport("sap/ui/core/Element"); // Element is needed for byId fallback signature | ||
let out = ""; | ||
mappings.forEach((idToModules, controllerName) => { | ||
out += this.generateModuleDeclaration(controllerName, idToModules); | ||
}); | ||
return this.generateCollectedImports() + out; | ||
} | ||
|
||
private generateCollectedImports() { | ||
return Array.from(this.imports.entries()) | ||
.map(([moduleName, localName]) => `import ${localName} from "${moduleName}";`) | ||
.join("\n") + "\n"; | ||
} | ||
|
||
private generateByIdMapping(idToModules: IdModulesMap) { | ||
let out = "interface ByIdMapping {\n"; | ||
idToModules.forEach((modules, id) => { | ||
const localNames = Array.from(modules).map((moduleName: string) => this.addImport(moduleName)); | ||
out += `\t\t"${id}": ${localNames.join(" | ")};\n`; | ||
}); | ||
out += "\t}"; | ||
return out; | ||
} | ||
|
||
private generateModuleDeclaration(controllerName: string, idToModules: IdModulesMap) { | ||
const moduleName = controllerName.replace(/\./g, "/") + ".controller"; | ||
|
||
return ` | ||
declare module "${moduleName}" { | ||
${this.generateByIdMapping(idToModules)} | ||
type ByIdFunction = { | ||
<T extends keyof ByIdMapping>(sId: T): ByIdMapping[T]; | ||
(sId: string): ${this.imports.get("sap/ui/core/Element")}; | ||
} | ||
interface ControllerView extends ${this.imports.get("sap/ui/core/mvc/View")} { | ||
byId: ByIdFunction; | ||
} | ||
export default interface Controller { | ||
byId: ByIdFunction; | ||
getView(): ControllerView; | ||
} | ||
} | ||
`; | ||
} | ||
|
||
private addImport(moduleName: string) { | ||
const localName = this.getLocalModuleName(moduleName); | ||
if (!this.imports.has(moduleName)) { | ||
this.imports.set(moduleName, localName); | ||
} | ||
return localName; | ||
} | ||
|
||
private getLocalModuleName(moduleName: string) { | ||
return moduleName.replace(/[/.]/g, "_"); | ||
} | ||
} |
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
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
17 changes: 17 additions & 0 deletions
17
test/fixtures/linter/projects/com.ui5.troublesome.app/webapp/view/DesktopMain.view.xml
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,17 @@ | ||
<!-- | ||
This file is a partial copy of Main.view.xml but uses other controls. | ||
Its purpose is to cover the case where multiple views refer to | ||
the same controller (controllerName) and contain controls with | ||
the same ID but a different type. The resulting type for the | ||
controller byId() call should be the union of the types. | ||
--> | ||
<mvc:View | ||
controllerName="com.ui5.troublesome.app.controller.Main" | ||
displayBlock="true" | ||
xmlns="sap.ui.commons" | ||
xmlns:mvc="sap.ui.core.mvc" | ||
xmlns:core="sap.ui.core"> | ||
|
||
<Button id="testButton" /> | ||
|
||
</mvc:View> |
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 |
---|---|---|
|
@@ -23,4 +23,6 @@ | |
</buttons> | ||
</MessagePage> | ||
|
||
<Button id="testButton" /> | ||
|
||
</mvc:View> |
Oops, something went wrong.