Skip to content

Commit 28ab574

Browse files
committed
fix: Cannot read properties of undefined (reading 'map')
This fixes an exception that was happening when a source map with sections was being processed. It mainly occurred when a UI5 bundle such as a `Component-preload.js` is part of the project sources and not excluded from linting. UI5 bundles are now excluded from linting and AMD transpilation. In addition, source maps with sections are not processed. Fixes: #583
1 parent 93acfff commit 28ab574

File tree

17 files changed

+339
-34
lines changed

17 files changed

+339
-34
lines changed

src/linter/ui5Types/SourceFileReporter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ export default class SourceFileReporter {
3737
this.#sourceFile = sourceFile;
3838
if (sourceMap) {
3939
const parsedSourceMap = JSON.parse(sourceMap) as EncodedSourceMap;
40-
if (parsedSourceMap.mappings !== "") {
40+
if (parsedSourceMap.mappings !== "" && !("sections" in parsedSourceMap)) {
4141
// Only create a trace map if there are mappings.
4242
// Otherwise, it will be useless and causes errors in some cases (Failed to map back to source).
43+
44+
// Also, sections are not supported as they only appear in bundles, which in general are not supported
45+
// as source files should be linted individually.
46+
4347
this.#traceMap = new TraceMap(parsedSourceMap);
4448
}
4549
}

src/linter/ui5Types/TypeLinter.ts

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -133,31 +133,32 @@ export default class TypeLinter {
133133
const messageDetails = this.#context.getIncludeMessageDetails();
134134
const typeCheckDone = taskStart("Linting all transpiled resources");
135135
for (const sourceFile of program.getSourceFiles()) {
136-
if (!sourceFile.isDeclarationFile && pathsToLint.includes(sourceFile.fileName)) {
137-
const sourceMap = this.#sourceMaps.get(sourceFile.fileName);
138-
if (!sourceMap) {
139-
log.verbose(`Failed to get source map for ${sourceFile.fileName}`);
140-
}
141-
let manifestContent;
142-
if (sourceFile.fileName.endsWith("/Component.js") || sourceFile.fileName.endsWith("/Component.ts")) {
143-
const res = await this.#workspace.byPath(path.dirname(sourceFile.fileName) + "/manifest.json");
144-
if (res) {
145-
manifestContent = await res.getString();
146-
}
147-
}
148-
if (silly) {
149-
log.silly(`Linting ${sourceFile.fileName}`);
136+
if (sourceFile.isDeclarationFile || !pathsToLint.includes(sourceFile.fileName)) {
137+
continue;
138+
}
139+
if (sourceFile.getFullText().startsWith("//@ui5-bundle ")) {
140+
log.verbose(`Skipping linting of UI5 bundle '${sourceFile.fileName}'`);
141+
continue;
142+
}
143+
let manifestContent;
144+
if (sourceFile.fileName.endsWith("/Component.js") || sourceFile.fileName.endsWith("/Component.ts")) {
145+
const res = await this.#workspace.byPath(path.dirname(sourceFile.fileName) + "/manifest.json");
146+
if (res) {
147+
manifestContent = await res.getString();
150148
}
151-
const linterDone = taskStart("Type-check resource", sourceFile.fileName, true);
152-
const linter = new SourceFileLinter(
153-
this,
154-
sourceFile,
155-
checker, reportCoverage, messageDetails,
156-
apiExtract, this.#filePathsWorkspace, this.#workspace, ambientModuleCache, manifestContent
157-
);
158-
await linter.lint();
159-
linterDone();
160149
}
150+
if (silly) {
151+
log.silly(`Linting ${sourceFile.fileName}`);
152+
}
153+
const linterDone = taskStart("Type-check resource", sourceFile.fileName, true);
154+
const linter = new SourceFileLinter(
155+
this,
156+
sourceFile,
157+
checker, reportCoverage, messageDetails,
158+
apiExtract, this.#filePathsWorkspace, this.#workspace, ambientModuleCache, manifestContent
159+
);
160+
await linter.lint();
161+
linterDone();
161162
}
162163

163164
// Will eventually produce new JS files for XML views and fragments
@@ -186,17 +187,18 @@ export default class TypeLinter {
186187
checker = program.getTypeChecker();
187188
ambientModuleCache = new AmbientModuleCache(checker.getAmbientModules());
188189
for (const sourceFile of program.getSourceFiles()) {
189-
if (!sourceFile.isDeclarationFile && /\.inline-[0-9]+\.(view|fragment)\.js/.exec(sourceFile.fileName)) {
190-
const linterDone = taskStart("Type-check resource", sourceFile.fileName, true);
191-
const linter = new SourceFileLinter(
192-
this,
193-
sourceFile,
194-
checker, reportCoverage, messageDetails,
195-
apiExtract, this.#filePathsWorkspace, this.#workspace, ambientModuleCache
196-
);
197-
await linter.lint();
198-
linterDone();
190+
if (sourceFile.isDeclarationFile || !/\.inline-[0-9]+\.(view|fragment)\.js/.exec(sourceFile.fileName)) {
191+
continue;
199192
}
193+
const linterDone = taskStart("Type-check resource", sourceFile.fileName, true);
194+
const linter = new SourceFileLinter(
195+
this,
196+
sourceFile,
197+
checker, reportCoverage, messageDetails,
198+
apiExtract, this.#filePathsWorkspace, this.#workspace, ambientModuleCache
199+
);
200+
await linter.lint();
201+
linterDone();
200202
}
201203
}
202204
typeCheckDone();

src/linter/ui5Types/amdTranspiler/transpiler.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ function createProgram(inputFileNames: string[], host: ts.CompilerHost): ts.Prog
5353
export default function transpileAmdToEsm(
5454
resourcePath: string, content: string, context: LinterContext, strict?: boolean
5555
): TranspileResult {
56+
// Do not transpile UI5 bundles
57+
if (content.startsWith("//@ui5-bundle ")) {
58+
log.verbose(`Skipping transformation of UI5 bundle ${resourcePath}.`);
59+
return {source: content, map: ""};
60+
}
61+
5662
// This is heavily inspired by the TypesScript "transpileModule" API
5763
const fileName = path.basename(resourcePath);
5864
const taskDone = taskStart("Transpiling AMD to ESM", fileName, true);

test/e2e/snapshots/compare-snapshots.ts.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,28 @@ Generated by [AVA](https://avajs.dev).
1313
> Snapshot 2
1414
1515
[
16+
{
17+
errorCount: 2,
18+
fatalErrorCount: 0,
19+
filePath: 'webapp/bundles/thirdparty-bundle.js',
20+
messages: [
21+
{
22+
column: 20,
23+
line: 1,
24+
message: 'Access of global variable \'sap\' (sap.m.Button)',
25+
ruleId: 'no-globals',
26+
severity: 2,
27+
},
28+
{
29+
column: 19,
30+
line: 2,
31+
message: 'Access of global variable \'sap\' (sap.m.Input)',
32+
ruleId: 'no-globals',
33+
severity: 2,
34+
},
35+
],
36+
warningCount: 0,
37+
},
1638
{
1739
errorCount: 3,
1840
fatalErrorCount: 0,
152 Bytes
Binary file not shown.

test/fixtures/linter/projects/com.ui5.troublesome.app/webapp/bundles/thirdparty-bundle.js

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/linter/projects/com.ui5.troublesome.app/webapp/bundles/thirdparty-bundle.js.map

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ui5-bundle com/ui5/troublesome/app/bundles/ui5-bundle-without-sourcemap.js
2+
jQuery.sap.registerPreloadedModules({
3+
"version": "2.0",
4+
"modules": {
5+
"com/ui5/troublesome/app/Component.js": function () {
6+
sap.ui.define(["sap/ui/Device"], function () {
7+
return sap.ui.core.UIComponent.extend("com.ui5.troublesome.app.Component", {
8+
metadata: {
9+
manifest: "json"
10+
}
11+
});
12+
});
13+
}
14+
}
15+
});
16+
17+
// This file should be excluded from linting as it is a UI5 bundle file.
18+
// It should also not be transformed by the amdTranspiler.

test/fixtures/linter/projects/com.ui5.troublesome.app/webapp/bundles/ui5-bundle.js

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/linter/projects/com.ui5.troublesome.app/webapp/bundles/ui5-bundle.js.map

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)