package jetbrains.mps.baseLanguage.textGen; /*Generated by MPS */ import java.util.Set; import java.util.Map; import org.jetbrains.mps.openapi.model.SNode; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import java.util.HashMap; import java.util.HashSet; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations; import jetbrains.mps.util.JavaNameUtil; /*package*/ class ImportsContext { private final String packageName; private final Set<String> packageSimpleNames; private final Map<String, String> bindings; private ContextClassifiersInRoot contextClassifiers; /*package*/ ImportsContext(SNode rootNode) { this.packageName = SModelOperations.getModelName(SNodeOperations.getModel(rootNode)); contextClassifiers = new ContextClassifiersInRoot(rootNode); // init nested class bindings bindings = new HashMap<String, String>(); // init package simple names packageSimpleNames = new HashSet<String>(); for (SNode classifier : SModelOperations.roots(SNodeOperations.getModel(rootNode), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"))) { packageSimpleNames.add(SPropertyOperations.getString(classifier, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"))); } } /*package*/ ImportEntry getClassifierRefText(String packageName, String fqName, SNode contextNode) { // main invariant: use always nested names, import only root classifiers String nestedName = JavaNameUtil.nestedClassName(packageName, fqName); int dotIndex = nestedName.indexOf('.'); String rootClassifierName = (dotIndex == -1 ? nestedName : nestedName.substring(0, dotIndex)); String nestedPart = nestedName.substring(rootClassifierName.length()); ImportEntry entry = getRootClassifierRefText(packageName, rootClassifierName, contextNode); if (nestedPart.length() > 0) { return new ImportEntry(nestedPart, entry); } else { return entry; } } private ImportEntry getRootClassifierRefText(String packageName, String className, SNode contextNode) { assert !(className.contains(".")); String fqName = packageName + "." + className; Map<String, String> nestedClassifiersBinding = contextClassifiers.getContextClassifiers(contextNode); // 1) check nested classes context if (nestedClassifiersBinding.containsKey(className)) { if (fqName.equals(nestedClassifiersBinding.get(className))) { return new ImportEntry(className); } else { return new ImportEntry(fqName); } } // 2) check current binding if (bindings.containsKey(className)) { if (fqName.equals(bindings.get(className))) { return new ImportEntry(className); } else { return new ImportEntry(fqName); } } // 3) add binding, question is: add explicit import or not? bindings.put(className, fqName); boolean shouldBeImported; if (packageName.equals(this.packageName)) { shouldBeImported = false; } else if (packageName.equals("java.lang")) { // java.lang model: generate without explicit import if context package doesn't contains same simple name shouldBeImported = packageSimpleNames.contains(className); } else { // in other cases: generate explicit import shouldBeImported = true; } return new ImportEntry((shouldBeImported ? fqName : null), className); } }