package jetbrains.mps.baseLanguage.typesystem;
/*Generated by MPS */
import jetbrains.mps.lang.typesystem.runtime.AbstractNonTypesystemRule_Runtime;
import jetbrains.mps.lang.typesystem.runtime.NonTypesystemRule_Runtime;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.typesystem.inference.TypeCheckingContext;
import jetbrains.mps.lang.typesystem.runtime.IsApplicableStatus;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.generator.TransientModelsModule;
import jetbrains.mps.analyzers.runtime.framework.CustomAnalyzerRunner;
import java.util.Map;
import jetbrains.mps.baseLanguage.dataFlow.NullableState;
import jetbrains.mps.baseLanguage.dataFlow.NullableAnalyzerRunner;
import jetbrains.mps.lang.dataFlow.framework.AnalysisResult;
import jetbrains.mps.lang.dataFlow.framework.Program;
import jetbrains.mps.lang.dataFlow.framework.instructions.Instruction;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.baseLanguage.tuples.runtime.Tuples;
import jetbrains.mps.lang.dataFlow.framework.instructions.IfJumpInstruction;
import jetbrains.mps.baseLanguage.dataFlow.NullableUtil;
import jetbrains.mps.errors.messageTargets.MessageTarget;
import jetbrains.mps.errors.messageTargets.NodeMessageTarget;
import jetbrains.mps.errors.IErrorReporter;
import jetbrains.mps.lang.dataFlow.framework.instructions.WriteInstruction;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.baseLanguage.behavior.IMethodLike__BehaviorDescriptor;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
public class check_NullableStates_NonTypesystemRule extends AbstractNonTypesystemRule_Runtime implements NonTypesystemRule_Runtime {
public check_NullableStates_NonTypesystemRule() {
}
public void applyRule(final SNode iMethodLike, final TypeCheckingContext typeCheckingContext, IsApplicableStatus status) {
if (SNodeOperations.getModel(iMethodLike).getModule() instanceof TransientModelsModule) {
return;
}
// Find possible NPE
CustomAnalyzerRunner<Map<SNode, NullableState>> nullableRunner = new NullableAnalyzerRunner(iMethodLike);
AnalysisResult<Map<SNode, NullableState>> result = nullableRunner.analyze();
Program program = nullableRunner.getProgram();
if (DataFlowUtil.tooComplex(program)) {
return;
}
for (Instruction instruction : program.getInstructions()) {
SNode source = (SNode) instruction.getSource();
SNode variable = source;
if (SNodeOperations.isInstanceOf(source, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference"))) {
variable = SLinkOperations.getTarget(SNodeOperations.cast(source, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, "jetbrains.mps.baseLanguage.structure.VariableReference")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e98L, 0xf8cc6bf960L, "variableDeclaration"));
}
NullableState varState = result.get(instruction).get(variable);
SNode parent = SNodeOperations.getParent(source);
Tuples._2<String, SNode> checkingResult;
String warning;
SNode nodeToWarn;
if (!(instruction instanceof IfJumpInstruction)) {
checkingResult = NullableUtil.isNullableDotExpression(parent, source, varState);
if (checkingResult != null) {
warning = checkingResult._0();
nodeToWarn = checkingResult._1();
{
MessageTarget errorTarget = new NodeMessageTarget();
IErrorReporter _reporter_2309309498 = typeCheckingContext.reportWarning(nodeToWarn, warning, "r:00000000-0000-4000-0000-011c895902c5(jetbrains.mps.baseLanguage.typesystem)", "3451033204592343684", null, errorTarget);
}
}
}
checkingResult = NullableUtil.isNullableMethodCall(parent, source, varState);
if (checkingResult != null) {
warning = checkingResult._0();
nodeToWarn = checkingResult._1();
{
MessageTarget errorTarget = new NodeMessageTarget();
IErrorReporter _reporter_2309309498 = typeCheckingContext.reportWarning(nodeToWarn, warning, "r:00000000-0000-4000-0000-011c895902c5(jetbrains.mps.baseLanguage.typesystem)", "4235809288654203516", null, errorTarget);
}
continue;
}
// Test equals and not equals is always true or false
checkingResult = NullableUtil.isAlwaysTrueOrFalse(instruction, parent, source, varState);
if (checkingResult != null) {
warning = checkingResult._0();
nodeToWarn = checkingResult._1();
{
MessageTarget errorTarget = new NodeMessageTarget();
IErrorReporter _reporter_2309309498 = typeCheckingContext.reportWarning(nodeToWarn, warning, "r:00000000-0000-4000-0000-011c895902c5(jetbrains.mps.baseLanguage.typesystem)", "4235809288654205433", null, errorTarget);
}
continue;
}
// Find Nullable assignements to NotNull variables
if (instruction instanceof WriteInstruction) {
checkingResult = NullableUtil.checkNullableAssignment(((WriteInstruction) instruction), result);
if (checkingResult != null) {
warning = checkingResult._0();
nodeToWarn = checkingResult._1();
{
MessageTarget errorTarget = new NodeMessageTarget();
IErrorReporter _reporter_2309309498 = typeCheckingContext.reportWarning(nodeToWarn, warning, "r:00000000-0000-4000-0000-011c895902c5(jetbrains.mps.baseLanguage.typesystem)", "4235809288654207287", null, errorTarget);
}
continue;
}
}
}
// Find Nullable returns of NotNull methods
if (SNodeOperations.isInstanceOf(iMethodLike, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, "jetbrains.mps.baseLanguage.structure.BaseMethodDeclaration"))) {
SNode method = SNodeOperations.cast(iMethodLike, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, "jetbrains.mps.baseLanguage.structure.BaseMethodDeclaration"));
if (Sequence.fromIterable(SLinkOperations.collect(SLinkOperations.getChildren(method, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x114a6be947aL, 0x114a6beb0bdL, "annotation")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x114a6b4ccabL, 0x114a6b85d40L, "annotation"))).contains(SNodeOperations.getNode("3f233e7f-b8a6-46d2-a57f-795d56775243/java:org.jetbrains.annotations(Annotations/)", "~NotNull"))) {
for (SNode returnStatement : RulesFunctions_BaseLanguage.collectReturnStatements(SLinkOperations.getTarget(method, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b1fcL, 0xf8cc56b1ffL, "body")))) {
RulesFunctions_BaseLanguage.checkReturningExpression(typeCheckingContext, SLinkOperations.getTarget(returnStatement, MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc67c7feL, 0xf8cc6bf96cL, "expression")), returnStatement, program, result);
}
SNode last = IMethodLike__BehaviorDescriptor.getLastStatement_idi2fhS7A.invoke(method);
if (SNodeOperations.isInstanceOf(last, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b213L, "jetbrains.mps.baseLanguage.structure.ExpressionStatement"))) {
RulesFunctions_BaseLanguage.checkReturningExpression(typeCheckingContext, SLinkOperations.getTarget(SNodeOperations.cast(last, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b213L, "jetbrains.mps.baseLanguage.structure.ExpressionStatement")), MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8cc56b213L, 0xf8cc56b214L, "expression")), last, program, result);
}
}
}
}
public SAbstractConcept getApplicableConcept() {
return MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1208f458d37L, "jetbrains.mps.baseLanguage.structure.IMethodLike");
}
public IsApplicableStatus isApplicableAndPattern(SNode argument) {
return new IsApplicableStatus(argument.getConcept().isSubConceptOf(getApplicableConcept()), null);
}
public boolean overrides() {
return false;
}
}