package org.simantics.scl.compiler.module; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Consumer; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.elaboration.modules.Documentation; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.elaboration.modules.TypeClass; import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance; import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor; import org.simantics.scl.compiler.elaboration.relations.SCLEntityType; import org.simantics.scl.compiler.elaboration.relations.SCLRelation; import org.simantics.scl.compiler.elaboration.rules.MappingRelation; import org.simantics.scl.compiler.elaboration.rules.TransformationRule; import org.simantics.scl.compiler.environment.filter.NamespaceFilter; import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor; import org.simantics.scl.compiler.top.ModuleInitializer; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.runtime.profiling.BranchPoint; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectObjectProcedure; import gnu.trove.procedure.TObjectProcedure; public class ConcreteModule implements Module { String moduleName; THashMap typeDescriptors = new THashMap(); THashMap effectConstructors = new THashMap(); THashMap typeClasses = new THashMap(); THashMap> typeClassInstances = new THashMap>(); THashMap values = new THashMap(); THashMap relations = new THashMap(); THashMap entityTypes = new THashMap(); THashMap rules = new THashMap(); THashMap mappingRelations = new THashMap(); ArrayList dependencies = new ArrayList(); THashMap branchPoints; CompilationError[] warnings = CompilationError.EMPTY_ARRAY; Map classes = Collections.emptyMap(); ClassLoader parentClassLoader; ModuleInitializer moduleInitializer; protected Documentation documentation; public ConcreteModule(String moduleName) { this.moduleName = moduleName; } public boolean addTypeDescriptor(String name, TypeDescriptor typeConstructor) { return typeDescriptors.put(name, typeConstructor) != null; } public boolean addEffectConstructor(String name, EffectConstructor effectConstructor) { return effectConstructors.put(name, effectConstructor) != null; } public boolean addTypeClass(String name, TypeClass typeClass) { return typeClasses.put(name, typeClass) != null; } public void addTypeClassInstance(TCon typeClass, TypeClassInstance typeClassInstance) { ArrayList instances = typeClassInstances.get(typeClass); if(instances == null) { instances = new ArrayList(); typeClassInstances.put(typeClass, instances); } instances.add(typeClassInstance); } public boolean addRule(TransformationRule rule) { return rules.put(rule.name.name, rule) != null; } public boolean addMappingRelation(MappingRelation relation) { return mappingRelations.put(relation.name.name, relation) != null; } public Collection getTypeClassesWithInstances() { return typeClassInstances.keySet(); } public boolean addValue(SCLValue value) { return values.put(value.getName().name, value) != null; } public SCLValue addValue(String name, Constant constant) { SCLValue value = new SCLValue(Name.create(moduleName, name), constant); addValue(value); return value; } public void addRelation(String name, SCLRelation relation) { relations.put(name, relation); } public void addEntityType(String name, SCLEntityType entityType) { entityTypes.put(name, entityType); } public void addDependency(ImportDeclaration module) { if(!dependencies.contains(module)) dependencies.add(module); } public Collection getValues() { return values.values(); } public Collection getRules() { return rules.values(); } public Collection getMappingRelations() { return mappingRelations.values(); } @Override public String getName() { return moduleName; } @Override public SCLValue getValue(String name) { return values.get(name); } @Override public SCLRelation getRelation(String name) { return relations.get(name); } @Override public MappingRelation getMappingRelation(String name) { return mappingRelations.get(name); } @Override public TransformationRule getRule(String name) { return rules.get(name); } @Override public SCLEntityType getEntityType(String name) { return entityTypes.get(name); } public TypeClass getTypeClass(String name) { return typeClasses.get(name); } @Override public Collection getInstances(TCon typeClass) { Collection result = typeClassInstances.get(typeClass); if(result == null) return Collections.emptyList(); else return result; } @Override public TypeDescriptor getTypeDescriptor(String name) { return typeDescriptors.get(name); } @Override public EffectConstructor getEffectConstructor(String name) { return effectConstructors.get(name); } public Collection getTypeClasses() { return typeClasses.values(); } public THashMap> getTypeInstances() { return typeClassInstances; } @Override public List getDependencies() { return dependencies; } public void setDocumentation(Documentation documentation) { this.documentation = documentation; } public Documentation getDocumentation() { return documentation; } public void setClasses(Map classes) { this.classes = classes; } @Override public byte[] getClass(String name) { return classes.get(name); } public void setModuleInitializer(ModuleInitializer moduleInitializer) { this.moduleInitializer = moduleInitializer; } @Override public ModuleInitializer getModuleInitializer() { return moduleInitializer; } @Override public String toString() { return moduleName; } @Override public void findValuesForPrefix(final String prefix, final NamespaceFilter filter, final TObjectProcedure proc) { this.values.forEachEntry(new TObjectObjectProcedure() { @Override public boolean execute(String name, SCLValue value) { if(value.isPrivate()) return true; String lowerPrefix = prefix.toLowerCase(); String lowerName = name.toLowerCase(); if(lowerName.startsWith(lowerPrefix) && filter.isValueIncluded(name)) proc.execute(value); return true; } }); } @Override public void findValuesForPrefix(String prefix, NamespaceFilter filter, Consumer consumer) { values.values().forEach((Consumer) (value) -> { String lowerPrefix = prefix.toLowerCase(); String lowerName = value.getName().name.toLowerCase(); if(lowerName.startsWith(lowerPrefix) && filter.isValueIncluded(value.getName().name)) consumer.accept(value); }); } public Collection getRelations() { return relations.values(); } @Override public void findTypesForPrefix(String prefix, NamespaceFilter filter, Consumer consumer) { typeDescriptors.values().forEach(type -> { TCon tcon = type.name; if (tcon.name.toLowerCase().startsWith(prefix.toLowerCase()) && filter.isValueIncluded(tcon.name)) consumer.accept(tcon); }); } public void setBranchPoints(THashMap branchPoints) { this.branchPoints = branchPoints; } @Override public THashMap getBranchPoints() { return branchPoints; } @Override public void dispose() { } public void setWarnings(CompilationError[] warnings) { this.warnings = warnings; } public CompilationError[] getWarnings() { return warnings; } @Override public ClassLoader getParentClassLoader() { return parentClassLoader; } public void setParentClassLoader(ClassLoader parentClassLoader) { if(parentClassLoader == null) throw new NullPointerException(); this.parentClassLoader = parentClassLoader; } }