(trigger annotation.FullTrigger)
| 336 | } |
| 337 | |
| 338 | func (e *Engine) buildFromSingleFullTrigger(trigger annotation.FullTrigger) { |
| 339 | pKind, cKind := trigger.Producer.Annotation.Kind(), trigger.Consumer.Annotation.Kind() |
| 340 | pSite, cSite := trigger.Producer.Annotation.UnderlyingSite(), trigger.Consumer.Annotation.UnderlyingSite() |
| 341 | // NilAway does not know that (kind == Conditional || DeepConditional) => (site != nil), |
| 342 | // so we have to add some redundant checks in the corresponding cases to give some hints. |
| 343 | // TODO: remove those redundant nilness checks for sites. |
| 344 | switch { |
| 345 | case pKind == annotation.Always && cKind == annotation.Always: |
| 346 | // Producer always produces nilable value -> consumer always consumes nonnil value. |
| 347 | // We simply generate a failure for this case. |
| 348 | e.diagnosticEngine.AddSingleAssertionConflict(trigger) |
| 349 | |
| 350 | case pKind == annotation.Always && (cKind == annotation.Conditional || cKind == annotation.DeepConditional): |
| 351 | // Producer always produces nilable value -> consumer unknown. |
| 352 | // We propagate nilable to this consumer site. |
| 353 | if cSite == nil { |
| 354 | panic("trigger is conditional but the underlying site is nil") |
| 355 | } |
| 356 | site := e.primitive.site(cSite, cKind == annotation.DeepConditional) |
| 357 | e.observeSiteExplanation(site, TrueBecauseShallowConstraint{ |
| 358 | ExternalAssertion: e.primitive.fullTrigger(trigger), |
| 359 | }) |
| 360 | |
| 361 | case (pKind == annotation.Conditional || pKind == annotation.DeepConditional) && (cKind == annotation.Always): |
| 362 | // Producer unknown -> consumer always consumes nonnil value. |
| 363 | // We propagate nonnil to the producer site. |
| 364 | if pSite == nil { |
| 365 | panic("trigger is conditional but the underlying site is nil") |
| 366 | } |
| 367 | site := e.primitive.site(pSite, pKind == annotation.DeepConditional) |
| 368 | e.observeSiteExplanation(site, FalseBecauseShallowConstraint{ |
| 369 | ExternalAssertion: e.primitive.fullTrigger(trigger), |
| 370 | }) |
| 371 | |
| 372 | case (pKind == annotation.Conditional || pKind == annotation.DeepConditional) && |
| 373 | (cKind == annotation.Conditional || cKind == annotation.DeepConditional): |
| 374 | // Producer unknown -> consumer unknown. |
| 375 | // We store this implication in our map as UndeterminedBool. |
| 376 | if pSite == nil || cSite == nil { |
| 377 | panic("trigger is conditional but the underlying site is nil") |
| 378 | } |
| 379 | producer := e.primitive.site(pSite, pKind == annotation.DeepConditional) |
| 380 | consumer := e.primitive.site(cSite, cKind == annotation.DeepConditional) |
| 381 | |
| 382 | e.observeImplication(producer, consumer, e.primitive.fullTrigger(trigger)) |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | // observeSiteExplanation augments inferred map with a definite value for the passed |
| 387 | // site `site` - the definite value being given as the ExplainedBool `siteExplained`. Any conflicts |
no test coverage detected