Skip to content

Commit abdc6e2

Browse files
Fix built-in property visibility bug cause by LwcFlavor (#229)
1 parent aea5a88 commit abdc6e2

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

src/analyze/flavors/lwc/refine-feature.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ function isLWCComponent(component: ComponentFeatureBase, context: AnalyzerVisitC
4242
if (node) {
4343
return !!getLwcComponent(node, context);
4444
}
45-
// How do we know that we are dealing with LWC components?
46-
// Currently assume that it is always the case
47-
return true;
45+
// You can't assume that everything is a LWC component - that will cause huge
46+
// problems with the refinement rules below that switch default visibility to protected!!
47+
return false;
4848
}
4949

5050
export const refineFeature: AnalyzerFlavor["refineFeature"] = {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { join } from "path";
2+
import { analyzeSourceFile } from "../../../src/analyze/analyze-source-file";
3+
import { getCurrentTsModule, getCurrentTsModuleDirectory, tsTest } from "../../helpers/ts-test";
4+
5+
tsTest("analyzeSourceFile on lib.dom.ts returns correct result", t => {
6+
const tsModule = getCurrentTsModule();
7+
const program = tsModule.createProgram([join(getCurrentTsModuleDirectory(), "lib.dom.d.ts")], {});
8+
9+
const endsWithLibDom = "lib.dom.d.ts";
10+
11+
const domLibSourceFile = program.getSourceFiles().find(sf => sf.fileName.endsWith(endsWithLibDom));
12+
if (domLibSourceFile == null) {
13+
throw new Error(`Couldn't find '${endsWithLibDom}'. Have you included the 'dom' lib in your tsconfig?`);
14+
}
15+
16+
const result = analyzeSourceFile(domLibSourceFile, {
17+
program,
18+
ts: tsModule,
19+
config: {
20+
features: ["event", "member", "slot", "csspart", "cssproperty"],
21+
analyzeGlobalFeatures: false, // Don't analyze global features in lib.dom.d.ts
22+
analyzeDefaultLib: true,
23+
analyzeDependencies: true,
24+
analyzeAllDeclarations: false,
25+
excludedDeclarationNames: ["HTMLElement"]
26+
}
27+
});
28+
29+
t.truthy(result);
30+
31+
const scriptDefinition = result.componentDefinitions?.find(d => d.tagName === "script");
32+
t.truthy(scriptDefinition);
33+
34+
const srcProperty = scriptDefinition!.declaration?.members.find(m => m.kind === "property" && m.propName === "src");
35+
36+
t.truthy(srcProperty);
37+
t.true(srcProperty!.visibility === undefined || srcProperty!.visibility === "public", `srcProperty!.visibility is "${srcProperty!.visibility}"`);
38+
});

test/flavors/lwc/member-test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,48 @@ tsTest("LWC: Discovers properties from '@api'", t => {
4242
);
4343
});
4444

45+
tsTest("LWC: doesn't process non-LWC element'", t => {
46+
const {
47+
results: [result],
48+
checker
49+
} = analyzeTextWithCurrentTsModule({
50+
fileName: "modules/custom/myElement/myElement.ts",
51+
text: `
52+
// This is defined as an interface to test a regression
53+
interface MyElement extends HTMLElement {
54+
myProp: string;
55+
}
56+
declare var MyElement: {
57+
prototype: MyElement;
58+
new(): MyElement;
59+
};
60+
interface HTMLElementTagNameMap {
61+
'my-element': MyElement,
62+
}
63+
`
64+
});
65+
66+
const { members = [] } = result.componentDefinitions[0]?.declaration || {};
67+
assertHasMembers(
68+
members,
69+
[
70+
{
71+
kind: "property",
72+
propName: "myProp",
73+
default: undefined,
74+
typeHint: undefined,
75+
type: () => ({ kind: "STRING" }),
76+
visibility: "public",
77+
reflect: undefined,
78+
deprecated: undefined,
79+
required: undefined
80+
}
81+
],
82+
t,
83+
checker
84+
);
85+
});
86+
4587
tsTest("LWC: Discovers properties without @api'", t => {
4688
const {
4789
results: [result],

0 commit comments

Comments
 (0)