protected override void VisitReference(ReferenceNode referenceNode) { NestableSymbol nestableSymbol = referenceNode.Symbol as NestableSymbol; switch (nestableSymbol?.Node) { case ConstDefinitionNode _: case ParameterDeclarationNode _: break; case VarDeclarationNode _: if (_currentBlockSymbol == null) { throw new Exception(); } NestableSymbol baseSymbol = referenceNode.BaseSymbol as NestableSymbol; if (baseSymbol == null) { break; } ReferenceData referenceData = GetDataFromReferenceNode(referenceNode); if (referenceData == null) { break; } if (_currentBlockSymbol is SubclassSymbol currentSubclassSymbol) { if (baseSymbol.ParentBlockSymbol == currentSubclassSymbol.BaseClassSymbol) { HashSet <string> initializedAttributesPaths = GetInitializedAttributesPaths((SubclassNode)_currentBlockSymbol.Node); if (!initializedAttributesPaths.Contains(referenceData.PreDotPath)) { referenceNode.Annotations.Add(new UsageOfNonInitializedVariableWarning( referenceData.BaseName, referenceData.Index, true)); } break; } } if (nestableSymbol.ParentBlockSymbol == _currentBlockSymbol) { if (!_initializedLocalsPaths.Contains(referenceData.PreDotPath)) { referenceNode.Annotations.Add(new UsageOfNonInitializedVariableWarning( referenceData.BaseName, referenceData.Index, false)); } } break; } base.VisitReference(referenceNode); }
protected override void VisitAssignment(AssignmentNode node) { ReferenceNode referenceNode = node.LeftSideNode; if (referenceNode.Symbol is InstanceSymbol) { // instances as of now aren't of type NestableSymbol, they can appear tough // however they are always initialized when they are created return; } Visit(node.RightSideNode); NestableSymbol nestableSymbol = (NestableSymbol)referenceNode.Symbol; switch (nestableSymbol?.Node) { case ConstDefinitionNode _: case ParameterDeclarationNode _: break; case VarDeclarationNode _: if (_currentBlockSymbol == null) { throw new Exception(); } NestableSymbol baseSymbol = referenceNode.BaseSymbol as NestableSymbol; if (baseSymbol == null) { break; } ReferenceData referenceData = GetDataFromReferenceNode(referenceNode); if (referenceData == null || referenceData.HasDotInPath) { break; } string relativePath = referenceData.PreDotPath; if (_currentBlockSymbol is SubclassSymbol currentSubclassSymbol) { if (baseSymbol.ParentBlockSymbol == currentSubclassSymbol.BaseClassSymbol) { _initializedAttributesPaths.Add(relativePath); break; } } if (nestableSymbol.ParentBlockSymbol == _currentBlockSymbol) { _initializedLocalsPaths.Add(relativePath); } break; } Visit(node.LeftSideNode); }