package jetbrains.mps.baseLanguage.closures.behavior;
/*Generated by MPS */
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import java.util.ArrayList;
import jetbrains.mps.lang.pattern.util.MatchingUtil;
public class ControlMethodUtil {
public ControlMethodUtil() {
}
public static boolean isControlMethod(SNode smd) {
return ControlMethodUtil.analyze(smd) != null;
}
public static ControlMethodUtil.Info analyze(SNode smd) {
if (SNodeOperations.isInstanceOf(SLinkOperations.getTarget(smd, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1fdL, "returnType")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc6bf96dL, "jetbrains.mps.baseLanguage.structure.VoidType"))) {
List<SNode> params = SLinkOperations.getChildren(smd, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1feL, "parameter"));
// 0..k-1 : control function parameters, k..l-1 : control closure parameter declarations (closures), l..m-1 : control closures
ControlMethodUtil.Info inf = new ControlMethodUtil.Info();
int functionParams = 0;
int initClosures = 0;
int controlClosures = 0;
List<SNode> closureParamTypes = null;
for (int idx = ListSequence.fromList(params).count() - 1; idx >= 0; idx--) {
SNode p = ListSequence.fromList(params).getElement(idx);
SNode ptype = SLinkOperations.getTarget(p, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x450368d90ce15bc3L, 0x4ed4d318133c80ceL, "type"));
if (SNodeOperations.isInstanceOf(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType"))) {
if (functionParams > 0) {
return null;
}
if (SConceptOperations.isExactly(SNodeOperations.asSConcept(SNodeOperations.getConcept(ptype)), MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x11e505b9d83L, "jetbrains.mps.baseLanguage.closures.structure.UnrestrictedFunctionType")) && SNodeOperations.isInstanceOf(SLinkOperations.getTarget(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4d5371L, "resultType")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc6bf96dL, "jetbrains.mps.baseLanguage.structure.VoidType"))) {
if (initClosures > 0) {
return null;
}
controlClosures++;
inf.addControlClosureType(SNodeOperations.copyNode(ptype));
if (closureParamTypes == null) {
closureParamTypes = ListSequence.fromList(new ArrayList<SNode>());
for (SNode pt : SLinkOperations.getChildren(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4e013cL, "parameterType"))) {
ListSequence.fromList(closureParamTypes).addElement(SNodeOperations.copyNode(pt));
}
} else if (closureParamTypes != null && ListSequence.fromList(closureParamTypes).count() == ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4e013cL, "parameterType"))).count()) {
int i = 0;
for (SNode pt : SLinkOperations.getChildren(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4e013cL, "parameterType"))) {
if (!(MatchingUtil.matchNodes(pt, ListSequence.fromList(closureParamTypes).getElement(i++)))) {
return null;
}
}
} else {
return null;
}
} else if (ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4e013cL, "parameterType"))).isEmpty() && !(SNodeOperations.isInstanceOf(SLinkOperations.getTarget(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, "jetbrains.mps.baseLanguage.closures.structure.FunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4d5371L, "resultType")), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc6bf96dL, "jetbrains.mps.baseLanguage.structure.VoidType")))) {
if (controlClosures == 0 || initClosures >= ListSequence.fromList(closureParamTypes).count()) {
return null;
}
initClosures++;
inf.addInitClosureType(SNodeOperations.copyNode(ptype));
SNode rt = SLinkOperations.getTarget(SNodeOperations.cast(ptype, MetaAdapterFactory.getConcept(0xfd3920347849419dL, 0x907112563d152375L, 0x11e505b9d83L, "jetbrains.mps.baseLanguage.closures.structure.UnrestrictedFunctionType")), MetaAdapterFactory.getContainmentLink(0xfd3920347849419dL, 0x907112563d152375L, 0x1174a4d19ffL, 0x1174a4d5371L, "resultType"));
if (!(MatchingUtil.matchNodes(rt, ListSequence.fromList(closureParamTypes).getElement(ListSequence.fromList(closureParamTypes).count() - initClosures)))) {
return null;
}
} else {
return null;
}
} else if (controlClosures > 0) {
functionParams++;
inf.addFunctionParameterType(SNodeOperations.copyNode(ptype));
} else {
return null;
}
}
return (inf.isInitialized() ? inf : null);
}
return null;
}
public static class Info {
private List<SNode> controlClosures;
private List<SNode> initClosures;
private List<SNode> functionParams;
private boolean initialized = false;
public Info() {
}
public boolean isInitialized() {
return this.initialized;
}
public void addControlClosureType(SNode cct) {
this.init();
ListSequence.fromList(this.controlClosures).addElement(cct);
}
public void addInitClosureType(SNode ict) {
this.init();
ListSequence.fromList(this.initClosures).addElement(ict);
}
public void addFunctionParameterType(SNode fpt) {
this.init();
ListSequence.fromList(this.functionParams).addElement(fpt);
}
public List<SNode> getControlClosureTypes() {
return this.ensureNotNull(this.controlClosures);
}
public List<SNode> getInitClosureTypes() {
return this.ensureNotNull(this.initClosures);
}
public List<SNode> getFunctionParamTypes() {
return this.ensureNotNull(this.functionParams);
}
public List<SNode> ensureNotNull(List<SNode> list) {
if (list == null) {
return ListSequence.fromList(new ArrayList<SNode>());
}
return list;
}
private void init() {
if (!(this.initialized)) {
this.controlClosures = ListSequence.fromList(new ArrayList<SNode>());
this.initClosures = ListSequence.fromList(new ArrayList<SNode>());
this.functionParams = ListSequence.fromList(new ArrayList<SNode>());
this.initialized = true;
}
}
}
}