package jetbrains.mps.ide.depanalyzer; /*Generated by MPS */ import org.jetbrains.mps.openapi.module.SRepository; import org.jetbrains.mps.openapi.module.SModule; import java.util.List; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.LinkedList; import java.util.Map; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.HashMap; import org.jetbrains.mps.openapi.module.SModuleReference; import java.util.ArrayList; import jetbrains.mps.project.AbstractModule; import jetbrains.mps.project.structure.modules.ModuleDescriptor; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.module.SDependency; import jetbrains.mps.smodel.Language; import jetbrains.mps.smodel.Generator; import jetbrains.mps.project.structure.modules.DevkitDescriptor; import jetbrains.mps.project.structure.modules.LanguageDescriptor; import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.internal.collections.runtime.ISelector; import jetbrains.mps.project.structure.modules.GeneratorDescriptor; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.Set; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.baseLanguage.tuples.runtime.MultiTuple; public class DependencyUtil { private boolean myNeedRuntime; private final SRepository myRepo; /*package*/ DependencyUtil(SRepository repo) { myRepo = repo; } public DependencyUtil trackRuntime(boolean needRuntime) { this.myNeedRuntime = needRuntime; return this; } /** * Build set of dependencies for the given module, grouped under a fake root container */ public DepLink build(SModule module) { DepLink rv = new DepLink(module.getModuleReference(), DependencyUtil.Role.None, null); List<DepLink> queue = ListSequence.fromList(new LinkedList<DepLink>()); ListSequence.fromList(queue).addElement(rv); Map<Dependency, DepLink> visited = MapSequence.fromMap(new HashMap<Dependency, DepLink>()); while (ListSequence.fromList(queue).isNotEmpty()) { DepLink e = ListSequence.fromList(queue).removeElementAt(0); List<DepLink> dependencies = dependencies(e.role, e.module); for (DepLink d : ListSequence.fromList(dependencies)) { d.myParent = e; ListSequence.fromList(e.children()).addElement(d); Dependency key = d.getRoleModuleKey(); if (MapSequence.fromMap(visited).containsKey(key)) { d.setReused(MapSequence.fromMap(visited).get(key)); } else { MapSequence.fromMap(visited).put(key, d); ListSequence.fromList(queue).addElement(d); } } } return rv; } private List<DepLink> dependencies(DependencyUtil.Role role, SModuleReference moduleRef) { List<DepLink> result = ListSequence.fromList(new ArrayList<DepLink>()); SModule module = moduleRef.resolve(myRepo); if (!(module instanceof AbstractModule)) { return result; } AbstractModule abstractModule = (AbstractModule) module; ModuleDescriptor descr = abstractModule.getModuleDescriptor(); if (descr == null) { return result; } switch (role) { case OwnedGenerator: case None: // first step addDeps(result, abstractModule.collectLanguagesAndDevkits().devkits, DependencyUtil.Role.UsedDevkit, DependencyUtil.LinkType.UsesDevkit); for (SLanguage lang : module.getUsedLanguages()) { SModule langModule = lang.getSourceModule(); if (langModule != null) { ListSequence.fromList(result).addElement(new DepLink(langModule.getModuleReference(), DependencyUtil.Role.UsedLanguage, DependencyUtil.LinkType.UsesLanguage)); } } for (SDependency dep : module.getDeclaredDependencies()) { switch (dep.getScope()) { case EXTENDS: SModule t = dep.getTarget(); if (t instanceof Language) { ListSequence.fromList(result).addElement(new DepLink(dep.getTargetModule(), DependencyUtil.Role.RegularDependency, DependencyUtil.LinkType.ExtendsLanguage)); } else if (t instanceof Generator) { ListSequence.fromList(result).addElement(new DepLink(dep.getTargetModule(), DependencyUtil.Role.RegularDependency, DependencyUtil.LinkType.ExtendsGenerator)); } else { // just in case module could not be resolved ListSequence.fromList(result).addElement(new DepLink(dep.getTargetModule(), DependencyUtil.Role.RegularDependency, DependencyUtil.LinkType.Depends)); } break; case DESIGN: ListSequence.fromList(result).addElement(new DepLink(dep.getTargetModule(), DependencyUtil.Role.RegularDependency, DependencyUtil.LinkType.Depends)); break; case RUNTIME: ListSequence.fromList(result).addElement(new DepLink(dep.getTargetModule(), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.Depends)); break; default: ListSequence.fromList(result).addElement(new DepLink(dep.getTargetModule(), DependencyUtil.Role.RegularDependency, (dep.isReexport() ? DependencyUtil.LinkType.ReexportsDep : DependencyUtil.LinkType.Depends))); } } if (module instanceof Language) { // generators and generators dependencies are now also added to language dependencies (MPS-15883) for (Generator g : ((Language) module).getGenerators()) { ListSequence.fromList(result).addElement(new DepLink(g.getModuleReference(), DependencyUtil.Role.OwnedGenerator, DependencyUtil.LinkType.Generator)); } } if (module instanceof Generator) { Language srcLang = ((Generator) module).getSourceLanguage(); ListSequence.fromList(result).addElement(new DepLink(srcLang.getModuleReference(), DependencyUtil.Role.SourceLanguage, DependencyUtil.LinkType.GeneratorLanguage)); } break; case UsedDevkit: // explicit use of devkit case DependencyDevkit: DevkitDescriptor devkit = as_he47wm_a0a0a3g0g(descr, DevkitDescriptor.class); if (devkit == null) { break; } boolean direct = role == DependencyUtil.Role.UsedDevkit; addDeps(result, devkit.getExtendedDevkits(), (direct ? DependencyUtil.Role.UsedDevkit : DependencyUtil.Role.DependencyDevkit), DependencyUtil.LinkType.ExtendsDevkit); addDeps(result, devkit.getExportedLanguages(), (direct ? DependencyUtil.Role.UsedLanguage : DependencyUtil.Role.DependencyLanguage), DependencyUtil.LinkType.ExportsLanguage); addDeps(result, devkit.getExportedSolutions(), (direct ? DependencyUtil.Role.RegularDependency : DependencyUtil.Role.RuntimeDependency), DependencyUtil.LinkType.ExportsSolution); break; case UsedLanguage: LanguageDescriptor lang = as_he47wm_a0a0a4g0g(descr, LanguageDescriptor.class); if (lang == null) { break; } addDeps(result, lang.getExtendedLanguages(), DependencyUtil.Role.UsedLanguage, DependencyUtil.LinkType.ExtendsLanguage); if (myNeedRuntime) { addDeps(result, lang.getRuntimeModules(), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.ExportsRuntime); } break; case RegularDependency: addDeps(result, getReexportDeps(descr), DependencyUtil.Role.RegularDependency, DependencyUtil.LinkType.ReexportsDep); if (descr instanceof LanguageDescriptor) { addDeps(result, (as_he47wm_a0a1a0a1a5g0g(descr, LanguageDescriptor.class)).getExtendedLanguages(), DependencyUtil.Role.RegularDependency, DependencyUtil.LinkType.ExtendsLanguage); } if (myNeedRuntime) { AbstractModule.LangAndDevkits actualUses = abstractModule.collectLanguagesAndDevkits(); addDeps(result, getNonreexportDeps(descr), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.Depends); addDeps(result, Sequence.fromIterable(((Iterable<SLanguage>) actualUses.languages)).select(new ISelector<SLanguage, SModuleReference>() { public SModuleReference select(SLanguage it) { return it.getSourceModuleReference(); } }), DependencyUtil.Role.DependencyLanguage, DependencyUtil.LinkType.UsesLanguage); addDeps(result, actualUses.devkits, DependencyUtil.Role.DependencyDevkit, DependencyUtil.LinkType.UsesDevkit); } break; case RuntimeDependency: if (myNeedRuntime) { AbstractModule.LangAndDevkits actualUses = abstractModule.collectLanguagesAndDevkits(); addDeps(result, getReexportDeps(descr), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.ReexportsDep); addDeps(result, getNonreexportDeps(descr), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.Depends); addDeps(result, Sequence.fromIterable(((Iterable<SLanguage>) actualUses.languages)).select(new ISelector<SLanguage, SModuleReference>() { public SModuleReference select(SLanguage it) { return it.getSourceModuleReference(); } }), DependencyUtil.Role.DependencyLanguage, DependencyUtil.LinkType.UsesLanguage); addDeps(result, actualUses.devkits, DependencyUtil.Role.DependencyDevkit, DependencyUtil.LinkType.UsesDevkit); if (descr instanceof LanguageDescriptor) { addDeps(result, (as_he47wm_a0a1a0a5a0a6g0g(descr, LanguageDescriptor.class)).getExtendedLanguages(), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.ExtendsLanguage); } if (descr instanceof GeneratorDescriptor) { GeneratorDescriptor gen = (GeneratorDescriptor) descr; // generator languages are now also dependencies addDeps(result, gen.getDepGenerators(), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.DependsOnGenerator); ListSequence.fromList(result).addElement(new DepLink((as_he47wm_a0a0a0a0a3a6a0a6g0g(module, Generator.class)).getSourceLanguage().getModuleReference(), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.GeneratorLanguage)); } } break; case SourceLanguage: // dependency from generator to its source language addDeps(result, check_he47wm_b0b0h6a6(as_he47wm_a0b0b0h6a6(descr, LanguageDescriptor.class)), DependencyUtil.Role.SourceLanguage, DependencyUtil.LinkType.ExtendsLanguage); addDeps(result, check_he47wm_b0c0h6a6(as_he47wm_a0b0c0h6a6(descr, LanguageDescriptor.class)), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.ExportsRuntime); break; case DependencyLanguage: addDeps(result, check_he47wm_b0a0i6a6(as_he47wm_a0b0a0i6a6(descr, LanguageDescriptor.class)), DependencyUtil.Role.DependencyLanguage, DependencyUtil.LinkType.ExtendsLanguage); addDeps(result, check_he47wm_b0b0i6a6(as_he47wm_a0b0b0i6a6(descr, LanguageDescriptor.class)), DependencyUtil.Role.RuntimeDependency, DependencyUtil.LinkType.ExportsRuntime); break; default: } return result; } public void addDeps(List<DepLink> result, Iterable<SModuleReference> modules, final DependencyUtil.Role role, final DependencyUtil.LinkType linktype) { if (modules == null) { return; } ListSequence.fromList(result).addSequence(Sequence.fromIterable(modules).select(new ISelector<SModuleReference, DepLink>() { public DepLink select(SModuleReference module) { return new DepLink(module, role, linktype); } })); } private static Iterable<SModuleReference> getReexportDeps(ModuleDescriptor descr) { return SetSequence.fromSet(((Set<jetbrains.mps.project.structure.modules.Dependency>) descr.getDependencies())).where(new IWhereFilter<jetbrains.mps.project.structure.modules.Dependency>() { public boolean accept(jetbrains.mps.project.structure.modules.Dependency dep) { return dep.isReexport(); } }).select(new ISelector<jetbrains.mps.project.structure.modules.Dependency, SModuleReference>() { public SModuleReference select(jetbrains.mps.project.structure.modules.Dependency dep) { return dep.getModuleRef(); } }); } private static Iterable<SModuleReference> getNonreexportDeps(ModuleDescriptor descr) { return SetSequence.fromSet(((Set<jetbrains.mps.project.structure.modules.Dependency>) descr.getDependencies())).where(new IWhereFilter<jetbrains.mps.project.structure.modules.Dependency>() { public boolean accept(jetbrains.mps.project.structure.modules.Dependency dep) { return !(dep.isReexport()); } }).select(new ISelector<jetbrains.mps.project.structure.modules.Dependency, SModuleReference>() { public SModuleReference select(jetbrains.mps.project.structure.modules.Dependency dep) { return dep.getModuleRef(); } }); } public enum LinkType { Depends("depends on"), ReexportsDep("reexports dependency on"), UsesLanguage("uses language"), ExtendsLanguage("extends language"), ExtendsGenerator("extends generator"), ExportsRuntime("exports runtime"), ExportsRuntimeLib("has runtime library"), UsesDevkit("uses devkit"), ExportsLanguage("exports language"), ExportsSolution("exports solution"), ExtendsDevkit("extends devkit"), GeneratorLanguage("generator language"), DependsOnGenerator("depends on generator"), Generator("generator"), LangCore(""); private String myText; LinkType(String text) { myText = text; } @Override public String toString() { return myText; } } /** * None is a fake role to get initial set of dependencies * UsedLanguage reflects language in use by the module. languages extended by UsedLanguage are reflected with the same role, too. * DependencyLanguage language in use by a module dependency other than 'used language' * UsedDevkit - explicit devkit dependency, direct or indirect (i.e. devkit1 extends devkit2 * DependencyDevkit - devkit dependencies from a module dependency other than 'UsedDevkit' (indirectly involved devkits) * RegularDependency - direct or indirect dependency of original module * OwnedGenerator - dependency between a language and its generators * SourceLanguage - dependency from generator to its owning language */ public enum Role { None(), RegularDependency(), RuntimeDependency(), UsedLanguage(), DependencyLanguage(), UsedDevkit(), DependencyDevkit(), SourceLanguage(), OwnedGenerator(); Role() { } public boolean isUsedLanguage() { return this == DependencyUtil.Role.UsedLanguage; } public boolean isDependency() { return this == DependencyUtil.Role.RegularDependency || this == DependencyUtil.Role.OwnedGenerator || this == DependencyUtil.Role.RuntimeDependency; } } public static class Dependency extends MultiTuple._2<SModuleReference, DependencyUtil.Role> { public Dependency() { super(); } public Dependency(SModuleReference module, DependencyUtil.Role role) { super(module, role); } public SModuleReference module(SModuleReference value) { return super._0(value); } public DependencyUtil.Role role(DependencyUtil.Role value) { return super._1(value); } public SModuleReference module() { return super._0(); } public DependencyUtil.Role role() { return super._1(); } } private static Set<SModuleReference> check_he47wm_b0b0h6a6(LanguageDescriptor checkedDotOperand) { if (null != checkedDotOperand) { return checkedDotOperand.getExtendedLanguages(); } return null; } private static Set<SModuleReference> check_he47wm_b0c0h6a6(LanguageDescriptor checkedDotOperand) { if (null != checkedDotOperand) { return checkedDotOperand.getRuntimeModules(); } return null; } private static Set<SModuleReference> check_he47wm_b0a0i6a6(LanguageDescriptor checkedDotOperand) { if (null != checkedDotOperand) { return checkedDotOperand.getExtendedLanguages(); } return null; } private static Set<SModuleReference> check_he47wm_b0b0i6a6(LanguageDescriptor checkedDotOperand) { if (null != checkedDotOperand) { return checkedDotOperand.getRuntimeModules(); } return null; } private static <T> T as_he47wm_a0a0a3g0g(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0a0a4g0g(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0a1a0a1a5g0g(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0a1a0a5a0a6g0g(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0a0a0a0a3a6a0a6g0g(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0b0b0h6a6(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0b0c0h6a6(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0b0a0i6a6(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } private static <T> T as_he47wm_a0b0b0i6a6(Object o, Class<T> type) { return (type.isInstance(o) ? (T) o : null); } }