package jetbrains.mps.lang.generator.generator.baseLanguage.template.util;
/*Generated by MPS */
import jetbrains.mps.generator.template.TemplateQueryContext;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.baseLanguage.tuples.runtime.MultiTuple;
import jetbrains.mps.generator.impl.template.MetaObjectGenerationHelper;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
public class GenUtil {
private static final String KEY = "VarName";
public GenUtil() {
}
public static String getVar(TemplateQueryContext context, SNode node, int skipMacro) {
List<SNode> macros = ListSequence.fromList(SNodeOperations.getChildren(node)).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return SNodeOperations.isInstanceOf(it, MetaAdapterFactory.getConcept(0xb401a68083254110L, 0x8fd384331ff25befL, 0xfd47ed6742L, "jetbrains.mps.lang.generator.structure.NodeMacro"));
}
}).toListSequence();
SNode real = (ListSequence.fromList(macros).count() <= skipMacro ? node : ListSequence.fromList(macros).getElement(skipMacro));
return (String) context.getTransientObject(MultiTuple.<String,SNode>from(KEY, real));
}
public static String saveListVar(TemplateQueryContext context, SNode node, int varIndex) {
// Don't want "tlist" and "tnode" scattered around
return saveVar(context, node, "tlist" + varIndex);
}
public static String saveNodeVar(TemplateQueryContext context, SNode node, int varIndex, boolean canBeNull) {
// Don't want "tlist" and "tnode" scattered around
String varName = saveVar(context, node, "tnode" + varIndex);
node.putUserObject("GenUtil:NotNull", Boolean.valueOf(!(canBeNull)));
return varName;
}
public static String saveVar(TemplateQueryContext context, SNode node, String var) {
SNode original = (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0xb401a68083254110L, 0x8fd384331ff25befL, 0xfd47ed6742L, "jetbrains.mps.lang.generator.structure.NodeMacro")) ? SNodeOperations.getParent(node) : node);
if (context.getTransientObject(original) == null) {
// guess, it's a mechanism to access variable name without knowledge of skipMacro value
context.putTransientObject(original, var);
}
context.putTransientObject(MultiTuple.<String,SNode>from(KEY, node), var);
return var;
}
public static String getVarHack(TemplateQueryContext context, SNode node) {
// see saveVar above
Object obj = context.getTransientObject(node);
return (obj instanceof String ? (String) obj : null);
}
public static boolean isCollectionVariable(TemplateQueryContext context, SNode node) {
// or !startsWith("tnode")?
String n = getVarHack(context, node);
return n != null && n.startsWith("tlist");
}
public static boolean isNodeVariable(TemplateQueryContext context, SNode node) {
String n = getVarHack(context, node);
return n != null && n.startsWith("tnode");
}
public static boolean isNonNullNodeVariable(TemplateQueryContext context, SNode node) {
return isNodeVariable(context, node) && Boolean.TRUE.equals(node.getUserObject("GenUtil:NotNull"));
}
public static boolean isNullableNodeVariable(TemplateQueryContext context, SNode node) {
return isNodeVariable(context, node) && !(Boolean.TRUE.equals(node.getUserObject("GenUtil:NotNull")));
}
/**
* Record the fact template for given node has been extracted into distinct method
*/
public static void markExtractedMethodForTemplate(TemplateQueryContext context, SNode node, String methodName) {
context.putTransientObject(MultiTuple.<String,SNode>from("meth", node), methodName);
}
/**
* Tell previously recorded name of the method extracted for the given template node.
*/
public static String getExtractedMethodName(TemplateQueryContext context, SNode node) {
return (String) context.getTransientObject(MultiTuple.<String,SNode>from("meth", node));
}
public static boolean hasMetaObjectHelper(TemplateQueryContext context, SNode node) {
return getMetaObjectHelper(context, node) != null;
}
public static MetaObjectGenerationHelper getMetaObjectHelper(TemplateQueryContext context, SNode node) {
return (MetaObjectGenerationHelper) context.getTransientObject(MultiTuple.<String,SNode>from("meta-object-helper", node));
}
public static MetaObjectGenerationHelper createMetaObjectHelper(TemplateQueryContext context, SNode node) {
MetaObjectGenerationHelper rv = new MetaObjectGenerationHelper();
context.putTransientObject(MultiTuple.<String,SNode>from("meta-object-helper", node), rv);
return rv;
}
public static boolean isGeneratable(SModel model) {
SNode node = SModelOperations.getModuleStub(model);
if (SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getConcept(0x86ef829012bb4ca7L, 0x947f093788f263a9L, 0x5869770da61dfe21L, "jetbrains.mps.lang.project.structure.Generator"))) {
return SPropertyOperations.getBoolean(SNodeOperations.cast(node, MetaAdapterFactory.getConcept(0x86ef829012bb4ca7L, 0x947f093788f263a9L, 0x5869770da61dfe21L, "jetbrains.mps.lang.project.structure.Generator")), MetaAdapterFactory.getProperty(0x86ef829012bb4ca7L, 0x947f093788f263a9L, 0x5869770da61dfe21L, 0x29a5716c5dfed280L, "generateTemplates"));
}
return false;
}
public static String asIdentifier(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c) && sb.length() > 0) {
sb.append(c);
} else if (Character.isJavaIdentifierStart(c) && c != '$') {
sb.append(c);
} else {
// replace all non-identifier characters with underscore
// I realize that may lead to name clashes, but odds are too low and do not justify e.g. _x0020 in the name with spaces
sb.append('_');
}
}
return sb.toString();
}
/**
* Record the fact template model node has incoming references from the same model (use it as a hint whether anyone can try
* to resolve output using this template node as identity)
*/
public static void markHasIncomingRefs(SNode n) {
// just care about the fact there are references, not their number nor nature
n.putUserObject("hasIncomingRefs", Boolean.TRUE);
}
/**
* Tells if there were recorded incoming references to the given node (from the same template model only)
*/
public static boolean hasIncomingRefs(SNode n) {
return n.getUserObject("hasIncomingRefs") == Boolean.TRUE;
}
}