@@ -27,247 +27,10 @@ import Set;
2727import String ;
2828import ValueIO ;
2929import util ::Reflective ;
30- import util ::FileSystem ;
3130
3231import lang ::rascalcore ::compile ::util ::Names ; // TODO: refactor, this is an undesired dependency on compile
3332import lang ::rascalcore ::compile ::CompileTimeError ;
3433
35-
36- str makeFileName (str qualifiedModuleName , str extension = "rsc" ) {
37- str qnameSlashes = replaceAll (qualifiedModuleName , "::" , "/" );
38- int n = findLast (qnameSlashes , "/" );
39- str prefix = extension == "rsc" ? "" : "$" ;
40- str package = extension == "rsc" ? "" : "rascal/" ;
41- qnameSlashes = n < 0 ? "<prefix > " + qnameSlashes : qnameSlashes [0 ..n ] + "/<prefix > " + qnameSlashes [n +1 ..];
42- return "<package ><qnameSlashes ><isEmpty (extension ) ? "" : ".<extension > " > " ;
43- }
44-
45- loc getSearchPathLoc (str filePath , PathConfig pcfg ){
46- for (loc dir <- pcfg .srcs + pcfg .libs ){
47- fileLoc = dir + filePath ;
48- if (exists (fileLoc )){
49- //println("getModuleLocation <qualifiedModuleName> =\> <fileLoc>");
50- return fileLoc ;
51- }
52- }
53- throw "Module with path <filePath > not found" ;
54- }
55-
56- @synopsis {Get the location of a named module, search for `src` in srcs and `tpl` in libs}
57- loc getModuleLocation (str qualifiedModuleName , PathConfig pcfg ){
58- fileName = makeFileName (qualifiedModuleName , extension ="rsc" );
59- for (loc dir <- pcfg .srcs ){
60- fileLoc = dir + fileName ;
61- if (exists (fileLoc )){
62- return fileLoc ;
63- }
64- }
65- fileName = makeFileName (qualifiedModuleName , extension ="tpl" );
66- for (loc dir <- pcfg .libs ){
67- fileLoc = dir + fileName ;
68-
69- if (exists (fileLoc )){
70- return fileLoc ;
71- }
72- }
73- throw "Module `<qualifiedModuleName > ` not found;\n <pcfg > " ;
74- }
75-
76- tuple [str ,str ] splitFileExtension (str path ){
77- int n = findLast (path , "." );
78- if (n < 0 ) return <path , "" > ;
79- return <path [0 .. n ], path [n +1 .. ]> ;
80- }
81-
82- @synopsis {Determine length of common suffix of list of strings}
83- int commonSuffix (list [str ] dir , list [str ] m )
84- = commonPrefix (reverse (dir ), reverse (m ));
85-
86- @synopsis {Determine length of common prefix of list of strings}
87- int commonPrefix (list [str ] rdir , list [str ] rm ){
88- for (int i <- index (rm )){
89- if (i > = size (rdir )){
90- return i ;
91- } else if (rdir [i ] != rm [i ]){
92- return i ;
93- } else {
94- continue ;
95- }
96- }
97- return size (rm );
98- }
99-
100- @synopsis {Find the module name corresponding to a given module location via its (src or tpl) location}
101- str getModuleName (loc moduleLoc , PathConfig pcfg ){
102- modulePath = moduleLoc .path ;
103-
104- rscFile = endsWith (modulePath , "rsc" );
105- tplFile = endsWith (modulePath , "tpl" );
106-
107- if (!( rscFile || tplFile )){
108- throw "Not a Rascal .src or .tpl file: <moduleLoc > " ;
109- }
110-
111- // Find matching .rsc file in source directories
112- if (rscFile ){
113- for (loc dir <- pcfg .srcs ){
114- if (moduleLoc .authority == dir .authority && startsWith (modulePath , dir .path )) {
115- moduleName = replaceFirst (modulePath , dir .path , "" );
116- <moduleName , ext > = splitFileExtension (moduleName );
117- if (moduleName [0 ] == "/" ){
118- moduleName = moduleName [1 ..];
119- }
120- moduleName = replaceAll (moduleName , "/" , "::" );
121- return moduleName ;
122- }
123- }
124- }
125-
126- // Find longest matching .tpl file in library directories
127-
128- <modulePathNoExt , ext > = splitFileExtension (modulePath );
129- while (modulePathNoExt [0 ] == "/" ){
130- modulePathNoExt = modulePathNoExt [1 ..];
131- }
132-
133- modulePathAsList = split ("/" , modulePathNoExt );
134- if (tplFile ){
135- lastName = modulePathAsList [-1 ];
136- if (lastName [0 ] == "$" ){
137- modulePathAsList = [*modulePathAsList [..-1 ],lastName [1 ..]];
138- }
139- }
140- if (modulePathAsList [0 ] == "rascal" ){
141- modulePathAsList = modulePathAsList [1 ..];
142- }
143- modulePathReversed = reverse (modulePathAsList );
144-
145- int longestSuffix = 0 ;
146- for (loc dir <- pcfg .libs ){
147- dir = dir + "rascal" ;
148- dpath = dir .path ;
149-
150- while (dpath [0 ] == "/" ){
151- dpath = dpath [1 ..];
152- }
153-
154- for (loc file <- find (dir , "tpl" )){
155- candidate = replaceFirst (file .path , dpath , "" );
156- <candidate , ext > = splitFileExtension (candidate );
157- while (candidate [0 ] == "/" ){
158- candidate = candidate [1 ..];
159- }
160-
161- candidateAsList = split ("/" , candidate );
162- lastName = candidateAsList [-1 ];
163- if (lastName [0 ] == "$" ){
164- candidateAsList = [*candidateAsList [..-1 ],lastName [1 ..]];
165- }
166- // println("cand: <candidateAsList>, modpath: <modulePathAsList>");
167- n = commonPrefix (reverse (candidateAsList ), modulePathReversed );
168-
169- if (n > longestSuffix ){
170- longestSuffix = n ;
171- }
172- }
173- }
174-
175- if (longestSuffix > 0 ){
176- lastName = modulePathAsList [-1 ];
177- if (lastName [0 ] == "$" ){
178- modulePathAsList = [*modulePathAsList [..-1 ],lastName [1 ..]];
179- }
180- return intercalate ("::" , modulePathAsList [size (modulePathAsList ) - longestSuffix .. ]);
181- }
182- throw "No module name found for <moduleLoc > ;\n srcs=<pcfg .srcs > ;\n libs=<pcfg .libs > " ;
183- }
184-
185- @synopsis {Derive a location from a given module name for reading}
186- @description {
187- Given a module name, a file name extension, and a PathConfig,
188- a path name is constructed from the module name + extension.
189-
190- If a file F with this path exists in one of the directories in the PathConfig,
191- then the pair <true, F> is returned. Otherwise <false, some error location> is returned.
192-
193- For a source extension (typically "rsc" or "mu" but this can be configured) srcs is searched, otherwise binPath + libs.
194- }
195- @examples {
196- ```rascal-shell
197- import util::Reflective;
198- getDerivedReadLoc("List", "rsc", pathConfig());
199- getDerivedReadLoc("experiments::Compiler::Compile", "rvm", pathConfig());
200- getDerivedReadLoc("experiments::Compiler::muRascal2RVM::Library", "mu", pathConfig());
201- ```
202- }
203- @benefits {
204- This function is useful for type checking and compilation tasks, when derived information related to source modules has to be read
205- from locations in different, configurable, directories.
206- }
207-
208- tuple [bool , loc ] getDerivedReadLoc (str qualifiedModuleName , str extension , PathConfig pcfg , set [str ] srcExtensions = {"rsc" , "mu" }, str rootDir = "" ){
209- fileName = makeFileName (qualifiedModuleName , extension =extension );
210- //println("getDerivedReadLoc: <fileName>");
211-
212- if (extension in srcExtensions ){
213- for (loc dir <- pcfg .srcs ){ // In a source directory?
214- fileLoc = dir + rootDir + fileName ;
215- if (exists (fileLoc )){
216- //println("getDerivedReadLoc: <qualifiedModuleName>, <extension> =\> <fileLoc");
217- return <true , fileLoc > ;
218- }
219- }
220- } else {
221- for (loc dir <- pcfg .bin + pcfg .libs ){ // In a bin or lib directory?
222-
223- fileLoc = dir + rootDir + fileName ;
224- if (exists (fileLoc )){
225- //println("getDerivedReadLoc: <qualifiedModuleName>, <extension> =\> <fileLoc>");
226- return <true , fileLoc > ;
227- }
228- }
229- }
230- //println("getDerivedReadLoc: <qualifiedModuleName>, <extension> =\> |error:///|");
231- return <false , |error:///| > ;
232- }
233-
234-
235- @synopsis {Derive a location from a given module name for writing}
236- @description {
237- Given a module name, a file name extension, and a PathConfig,
238- a path name is constructed from the module name + extension.
239-
240- For source modules, a writable location cannot be derived.
241- For other modules, a location for this path in bin will be returned.
242- }
243- @examples {
244- ```rascal-shell
245- import util::Reflective;
246- getDerivedWriteLoc("List", "rvm", pathConfig());
247- getDerivedWriteLoc("experiments::Compiler::Compile", "rvm", pathConfig());
248- ```
249-
250- ```rascal-shell,error
251- getDerivedWriteLoc("experiments::Compiler::muRascal2RVM::Library", "rsc", pathConfig());
252- ```
253- }
254- @benefits {
255- This function is useful for type checking and compilation tasks, when derived information related to source modules has to be written
256- to locations in separate, configurable, directories.
257- }
258- loc getDerivedWriteLoc (str qualifiedModuleName , str extension , PathConfig pcfg , set [str ] srcExtensions = {"rsc" , "mu" }, str rootDir = "" ){
259- if (extension in srcExtensions ){
260- throw "Cannot derive writable location for module <qualifiedModuleName > with extension <extension > " ;
261- }
262- fileNameSrc = makeFileName (qualifiedModuleName );
263- fileNameBin = makeFileName (qualifiedModuleName , extension =extension );
264-
265- bin = pcfg .bin ;
266- fileLocBin = bin + rootDir + fileNameBin ;
267- //println("getDerivedWriteLoc: <qualifiedModuleName>, <extension> =\> <fileLocBin>");
268- return fileLocBin ;
269- }
270-
27134void checkSupportedByParserGenerator (Tree t , Collector c ){
27235 c .require ("implemented by parsergenerator" , t , [t ], void (Solver s ){
27336 tp = s .getType (t );
0 commit comments