(f *FlowState, flow *ast.FlowNode)
| 1381 | } |
| 1382 | |
| 1383 | func (c *Checker) getTypeAtFlowArrayMutation(f *FlowState, flow *ast.FlowNode) FlowType { |
| 1384 | if f.declaredType == c.autoType || f.declaredType == c.autoArrayType { |
| 1385 | node := flow.Node |
| 1386 | var expr *ast.Node |
| 1387 | if ast.IsCallExpression(node) { |
| 1388 | expr = node.Expression().Expression() |
| 1389 | } else { |
| 1390 | expr = node.AsBinaryExpression().Left.Expression() |
| 1391 | } |
| 1392 | if c.isMatchingReference(f.reference, c.getReferenceCandidate(expr)) { |
| 1393 | flowType := c.getTypeAtFlowNode(f, flow.Antecedent) |
| 1394 | if flowType.t.objectFlags&ObjectFlagsEvolvingArray != 0 { |
| 1395 | evolvedType := flowType.t |
| 1396 | if ast.IsCallExpression(node) { |
| 1397 | for _, arg := range node.Arguments() { |
| 1398 | evolvedType = c.addEvolvingArrayElementType(evolvedType, arg) |
| 1399 | } |
| 1400 | } else { |
| 1401 | // We must get the context free expression type so as to not recur in an uncached fashion on the LHS (which causes exponential blowup in compile time) |
| 1402 | indexType := c.getContextFreeTypeOfExpression(node.AsBinaryExpression().Left.AsElementAccessExpression().ArgumentExpression) |
| 1403 | if c.isTypeAssignableToKind(indexType, TypeFlagsNumberLike) { |
| 1404 | evolvedType = c.addEvolvingArrayElementType(evolvedType, node.AsBinaryExpression().Right) |
| 1405 | } |
| 1406 | } |
| 1407 | return c.newFlowType(evolvedType, flowType.incomplete) |
| 1408 | } |
| 1409 | return flowType |
| 1410 | } |
| 1411 | } |
| 1412 | return FlowType{} |
| 1413 | } |
| 1414 | |
| 1415 | func (c *Checker) getDiscriminantPropertyAccess(f *FlowState, expr *ast.Node, computedType *Type) *ast.Node { |
| 1416 | // As long as the computed type is a subset of the declared type, we use the full declared type to detect |
no test coverage detected