@@ -6,22 +6,36 @@ import { typeStore } from "./parser";
66import config from "../../src/config" ;
77
88export const TEMPLATE_IDENTIFIER = "__ctrlFlow_template" ;
9- export const MODELICAPATH = [
9+ export let MODELICA_JSON_PATH = [
1010 `${ config . MODELICA_DEPENDENCIES } /template-json/json/` ,
1111] ;
1212
13- function _toModelicaPath ( filePath : string ) {
13+ // Used for testing: registers additional search paths for Modelica JSON files
14+ export function prependToModelicaJsonPath ( paths : string [ ] ) {
15+ MODELICA_JSON_PATH = [ ...paths , ...MODELICA_JSON_PATH ] ;
16+ }
17+
18+ export function getClassNameFromRelativePath ( filePath : string ) {
1419 filePath = filePath . endsWith ( ".json" ) ? filePath . slice ( 0 , - 5 ) : filePath ;
1520 return filePath . replace ( / \/ / g, "." ) ;
1621}
1722
23+ /**
24+ * Finds all entry points that contain the template identifier for a given package.
25+ * - LIMITATION: This function requires that the package uses
26+ * [Directory Hierarchy Mapping](https://specification.modelica.org/maint/3.6/packages.html#directory-hierarchy-mapping)
27+ * @param packageName - The Modelica class name of the package to search for entry points
28+ * @returns An array of objects containing the path and parsed JSON for each entry point found
29+ */
1830export function findPackageEntryPoints (
19- prefix : string ,
20- reference : string ,
31+ packageName : string ,
2132) : { path : string ; json : Object | undefined } [ ] {
2233 const entryPoints : { path : string ; json : Object | undefined } [ ] = [ ] ;
23- [ prefix , ...MODELICAPATH ] . forEach ( ( dir ) => {
24- const dirPath = path . resolve ( dir , reference ) ;
34+ MODELICA_JSON_PATH . forEach ( ( dir ) => {
35+ // We need a top directory to look up for entry points
36+ // so we can simply convert the class name to a relative path
37+ // without adding any file extension.
38+ const dirPath = path . resolve ( dir , packageName . replace ( / \. / g, "/" ) ) ;
2539 if ( fs . existsSync ( dirPath ) ) {
2640 const cmd = `grep -rl ${ dirPath } -e "${ TEMPLATE_IDENTIFIER } "` ;
2741 const response = execSync ( cmd ) . toString ( ) ;
@@ -32,10 +46,10 @@ export function findPackageEntryPoints(
3246 . sort ( ( a , b ) => ( a . includes ( "package.json" ) ? - 1 : 1 ) )
3347 . map ( ( p ) => path . relative ( dir , p ) )
3448 . map ( ( p ) => {
35- const path = _toModelicaPath ( p ) ;
49+ const path = getClassNameFromRelativePath ( p ) ;
3650 return {
3751 path : path ,
38- json : loader ( dir , path ) ,
52+ json : loader ( path ) ,
3953 } ;
4054 } ) ,
4155 ) ;
@@ -46,33 +60,36 @@ export function findPackageEntryPoints(
4660}
4761
4862/**
49- * Searched the provided directory for a given
50- * @param prefix directory to search
51- * @param filePath path to try and find
52- *
53- * @returns the found file path or null if not found
63+ * Gets the path to a Modelica JSON file based on the full class name.
64+ * - LIMITATION: This function requires that the library packages use
65+ * [Directory Hierarchy Mapping](https://specification.modelica.org/maint/3.6/packages.html#directory-hierarchy-mapping)
66+ * @param className - The full Modelica class name (e.g. "Library.Package.Class")
67+ * @param dirPath - The directory path to search in
68+ * @returns The file path if found, null otherwise
5469 */
55- function _findPath ( prefix : string , reference : string ) : string | null {
56- let filePath = path . parse ( reference . replace ( / \. / g, "/" ) ) ;
70+ function getPathFromClassName (
71+ className : string ,
72+ dirPath : string ,
73+ ) : string | null {
74+ let filePath = path . parse ( className . replace ( / \. / g, "/" ) ) ;
5775
58- let jsonFile = path . resolve ( prefix , filePath . dir , `${ filePath . name } .json` ) ;
76+ let jsonFile = path . resolve ( dirPath , filePath . dir , `${ filePath . name } .json` ) ;
5977
6078 while ( ! fs . existsSync ( jsonFile ) && filePath . name ) {
6179 // check if definition already exists
6280 // TODO - construct this path correctly...
6381 const curPath = path . relative ( filePath . dir , filePath . name ) ;
64- const modelicaPath = _toModelicaPath ( curPath ) ;
82+ const modelicaPath = getClassNameFromRelativePath ( curPath ) ;
6583 if ( typeStore . has ( modelicaPath ) ) {
6684 break ;
6785 }
6886 // package definitions break the typical modelica path to file mapping that
6987 // is used. A typical modelica path to file path look like:
70- // 'Template.AirHandlerFans.VAVMultizone' -> 'Template/AirhandlerFans/VAVMultizone
88+ // 'Template.AirHandlerFans.VAVMultizone' -> 'Template/AirhandlerFans/VAVMultizone.json'
7189 // We need to support mapping like this as well:
72- // 'Template.AirHandlerFans -> Template/AirhandlerFans/package'
73- // 'package' files behave kind of like 'index.html' files
90+ // 'Template.AirHandlerFans -> Template/AirhandlerFans/package.json'
7491 jsonFile = path . resolve (
75- prefix ,
92+ dirPath ,
7693 filePath . dir ,
7794 filePath . name ,
7895 "package.json" ,
@@ -81,20 +98,22 @@ function _findPath(prefix: string, reference: string): string | null {
8198 break ;
8299 }
83100 filePath = path . parse ( filePath . dir ) ;
84- jsonFile = path . resolve ( prefix , filePath . dir , `${ filePath . name } .json` ) ;
101+ jsonFile = path . resolve ( dirPath , filePath . dir , `${ filePath . name } .json` ) ;
85102 }
86103
87104 return fs . existsSync ( jsonFile ) ? jsonFile : null ;
88105}
89106
90- // When given a path, loads types. returns null if not found
91- export function loader ( prefix : string , reference : string ) : Object | undefined {
92- const modelicaDirs = [ prefix , ...MODELICAPATH ] ;
93-
107+ /**
108+ * Loads a Modelica JSON file given the full class name.
109+ * @param className The full Modelica class name to load (e.g. "Library.Package.Class")
110+ * @returns The loaded JSON object or undefined if not found
111+ */
112+ export function loader ( className : string ) : Object | undefined {
94113 // TODO: allow modelica paths
95- if ( ! reference . startsWith ( "Modelica" ) ) {
96- for ( const dir of modelicaDirs ) {
97- const jsonFile = _findPath ( dir , reference ) ;
114+ if ( ! className . startsWith ( "Modelica" ) ) {
115+ for ( const dir of MODELICA_JSON_PATH ) {
116+ const jsonFile = getPathFromClassName ( className , dir ) ;
98117 if ( jsonFile && fs . existsSync ( jsonFile ) ) {
99118 return require ( jsonFile ) ;
100119 }
0 commit comments