696 lines
15 KiB
Markdown
696 lines
15 KiB
Markdown
# UI5 Linter - Complete Autofix Reference
|
|
|
|
**Source**: [https://github.com/UI5/linter/blob/main/docs/Scope-of-Autofix.md](https://github.com/UI5/linter/blob/main/docs/Scope-of-Autofix.md)
|
|
**Last Updated**: 2025-11-21
|
|
**UI5 Linter Version**: 1.20.5
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The UI5 Linter's autofix feature (`--fix` flag) can automatically correct certain categories of issues. However, the documentation explicitly states: **"This list is not exhaustive; there are more APIs that are currently not replaced automatically."**
|
|
|
|
This reference provides comprehensive coverage of what can and cannot be automatically fixed.
|
|
|
|
---
|
|
|
|
## Using Autofix
|
|
|
|
### Basic Usage
|
|
|
|
```bash
|
|
# Apply fixes to all files
|
|
ui5lint --fix
|
|
|
|
# Fix specific files
|
|
ui5lint --fix "webapp/**/*.js"
|
|
|
|
# Preview fixes without applying (dry-run mode)
|
|
UI5LINT_FIX_DRY_RUN=true ui5lint --fix
|
|
```
|
|
|
|
### Dry-Run Mode
|
|
|
|
Before applying fixes, preview changes using the environment variable:
|
|
|
|
```bash
|
|
UI5LINT_FIX_DRY_RUN=true ui5lint --fix
|
|
```
|
|
|
|
This shows what would be changed without modifying any files.
|
|
|
|
---
|
|
|
|
## Rules with Autofix Support
|
|
|
|
### 1. no-globals ✅
|
|
|
|
**What It Fixes**: Replaces UI5 global references with corresponding module imports.
|
|
|
|
**Example**:
|
|
```javascript
|
|
// Before:
|
|
function onInit() {
|
|
const core = sap.ui.getCore();
|
|
const control = core.byId("myControl");
|
|
}
|
|
|
|
// After:
|
|
import Core from "sap/ui/core/Core";
|
|
|
|
function onInit() {
|
|
const core = Core;
|
|
const control = core.byId("myControl");
|
|
}
|
|
```
|
|
|
|
**Limitations**:
|
|
- ❌ Cannot fix assignments to global variables
|
|
- ❌ Cannot handle `delete` expressions on globals
|
|
- ❌ Third-party module access via globals (like `jQuery`) not handled
|
|
|
|
---
|
|
|
|
### 2. no-deprecated-api ✅ (Partial)
|
|
|
|
**What It Fixes**: Multiple categories of deprecated API usage.
|
|
|
|
#### Category A: Configuration Facade Replacements
|
|
|
|
**Core.getConfiguration() Methods**:
|
|
|
|
Replaces deprecated `Core.getConfiguration()` method calls with modern equivalents.
|
|
|
|
```javascript
|
|
// Before:
|
|
import Core from "sap/ui/core/Core";
|
|
const config = Core.getConfiguration();
|
|
const language = config.getLanguage();
|
|
|
|
// After:
|
|
import Localization from "sap/base/i18n/Localization";
|
|
const language = Localization.getLanguage();
|
|
```
|
|
|
|
**Supported Configuration Methods** (Partial List):
|
|
- `getLanguage()` → `sap/base/i18n/Localization.getLanguage()`
|
|
- `getAnimationMode()` → `sap/ui/core/AnimationMode.getAnimationMode()`
|
|
- `getTimezone()` → `sap/base/i18n/Localization.getTimezone()`
|
|
|
|
**Not Supported** (~20 methods, see Issue #620):
|
|
- `getAnimation()`
|
|
- `getAppCacheBuster()`
|
|
- `getCompatibilityVersion()`
|
|
- `getFormatSettings()` (requires complex manual replacement)
|
|
- `getDebug()`, `getInspect()`, `getOriginInfo()` (no alternatives)
|
|
- Many others...
|
|
|
|
---
|
|
|
|
#### Category B: Core Facade Replacements
|
|
|
|
**Core API Methods**:
|
|
|
|
```javascript
|
|
// Before:
|
|
import Core from "sap/ui/core/Core";
|
|
Core.loadLibrary("sap.m", {async: true});
|
|
|
|
// After:
|
|
import Lib from "sap/ui/core/Lib";
|
|
Lib.load({name: "sap.m"});
|
|
```
|
|
|
|
**Supported Core Methods** (Partial List):
|
|
- `loadLibrary()` → `sap/ui/core/Lib.load()` (with `async: true` only)
|
|
- `byId()` → `sap/ui/core/Element.getElementById()`
|
|
- `getLibraryResourceBundle()` → `sap/ui/core/Lib.getResourceBundleFor()`
|
|
|
|
**Not Supported** (~30+ methods, see Issue #619):
|
|
|
|
**Template & Rendering** (discarded concepts):
|
|
- `getTemplate()`
|
|
- `createRenderManager()`
|
|
- `getRenderManager()`
|
|
|
|
**Event Handlers** (different APIs):
|
|
- `attachLocalizationChanged()`
|
|
- Event attachment methods discontinued
|
|
|
|
**Error Management** (only on ManagedObject):
|
|
- Format/parse/validation error methods
|
|
|
|
**Model Operations** (only on ManagedObject):
|
|
- `getModel()`, `setModel()`, `hasModel()`
|
|
|
|
**Component/Application** (no replacements):
|
|
- `getApplication()`
|
|
- `getRootComponent()`
|
|
- `getLoadedLibraries()`
|
|
- `createUIArea()`, `getUIArea()`
|
|
|
|
**Other** (discarded or no alternatives):
|
|
- `applyChanges()`
|
|
- `isLocked()`, `lock()`, `unlock()`
|
|
- `registerPlugin()`
|
|
- `setRoot()`, `setThemeRoot()`
|
|
|
|
---
|
|
|
|
#### Category C: Button Event Handler Migration
|
|
|
|
**tap → press Event**:
|
|
|
|
```javascript
|
|
// Before:
|
|
new Button({
|
|
tap: function() {
|
|
console.log("Tapped");
|
|
}
|
|
});
|
|
|
|
// After:
|
|
new Button({
|
|
press: function() {
|
|
console.log("Pressed");
|
|
}
|
|
});
|
|
```
|
|
|
|
**XML Views**:
|
|
```xml
|
|
<!-- Before: -->
|
|
<Button tap="onTap"/>
|
|
|
|
<!-- After: -->
|
|
<Button press="onPress"/>
|
|
```
|
|
|
|
---
|
|
|
|
#### Category D: SmartTable Export Property
|
|
|
|
**exportType → useExportToExcel**:
|
|
|
|
```javascript
|
|
// Before:
|
|
new SmartTable({
|
|
exportType: sap.ui.comp.smarttable.ExportType.Excel
|
|
});
|
|
|
|
// After:
|
|
new SmartTable({
|
|
useExportToExcel: true
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
#### Category E: ODataModel Property Removals
|
|
|
|
Removes deprecated properties from ODataModel instantiation.
|
|
|
|
```javascript
|
|
// Before:
|
|
new ODataModel({
|
|
serviceUrl: "/sap/opu/odata/service",
|
|
deprecatedProperty: true
|
|
});
|
|
|
|
// After:
|
|
new ODataModel({
|
|
serviceUrl: "/sap/opu/odata/service"
|
|
// deprecatedProperty removed
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
#### Category F: SimpleForm Property Elimination
|
|
|
|
Removes deprecated SimpleForm properties.
|
|
|
|
---
|
|
|
|
#### Category G: Bootstrap Script Attributes
|
|
|
|
**Fixes HTML Bootstrap Script**:
|
|
|
|
```html
|
|
<!-- Before: -->
|
|
<script src="resources/sap-ui-core.js"
|
|
data-sap-ui-theme="sap_fiori_3"
|
|
data-sap-ui-libs="sap.m">
|
|
</script>
|
|
|
|
<!-- After: -->
|
|
<script src="resources/sap-ui-core.js"
|
|
data-sap-ui-theme="sap_horizon"
|
|
data-sap-ui-libs="sap.m">
|
|
</script>
|
|
```
|
|
|
|
**Bootstrap Parameter Fixes** (Added in v1.18.0):
|
|
- Updates deprecated theme parameters
|
|
- Fixes deprecated configuration attributes
|
|
|
|
---
|
|
|
|
#### Category H: jQuery.sap API Replacements
|
|
|
|
**Limited Support** - Only specific methods are replaced:
|
|
|
|
```javascript
|
|
// Supported:
|
|
jQuery.sap.log.error() → sap/base/Log.error()
|
|
jQuery.sap.uid() → sap/base/util/uid()
|
|
jQuery.sap.encodeHTML() → sap/base/security/encodeHTML()
|
|
```
|
|
|
|
**Not Supported** (Methods without replacements or too complex):
|
|
|
|
❌ **No Direct Replacement**:
|
|
- `jQuery.sap.act` (successor module is private)
|
|
- `jQuery.sap.getObject()` (no replacement exists)
|
|
- `jQuery.sap.getUriParameters()` (no replacement)
|
|
- `jQuery.sap.isSpecialKey()` (no replacement)
|
|
|
|
❌ **Not Yet Implemented**:
|
|
- `jQuery.sap.registerModulePath()`
|
|
- `jQuery.sap.registerResourcePath()`
|
|
|
|
❌ **Too Complex**:
|
|
- `jQuery.sap.removeUrlWhitelist()` (complex to automate)
|
|
|
|
❌ **All jQuery Plugins**:
|
|
All deprecated jQuery plugins remain undetected by the linter, preventing automatic fixes.
|
|
|
|
---
|
|
|
|
#### Category I: Deprecated isA API
|
|
|
|
**sap/ui/base/Object.isA** (Added in v1.18.0):
|
|
|
|
```javascript
|
|
// Before:
|
|
import BaseObject from "sap/ui/base/Object";
|
|
if (obj.isA("sap.ui.core.Control")) {
|
|
// ...
|
|
}
|
|
|
|
// After:
|
|
if (obj.isA(Control)) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 3. no-ambiguous-event-handler ✅
|
|
|
|
**What It Fixes**: Migrates event handlers to recommended notation format.
|
|
|
|
**Added in**: v1.19.0
|
|
|
|
```xml
|
|
<!-- Before: ambiguous notation -->
|
|
<Button press="handlePress"/>
|
|
|
|
<!-- After: controller method notation -->
|
|
<Button press=".handlePress"/>
|
|
```
|
|
|
|
---
|
|
|
|
### 4. no-removed-manifest-property ✅ (Partial)
|
|
|
|
**What It Fixes**: Removes incompatible manifest properties.
|
|
|
|
**Added in**: v1.19.0
|
|
|
|
**Supported Fixes**:
|
|
|
|
1. **Remove synchronizationMode**:
|
|
```json
|
|
// Before:
|
|
{
|
|
"sap.ui5": {
|
|
"models": {
|
|
"": {
|
|
"dataSource": "mainService",
|
|
"synchronizationMode": "None"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// After:
|
|
{
|
|
"sap.ui5": {
|
|
"models": {
|
|
"": {
|
|
"dataSource": "mainService"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Clean up empty sap.ui5/resources/js entries**:
|
|
```json
|
|
// Before:
|
|
{
|
|
"sap.ui5": {
|
|
"resources": {
|
|
"js": []
|
|
}
|
|
}
|
|
}
|
|
|
|
// After:
|
|
{
|
|
"sap.ui5": {
|
|
"resources": {}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## General Autofix Restrictions
|
|
|
|
The linter **cannot** automatically fix code in these scenarios:
|
|
|
|
### 1. Code Outside Module Definitions ❌
|
|
|
|
**Problem**: Fixes requiring new imports won't work unless code is within `sap.ui.define` or `sap.ui.require` blocks.
|
|
|
|
```javascript
|
|
// ❌ Cannot fix - not in module definition
|
|
sap.ui.getCore().byId("myControl");
|
|
|
|
// ✅ Can fix - inside module definition
|
|
sap.ui.define([], function() {
|
|
sap.ui.getCore().byId("myControl");
|
|
// Will add import and replace
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Synchronous-to-Asynchronous Conversions ❌
|
|
|
|
**Problem**: APIs returning promises can't replace sync versions without restructuring entire code flows across multiple files.
|
|
|
|
**Examples**:
|
|
|
|
```javascript
|
|
// ❌ Cannot automatically convert - sync to async
|
|
const component = sap.ui.component({name: "my.app"});
|
|
component.doSomething(); // Immediate usage
|
|
|
|
// ✅ Would require manual conversion to:
|
|
sap.ui.component({name: "my.app", async: true})
|
|
.then(function(component) {
|
|
component.doSomething();
|
|
});
|
|
```
|
|
|
|
**Affected APIs** (Sync-to-Async Barriers):
|
|
|
|
❌ **Library Loading**:
|
|
- `Core.loadLibrary()` → Only replaced with `Lib.load()` when `async: true` is specified
|
|
|
|
❌ **Component Creation**:
|
|
- `Core.createComponent()` → Only replaced with `Component.create()` when `async: true` is specified
|
|
|
|
❌ **Resource Bundles**:
|
|
- `Core.getLibraryResourceBundle()` → Not replaced if arguments suggest promise returns
|
|
|
|
❌ **View/Fragment Creation** (all require manual conversion):
|
|
- `sap.ui.component()`
|
|
- `sap.ui.view()`
|
|
- `sap.ui.xmlfragment()`
|
|
- `sap.ui.xmlview()`
|
|
- `sap.ui.jsonview()`
|
|
- `sap.ui.jsview()`
|
|
- `sap.ui.htmlview()`
|
|
|
|
---
|
|
|
|
### 3. Complex Replacements ❌
|
|
|
|
**Problem**: APIs needing multiple calls and new local variables lack support.
|
|
|
|
```javascript
|
|
// ❌ Cannot automatically fix - requires multiple steps
|
|
const config = Core.getConfiguration();
|
|
const formatSettings = config.getFormatSettings();
|
|
const datePattern = formatSettings.getDatePattern("medium");
|
|
|
|
// Would require complex manual replacement:
|
|
import Formatting from "sap/base/i18n/Formatting";
|
|
import DateFormat from "sap/ui/core/format/DateFormat";
|
|
const dateFormat = DateFormat.getDateInstance({style: "medium"},
|
|
Formatting.getLanguageTag());
|
|
const datePattern = dateFormat.oFormatOptions.pattern;
|
|
```
|
|
|
|
---
|
|
|
|
### 4. Context-Dependent Replacements ❌
|
|
|
|
**Problem**: Usage patterns affecting broader code context prevent automation.
|
|
|
|
```javascript
|
|
// ❌ Cannot automatically fix - context-dependent
|
|
function doSomething() {
|
|
const model = this.getView().getModel();
|
|
// vs
|
|
const model = Core.getModel(); // Different context!
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Return Value Changes ❌
|
|
|
|
**Problem**: When return types differ, automated replacement becomes impossible.
|
|
|
|
```javascript
|
|
// ❌ Cannot fix - return type changes
|
|
const libs = Core.getLoadedLibraries(); // Returns object
|
|
const libNames = Object.keys(libs);
|
|
|
|
// No direct replacement exists that returns the same structure
|
|
```
|
|
|
|
---
|
|
|
|
## Autofix Development Standards
|
|
|
|
For contributors developing new autofix capabilities:
|
|
|
|
### 1:1 Replacement Requirements
|
|
|
|
When implementing 1:1 replacements, verify:
|
|
|
|
- ✅ Function arguments maintain identical type, order, value, and count
|
|
- ✅ Return types match exactly between old and new implementations
|
|
- ✅ Complex return types (enums/objects) preserve all original values and properties
|
|
- ✅ Object method return values maintain type compatibility
|
|
|
|
### Complex Replacement Standards
|
|
|
|
When implementing sophisticated migrations:
|
|
|
|
- ✅ Skip replacements where return types differ unless the value remains unused
|
|
- ✅ Utilize `isExpectedValueExpression()` utility or `mustNotUseReturnValue` flags
|
|
- ✅ Perform static argument type verification using TypeScript's TypeChecker
|
|
- ✅ Preserve comments and whitespace during argument restructuring
|
|
- ✅ Maintain line breaks and spacing conventions in modified expressions
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### 1. Always Use Dry-Run First
|
|
|
|
```bash
|
|
# Preview changes before applying
|
|
UI5LINT_FIX_DRY_RUN=true ui5lint --fix
|
|
```
|
|
|
|
### 2. Review Changes Before Committing
|
|
|
|
Autofix can make extensive changes. Always review before committing:
|
|
|
|
```bash
|
|
ui5lint --fix
|
|
git diff
|
|
```
|
|
|
|
### 3. Use Version Control
|
|
|
|
Commit your code before running autofix:
|
|
|
|
```bash
|
|
git commit -am "Pre-autofix snapshot"
|
|
ui5lint --fix
|
|
git diff # Review changes
|
|
```
|
|
|
|
### 4. Test After Autofix
|
|
|
|
Autofix may introduce subtle issues. Always test:
|
|
|
|
```bash
|
|
ui5lint --fix
|
|
npm test
|
|
npm run build
|
|
```
|
|
|
|
### 5. Handle Limitations Manually
|
|
|
|
For unsupported APIs, manually refactor:
|
|
|
|
```javascript
|
|
// Linter will flag but not fix:
|
|
const libs = Core.getLoadedLibraries();
|
|
|
|
// Manual replacement:
|
|
import Lib from "sap/ui/core/Lib";
|
|
const libs = Lib.all();
|
|
```
|
|
|
|
---
|
|
|
|
## Common Autofix Scenarios
|
|
|
|
### Scenario 1: Clean Global Usage
|
|
|
|
```bash
|
|
# Fix all global access patterns
|
|
ui5lint --fix "webapp/**/*.js"
|
|
```
|
|
|
|
**Result**: Replaces `sap.ui.getCore()`, global namespace access, etc.
|
|
|
|
---
|
|
|
|
### Scenario 2: Modernize Component
|
|
|
|
```bash
|
|
# Fix component and manifest issues
|
|
ui5lint --fix "webapp/manifest.json" "webapp/Component.js"
|
|
```
|
|
|
|
**Result**: Removes `synchronizationMode`, updates deprecated APIs
|
|
|
|
---
|
|
|
|
### Scenario 3: Update Views
|
|
|
|
```bash
|
|
# Fix event handlers and deprecated controls
|
|
ui5lint --fix "webapp/view/**/*.xml"
|
|
```
|
|
|
|
**Result**: Updates event handler notation, deprecated attributes
|
|
|
|
---
|
|
|
|
### Scenario 4: Migrate jQuery.sap
|
|
|
|
```bash
|
|
# Fix supported jQuery.sap APIs
|
|
ui5lint --fix "webapp/**/*.js"
|
|
```
|
|
|
|
**Result**: Replaces `jQuery.sap.log`, `jQuery.sap.uid`, etc.
|
|
**Note**: Many jQuery.sap APIs cannot be automatically fixed!
|
|
|
|
---
|
|
|
|
## Troubleshooting Autofix
|
|
|
|
### Issue: "autofix-error" Reported
|
|
|
|
**Cause**: Expected autofix cannot be applied
|
|
|
|
**Solutions**:
|
|
1. Check if code is within module definition
|
|
2. Verify file syntax is valid (no parsing errors)
|
|
3. Review edge cases that may prevent replacement
|
|
4. Report issue to UI5 Linter team if unexpected
|
|
|
|
---
|
|
|
|
### Issue: Autofix Changes Too Much
|
|
|
|
**Cause**: Running autofix on entire codebase at once
|
|
|
|
**Solutions**:
|
|
1. Run autofix on specific directories:
|
|
```bash
|
|
ui5lint --fix "webapp/controller/**/*.js"
|
|
```
|
|
2. Use `--ignore-pattern` to exclude files:
|
|
```bash
|
|
ui5lint --fix --ignore-pattern "webapp/thirdparty/**"
|
|
```
|
|
|
|
---
|
|
|
|
### Issue: Autofix Missed Some Deprecations
|
|
|
|
**Cause**: Not all deprecated APIs support autofix
|
|
|
|
**Solutions**:
|
|
1. Review this document for known limitations
|
|
2. Check `Scope-of-Autofix.md` for latest updates
|
|
3. Manually refactor unsupported APIs
|
|
4. Consider reporting missing autofix as feature request
|
|
|
|
---
|
|
|
|
## Version History
|
|
|
|
### v1.20.5 (2025-11-18)
|
|
- Dependency updates
|
|
|
|
### v1.20.0 (2025-09-11)
|
|
- Manifest v2 support
|
|
- Deterministic file ordering
|
|
|
|
### v1.19.0 (2025-08-28)
|
|
- ✨ Removal of `synchronizationMode` from manifest.json
|
|
- ✨ Cleanup of empty `sap.ui5/resources/js` entries
|
|
- ✨ Migration to recommended event handler notation
|
|
|
|
### v1.18.0 (2025-08-19)
|
|
- ✨ Fix UI5 Bootstrap Parameters in HTML
|
|
- ✨ Autofix for deprecated `sap/ui/base/Object.isA` API
|
|
|
|
### v1.14.0 (2025-06-27)
|
|
- ✨ Deprecated sap/ui/core/Core APIs autofix
|
|
- ✨ Deprecated sap/ui/core/Configuration APIs autofix
|
|
- ✨ Deprecated jQuery.sap APIs autofix
|
|
- ✨ Deprecated property assignments autofix
|
|
|
|
---
|
|
|
|
## Further Reading
|
|
|
|
- **Autofix Documentation**: [https://github.com/UI5/linter/blob/main/docs/Scope-of-Autofix.md](https://github.com/UI5/linter/blob/main/docs/Scope-of-Autofix.md)
|
|
- **Issue #619** (Core API Limitations): [https://github.com/UI5/linter/issues/619](https://github.com/UI5/linter/issues/619)
|
|
- **Issue #620** (Configuration API Limitations): [https://github.com/UI5/linter/issues/620](https://github.com/UI5/linter/issues/620)
|
|
- **Main Repository**: [https://github.com/UI5/linter](https://github.com/UI5/linter)
|
|
- **Development Guide**: [https://github.com/UI5/linter/blob/main/docs/Development.md](https://github.com/UI5/linter/blob/main/docs/Development.md)
|
|
|
|
---
|
|
|
|
**Document Version**: 1.0
|
|
**Last Verified**: 2025-11-21
|
|
**Next Review**: 2026-02-21
|