package jetbrains.mps.lang.dataFlow;
/*Generated by MPS */
import jetbrains.mps.lang.dataFlow.framework.StructuralProgramBuilder;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.module.SRepository;
import jetbrains.mps.lang.dataFlow.framework.instructions.InstructionBuilder;
import jetbrains.mps.lang.dataFlow.framework.ProgramBuilderContext;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.dataFlow.framework.IDataFlowBuilder;
import jetbrains.mps.lang.dataFlow.framework.instructions.Instruction;
import jetbrains.mps.lang.dataFlow.framework.instructions.EndTryInstruction;
import jetbrains.mps.smodel.language.LanguageRegistry;
import jetbrains.mps.smodel.language.LanguageRuntime;
import jetbrains.mps.lang.dataFlow.framework.DataFlowAspectDescriptor;
import jetbrains.mps.lang.dataFlow.framework.DataFlowAspectDescriptorBase;
import java.util.Collection;
import jetbrains.mps.lang.dataFlow.framework.IDataFlowModeId;
import jetbrains.mps.internal.collections.runtime.CollectionSequence;
public class MPSProgramBuilder extends StructuralProgramBuilder<SNode> {
private DataFlowManager myDataFlowManager;
private boolean myMayBeUnreachable = false;
private SRepository myRepository;
public MPSProgramBuilder() {
// todo remove after 3.4
this.myDataFlowManager = DataFlowManager.getInstance();
}
public MPSProgramBuilder(InstructionBuilder builder) {
super(builder);
// todo remove after 3.4
this.myDataFlowManager = DataFlowManager.getInstance();
}
public MPSProgramBuilder(SRepository repository) {
this.myRepository = repository;
// todo remove after 3.4
this.myDataFlowManager = DataFlowManager.getInstance();
}
public MPSProgramBuilder(SRepository repository, InstructionBuilder builder) {
super(builder);
this.myRepository = repository;
// todo remove after 3.4
this.myDataFlowManager = DataFlowManager.getInstance();
}
public MPSProgramBuilder(SRepository repository, InstructionBuilder builder, ProgramBuilderContext context) {
super(builder, context);
this.myRepository = repository;
// todo remove after 3.4
this.myDataFlowManager = DataFlowManager.getInstance();
}
/**
*
* @deprecated
*/
@Deprecated
public MPSProgramBuilder(DataFlowManager dataFlowManager) {
this.myDataFlowManager = dataFlowManager;
}
protected DataFlowBuilderContext createContext(SNode node) {
return new DataFlowBuilderContext(node, this);
}
@Override
protected void doBuild(SNode node) {
if (node == null) {
return;
}
SNode snode = node;
for (SAbstractConcept concept : SConceptOperations.getAllSuperConcepts(SNodeOperations.getConcept(snode), true)) {
IDataFlowBuilder dataFlowBuilder = getDataFlowBuilder(concept);
if (dataFlowBuilder != null) {
dataFlowBuilder.build(createContext(snode));
break;
}
// todo to remove after 3.4
if (myDataFlowManager != null) {
DataFlowBuilder oldBuilder = this.myDataFlowManager.getBuilderFor(concept.getQualifiedName());
if (oldBuilder != null) {
oldBuilder.build(createContext(snode));
break;
}
}
}
}
public void emitMayBeUnreachable(Runnable r) {
boolean oldMayBeUnreachable = this.myMayBeUnreachable;
this.myMayBeUnreachable = true;
try {
r.run();
} finally {
this.myMayBeUnreachable = oldMayBeUnreachable;
}
}
@Override
protected void onInstructionEmitted(Instruction instruction) {
super.onInstructionEmitted(instruction);
if (this.myMayBeUnreachable || instruction instanceof EndTryInstruction) {
instruction.putUserObject(DataFlow.MAY_BE_UNREACHABLE, true);
}
}
private IDataFlowBuilder getDataFlowBuilder(SAbstractConcept concept) {
LanguageRegistry instance = (myRepository != null ? LanguageRegistry.getInstance(myRepository) : LanguageRegistry.getInstance());
LanguageRuntime language = instance.getLanguage(concept.getLanguage());
if (language != null) {
DataFlowAspectDescriptor aspect = language.getAspect(DataFlowAspectDescriptor.class);
if (aspect instanceof DataFlowAspectDescriptorBase) {
Collection<IDataFlowBuilder> dataFlowBuilders = ((DataFlowAspectDescriptorBase) aspect).getDataFlowBuilders(concept);
Collection<IDataFlowModeId> contextModes = getBuilderContext().getBuilderModes();
for (IDataFlowModeId contextMode : CollectionSequence.fromCollection(contextModes)) {
for (IDataFlowBuilder builder : CollectionSequence.fromCollection(dataFlowBuilders)) {
if (builder.getModes().contains(contextMode)) {
return builder;
}
}
}
for (IDataFlowBuilder builder : CollectionSequence.fromCollection(dataFlowBuilders)) {
if (builder.getModes().isEmpty()) {
return builder;
}
}
return null;
}
}
return null;
}
}