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);
}
}