21
21
import java .util .Collections ;
22
22
import java .util .HashMap ;
23
23
import java .util .HashSet ;
24
+ import java .util .Iterator ;
24
25
import java .util .LinkedHashSet ;
25
26
import java .util .LinkedList ;
26
27
import java .util .List ;
27
28
import java .util .Map ;
29
+ import java .util .Map .Entry ;
30
+ import java .util .Optional ;
28
31
import java .util .Set ;
29
32
import java .util .function .Predicate ;
30
33
67
70
*/
68
71
public class ModuleEnvironment extends Environment {
69
72
protected final GlobalEnvironment heap ;
70
- protected Set <String > importedModules ;
73
+ /** Map of imported modules to resolved ModuleEnvironments, will only be empty in case of a module was in a cycle or got reloaded and failed during the reload. use {@link #importedModulesResolved} to lazily resolve the modules. */
74
+ protected Map <String , Optional <ModuleEnvironment >> importedModules ;
71
75
protected Set <String > extended ;
72
76
protected TypeStore typeStore ;
73
77
protected Set <IValue > productions ;
@@ -87,7 +91,7 @@ public class ModuleEnvironment extends Environment {
87
91
public ModuleEnvironment (String name , GlobalEnvironment heap ) {
88
92
super (ValueFactoryFactory .getValueFactory ().sourceLocation (URIUtil .assumeCorrect ("main" , name , "" )), name );
89
93
this .heap = heap ;
90
- this .importedModules = new HashSet < String >();
94
+ this .importedModules = new HashMap < >();
91
95
this .concreteSyntaxTypes = new HashMap <String , NonTerminalType >();
92
96
this .productions = new HashSet <IValue >();
93
97
this .generalKeywordParameters = new HashMap <Type ,List <KeywordFormal >>();
@@ -122,7 +126,7 @@ protected ModuleEnvironment(ModuleEnvironment env) {
122
126
@ Override
123
127
public void reset () {
124
128
super .reset ();
125
- this .importedModules = new HashSet <>();
129
+ this .importedModules = new HashMap <>();
126
130
this .concreteSyntaxTypes = new HashMap <>();
127
131
this .typeStore = new TypeStore ();
128
132
this .productions = new HashSet <IValue >();
@@ -142,9 +146,9 @@ public void extend(ModuleEnvironment other) {
142
146
// so that types become available
143
147
if (other .importedModules != null ) {
144
148
if (this .importedModules == null ) {
145
- this .importedModules = new HashSet < String >();
149
+ this .importedModules = new HashMap < >();
146
150
}
147
- this .importedModules .addAll (other .importedModules );
151
+ this .importedModules .putAll (other .importedModules );
148
152
}
149
153
150
154
if (other .concreteSyntaxTypes != null ) {
@@ -294,7 +298,7 @@ public IMap getSyntaxDefinition() {
294
298
result .put (VF .string (m ), t );
295
299
}else if (m .equals (getName ())) { // This is the root scope.
296
300
ISetWriter importWriter = VF .setWriter ();
297
- for (String impname : importedModules ){
301
+ for (String impname : importedModules . keySet () ){
298
302
if (!done .contains (impname )) todo .add (impname );
299
303
300
304
importWriter .insert (VF .string (impname ));
@@ -327,9 +331,13 @@ public boolean isModuleEnvironment() {
327
331
328
332
public void addImport (String name , ModuleEnvironment env ) {
329
333
assert heap .getModule (name ).equals (env );
330
- importedModules .add (name );
334
+ importedModules .put (name , Optional . ofNullable ( env ) );
331
335
typeStore .importStore (env .typeStore );
332
336
}
337
+
338
+ void deleteImport (String name ) {
339
+ importedModules .computeIfPresent (name , (k , v ) -> Optional .empty ());
340
+ }
333
341
334
342
public void addExtend (String name ) {
335
343
if (extended == null ) {
@@ -356,7 +364,7 @@ public List<AbstractFunction> getTests() {
356
364
357
365
@ Override
358
366
public Set <String > getImports () {
359
- return Collections .unmodifiableSet (importedModules );
367
+ return Collections .unmodifiableSet (importedModules . keySet () );
360
368
}
361
369
362
370
public Set <String > getImportsTransitive () {
@@ -384,11 +392,9 @@ public Set<String> getImportsTransitive() {
384
392
}
385
393
386
394
public void unImport (String moduleName ) {
387
- if (importedModules .remove (moduleName )) {
388
- ModuleEnvironment old = heap .getModule (moduleName );
389
- if (old != null ) {
390
- typeStore .unimportStores (new TypeStore [] { old .getStore () });
391
- }
395
+ var old = importedModules .remove (moduleName );
396
+ if (old != null && old .isPresent ()) {
397
+ typeStore .unimportStores (old .get ().getStore ());
392
398
}
393
399
cachedGeneralKeywordParameters = null ;
394
400
}
@@ -447,6 +453,7 @@ public Result<IValue> getVariable(QualifiedName name) {
447
453
448
454
return getFrameVariable (cons );
449
455
}
456
+
450
457
451
458
@ Override
452
459
public void storeVariable (String name , Result <IValue > value ) {
@@ -461,8 +468,7 @@ public void storeVariable(String name, Result<IValue> value) {
461
468
super .storeVariable (name , value );
462
469
}
463
470
else {
464
- for (String i : importedModules ) {
465
- ModuleEnvironment module = heap .getModule (i );
471
+ for (ModuleEnvironment module : importedModulesResolved ) {
466
472
result = module .getLocalPublicVariable (name );
467
473
468
474
if (result != null ) {
@@ -483,8 +489,7 @@ public org.rascalmpl.interpreter.result.Result<IValue> getSimpleVariable(String
483
489
return var ;
484
490
}
485
491
486
- for (String moduleName : importedModules ) {
487
- ModuleEnvironment mod = getImport (moduleName );
492
+ for (ModuleEnvironment mod : importedModulesResolved ) {
488
493
489
494
if (mod != null ) {
490
495
var = mod .getLocalPublicVariable (name );
@@ -511,8 +516,7 @@ protected Map<String,Result<IValue>> getVariableDefiningEnvironment(String name)
511
516
}
512
517
}
513
518
514
- for (String moduleName : importedModules ) {
515
- ModuleEnvironment mod = getImport (moduleName );
519
+ for (ModuleEnvironment mod : importedModulesResolved ) {
516
520
Result <IValue > r = null ;
517
521
if (mod != null && mod .variableEnvironment != null )
518
522
r = mod .variableEnvironment .get (name );
@@ -529,8 +533,7 @@ protected Map<String,Result<IValue>> getVariableDefiningEnvironment(String name)
529
533
public void getAllFunctions (String name , List <AbstractFunction > collection ) {
530
534
super .getAllFunctions (name , collection );
531
535
532
- for (String moduleName : importedModules ) {
533
- ModuleEnvironment mod = getImport (moduleName );
536
+ for (ModuleEnvironment mod : importedModulesResolved ) {
534
537
535
538
if (mod != null ) {
536
539
mod .getLocalPublicFunctions (name , collection );
@@ -542,8 +545,7 @@ public void getAllFunctions(String name, List<AbstractFunction> collection) {
542
545
public void getAllFunctions (Type returnType , String name , List <AbstractFunction > collection ) {
543
546
super .getAllFunctions (returnType , name , collection );
544
547
545
- for (String moduleName : importedModules ) {
546
- ModuleEnvironment mod = getImport (moduleName );
548
+ for (ModuleEnvironment mod : importedModulesResolved ) {
547
549
548
550
if (mod != null ) {
549
551
mod .getLocalPublicFunctions (returnType , name , collection );
@@ -732,8 +734,7 @@ public Set<GenericKeywordParameters> lookupGenericKeywordParameters(Type adt) {
732
734
result .add (new GenericKeywordParameters (this , list , getStore ().getKeywordParameters (adt )));
733
735
}
734
736
735
- for (String moduleName : importedModules ) {
736
- ModuleEnvironment mod = getImport (moduleName );
737
+ for (ModuleEnvironment mod : importedModulesResolved ) {
737
738
738
739
list = mod .generalKeywordParameters .get (adt );
739
740
if (list != null ) {
@@ -825,13 +826,33 @@ public String toString() {
825
826
826
827
@ Override
827
828
public ModuleEnvironment getImport (String moduleName ) {
828
- if ( importedModules .contains (moduleName )) {
829
- return heap .getModule (moduleName );
830
- }
831
- else {
832
- return null ;
829
+ var result = importedModules .computeIfPresent (moduleName ,
830
+ ( m , c ) -> c . isPresent () ? c : Optional . ofNullable ( heap .getModule (m ))
831
+ );
832
+ if ( result == null || result . isEmpty ()) {
833
+ return null ;
833
834
}
835
+ return result .get ();
834
836
}
837
+
838
+ private Iterable <ModuleEnvironment > importedModulesResolved =
839
+ () -> new Iterator <ModuleEnvironment >() {
840
+ Iterator <Entry <String , Optional <ModuleEnvironment >>> iterator = importedModules .entrySet ().iterator ();
841
+ @ Override
842
+ public boolean hasNext () {
843
+ return iterator .hasNext ();
844
+ }
845
+ @ Override
846
+ public ModuleEnvironment next () {
847
+ var entry = iterator .next ();
848
+ var result = entry .getValue ();
849
+ if (result .isEmpty ()) {
850
+ result = Optional .ofNullable (heap .getModule (entry .getKey ()));
851
+ entry .setValue (result );
852
+ }
853
+ return result .orElse (null );
854
+ }
855
+ };
835
856
836
857
@ Override
837
858
public void storeVariable (QualifiedName name , Result <IValue > result ) {
@@ -870,8 +891,7 @@ public Type lookupConcreteSyntaxType(String name) {
870
891
Type type = concreteSyntaxTypes .get (name );
871
892
872
893
if (type == null ) {
873
- for (String i : importedModules ) {
874
- ModuleEnvironment mod = getImport (i );
894
+ for (ModuleEnvironment mod : importedModulesResolved ) {
875
895
876
896
if (mod == null ) {
877
897
continue ;
@@ -989,8 +1009,7 @@ protected Environment getFlagsEnvironment(String name) {
989
1009
return env ;
990
1010
}
991
1011
992
- for (String moduleName : importedModules ) {
993
- ModuleEnvironment mod = getImport (moduleName );
1012
+ for (ModuleEnvironment mod : importedModulesResolved ) {
994
1013
if (mod == null ) {
995
1014
throw new RuntimeException ("getFlagsEnvironment" );
996
1015
}
0 commit comments