(reference *ast.Node, declaredType *Type, initialType *Type, flowContainer *ast.Node, flowNode *ast.FlowNode)
| 79 | } |
| 80 | |
| 81 | func (c *Checker) getFlowTypeOfReferenceEx(reference *ast.Node, declaredType *Type, initialType *Type, flowContainer *ast.Node, flowNode *ast.FlowNode) *Type { |
| 82 | if c.flowAnalysisDisabled { |
| 83 | return c.errorType |
| 84 | } |
| 85 | if flowNode == nil { |
| 86 | flowNode = getFlowNodeOfNode(reference) |
| 87 | if flowNode == nil { |
| 88 | return declaredType |
| 89 | } |
| 90 | } |
| 91 | f := c.getFlowState() |
| 92 | f.reference = reference |
| 93 | f.declaredType = declaredType |
| 94 | f.initialType = core.Coalesce(initialType, declaredType) |
| 95 | f.flowContainer = flowContainer |
| 96 | f.sharedFlowStart = len(c.sharedFlows) |
| 97 | c.flowInvocationCount++ |
| 98 | evolvedType := c.getTypeAtFlowNode(f, flowNode).t |
| 99 | c.sharedFlows = c.sharedFlows[:f.sharedFlowStart] |
| 100 | c.putFlowState(f) |
| 101 | // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation, |
| 102 | // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations |
| 103 | // on empty arrays are possible without implicit any errors and new element types can be inferred without |
| 104 | // type mismatch errors. |
| 105 | var resultType *Type |
| 106 | if evolvedType.objectFlags&ObjectFlagsEvolvingArray != 0 && c.isEvolvingArrayOperationTarget(reference) { |
| 107 | resultType = c.autoArrayType |
| 108 | } else { |
| 109 | resultType = c.finalizeEvolvingArrayType(evolvedType) |
| 110 | } |
| 111 | if resultType == c.unreachableNeverType || reference.Parent != nil && ast.IsNonNullExpression(reference.Parent) && resultType.flags&TypeFlagsNever == 0 && c.getTypeWithFacts(resultType, TypeFactsNEUndefinedOrNull).flags&TypeFlagsNever != 0 { |
| 112 | return declaredType |
| 113 | } |
| 114 | return resultType |
| 115 | } |
| 116 | |
| 117 | func (c *Checker) getTypeAtFlowNode(f *FlowState, flow *ast.FlowNode) FlowType { |
| 118 | if f.depth == 2000 { |
no test coverage detected