Skip to content

Commit f064462

Browse files
committed
chore: Fully comment @css-blocks/glimmer's Resolver.ts.
1 parent 07a44b9 commit f064462

File tree

1 file changed

+73
-16
lines changed

1 file changed

+73
-16
lines changed

Diff for: packages/@css-blocks/glimmer/src/Resolver.ts

+73-16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ import { ResolvedFile } from "./Template";
1111

1212
const DEBUG = debugGenerator("css-blocks:glimmer:resolver");
1313

14+
/**
15+
* Convert constituent template path parts to an Ember Classic style Block path.
16+
*
17+
* @param base The base path of the project to discover files relative from.
18+
* @param templatePath The template's filesystem path relative to `base`.
19+
* @param ext The extension to look for.
20+
* @return Where the associated Block should be located on the filesystem.
21+
*/
1422
function toClassicPath(base: string, templatePath: string, ext: string): string {
1523
// TODO: There is a more robust way to do all this path munging!
1624
let classic = path.parse(templatePath.replace("templates/", "styles/"));
@@ -19,6 +27,14 @@ function toClassicPath(base: string, templatePath: string, ext: string): string
1927
return path.join(base, path.format(classic));
2028
}
2129

30+
/**
31+
* Convert constituent template path parts to an Ember Pods style Block path.
32+
*
33+
* @param base The base path of the project to discover files relative from.
34+
* @param templatePath The template's filesystem path relative to `base`.
35+
* @param ext The extension to look for.
36+
* @return Where the associated Block should be located on the filesystem.
37+
*/
2238
function toPodsPath(base: string, templatePath: string, ext: string): string {
2339
let pods = path.parse(templatePath);
2440
delete pods.base; // Required for path.format to pick up new extension.
@@ -28,18 +44,29 @@ function toPodsPath(base: string, templatePath: string, ext: string): string {
2844
}
2945

3046
/**
31-
* The Glimmer CSS Blocks Resolver deals in three
47+
* The Glimmer CSS Blocks Resolver currently supports three
3248
* kinds of project structure modes:
3349
* - Component Names as Paths (Module Config)
3450
* - Relative Template Paths (Classic Ember)
3551
* - Relative Template Paths (Ember Pods)
52+
*
53+
* It provides abstractions for interacting with the three project
54+
* structures, so the rest of the Glimmer analyzer code can operate
55+
* independently of the filesystem structure.
56+
*
3657
*/
3758
export class Resolver {
3859

3960
private depAnalyzers: Map<string, DependencyAnalyzer> = new Map();
4061
private moduleConfig?: ResolverConfiguration;
4162
private fileEndings: Set<string>;
4263

64+
/**
65+
* Creates a new Resolver for this project.
66+
*
67+
* @param cssBlocksConfig The CSS Blocks configuration object.
68+
* @param moduleConfig If applicable, the Glimmer module config for static analysis.
69+
*/
4370
constructor(cssBlocksConfig: ResolvedConfiguration, moduleConfig?: ResolverConfiguration) {
4471
if (moduleConfig) {
4572
this.moduleConfig = moduleConfig;
@@ -48,23 +75,39 @@ export class Resolver {
4875
DEBUG(`Discovering all Block files that end with ("${[...this.fileEndings].join(`|`)}")`);
4976
}
5077

51-
private dependencyAnalyzerFor(dir: string): DependencyAnalyzer | undefined {
78+
/**
79+
* If appropriate, returns the `DependencyAnalyzer` for a given project.
80+
* If no module config exists for the project (aka: is not a full, statically
81+
* analyzable Glimmer app) it returns undefined.
82+
*
83+
* @param base The base path of the project to analyze.
84+
* @return The DependencyAnalyzer, or undefined.
85+
*/
86+
private dependencyAnalyzerFor(base: string): DependencyAnalyzer | undefined {
5287
if (!this.moduleConfig) { return undefined; }
53-
if (this.depAnalyzers.has(dir)) {
54-
return this.depAnalyzers.get(dir)!;
88+
if (this.depAnalyzers.has(base)) {
89+
return this.depAnalyzers.get(base)!;
5590
}
5691
let src = this.moduleConfig.app && this.moduleConfig.app.mainPath || "src";
57-
let depAnalyzer = new DependencyAnalyzer(dir, {
92+
let depAnalyzer = new DependencyAnalyzer(base, {
5893
config: { moduleConfiguration: this.moduleConfig },
5994
paths: {
6095
src,
6196
},
6297
});
63-
this.depAnalyzers.set(dir, depAnalyzer);
98+
this.depAnalyzers.set(base, depAnalyzer);
6499
return depAnalyzer;
65100
}
66101

67-
// TODO: We need to automatically discover the file ending here – its not guaranteed to be a css file.
102+
/**
103+
* Converts a template file path to its associated Block filepath, if present.
104+
* All file endings associated with a preprocessor are attempted.
105+
* If no block exists, returns undefined.
106+
*
107+
* @param base The base path of the project to lookup Block files relative to.
108+
* @param template The template name we're attempting to discover block files for.
109+
* @return A promise that resolves with the discover Block path, or undefined.
110+
*/
68111
private async tmplPathToStylesheetPath(base: string, template: string): Promise<string | undefined> {
69112
let triedPaths = [];
70113
// For every supported block extension:
@@ -75,13 +118,16 @@ export class Resolver {
75118
DEBUG(`Discovered classic Block for template ${template}: ${classic}`);
76119
return classic;
77120
}
121+
// Else attempt to fetch at the pods path.
78122
let podsPath = toPodsPath(base, template, ext);
79123
if (fs.pathExistsSync(podsPath)) {
80124
DEBUG(`Discovered pods Block for template ${template}: ${podsPath}`);
81125
return podsPath;
82126
}
83127
triedPaths.push(path.relative(base, classic), path.relative(base, podsPath));
84128
}
129+
130+
// If we get here, there is no Block file at any standard Ember location, for any support file ending.
85131
DEBUG(`No Block discovered for template ${template}. Attempted at:${triedPaths.join(`\n - `)}`);
86132
return undefined;
87133
}
@@ -92,22 +138,30 @@ export class Resolver {
92138
* "Module Map" mode where we can statically analyze application
93139
* dependencies. In "Classic Ember" or "Ember Pods" mode we just
94140
* return the same ident.
141+
*
142+
* @param base The base of the project to analyze.
143+
* @param identifier The Glimmer identifier to discover recursive dependencies for.
144+
* @return The list of recursive dependencies for this identifier.
95145
*/
96-
recursiveDependenciesForTemplate(dir: string, identifier: string): string[] {
97-
let depAnalyzer = this.dependencyAnalyzerFor(dir);
146+
recursiveDependenciesForTemplate(base: string, identifier: string): string[] {
147+
let depAnalyzer = this.dependencyAnalyzerFor(base);
98148
if (!depAnalyzer) { return [identifier]; }
99149
return depAnalyzer.recursiveDependenciesForTemplate(identifier).components;
100150
}
101151

102152
/**
103153
* Given a template identifier, resolve the Block file associated
104154
* with the template, if any.
155+
*
156+
* @param base The base of the project to analyze.
157+
* @param identifier The Glimmer identifier to discover recursive dependencies for.
158+
* @return The resolved Block file if present, or undefined.
105159
*/
106-
async stylesheetFor(dir: string, identifier: string): Promise<ResolvedFile | undefined> {
107-
let depAnalyzer = this.dependencyAnalyzerFor(dir);
160+
async stylesheetFor(base: string, identifier: string): Promise<ResolvedFile | undefined> {
161+
let depAnalyzer = this.dependencyAnalyzerFor(base);
108162

109163
if (!depAnalyzer) {
110-
let stylesheet = await this.tmplPathToStylesheetPath(dir, identifier);
164+
let stylesheet = await this.tmplPathToStylesheetPath(base, identifier);
111165
if (!stylesheet) { return undefined; }
112166
return new ResolvedFile(
113167
(fs.readFileSync(stylesheet)).toString(),
@@ -120,7 +174,7 @@ export class Resolver {
120174
identifier = depAnalyzer.project.resolver.identify(`stylesheet:${identifier}`);
121175
let file: string = depAnalyzer.project.resolver.resolve(identifier);
122176
if (!file) { return undefined; }
123-
file = path.join(dir, depAnalyzer.project.paths.src, file);
177+
file = path.join(base, depAnalyzer.project.paths.src, file);
124178
if (!fs.existsSync(file)) { return undefined; }
125179
let content = (fs.readFileSync(file)).toString();
126180
return new ResolvedFile(content, identifier, file);
@@ -129,12 +183,15 @@ export class Resolver {
129183
/**
130184
* Given a template identifier, resolve the actual template file associated
131185
* with it, if any.
186+
* @param base The base of the project to analyze.
187+
* @param identifier The template identifier to discover recursive dependencies for.
188+
* @return The resolved Block file if present, or undefined.
132189
*/
133-
async templateFor(dir: string, identifier: string): Promise<ResolvedFile | undefined> {
134-
let depAnalyzer = this.dependencyAnalyzerFor(dir);
190+
async templateFor(base: string, identifier: string): Promise<ResolvedFile | undefined> {
191+
let depAnalyzer = this.dependencyAnalyzerFor(base);
135192

136193
if (!depAnalyzer) {
137-
let template = path.join(dir, identifier);
194+
let template = path.join(base, identifier);
138195
return new ResolvedFile(
139196
(fs.readFileSync(template)).toString(),
140197
identifier,

0 commit comments

Comments
 (0)