protected void WalkChildrenInReverse(IAbstractSyntax syntax, T arg) { foreach (var child in syntax.Children().Reverse()) { WalkNonNull(child, arg); } }
private protected HeapPlace( IReferenceGraph graph, IAbstractSyntax originSyntax, IReference?originOfMutability) : base(graph) { OriginSyntax = originSyntax; OriginOfMutability = originOfMutability; }
protected override void WalkNonNull(IAbstractSyntax syntax, BindingScope bindingScope) { switch (syntax) { case IConcreteInvocableDeclaration syn: foreach (var parameter in syn.Parameters.OfType <INamedParameter>()) { bindingScope = new VariableBindingScope(bindingScope, parameter); } break; case IFieldDeclaration syn: WalkChildren(syn, bindingScope); break; case IBodyOrBlock syn: foreach (var statement in syn.Statements) { WalkNonNull(statement, bindingScope); // Each variable declaration establishes a new binding scope if (statement is IVariableDeclarationStatement variableDeclaration) { bindingScope = new VariableBindingScope(bindingScope, variableDeclaration); } } return; case IVariableDeclarationStatement syn: { WalkChildren(syn, bindingScope); if (!bindingScope.Lookup(syn.Symbol.Name, out var binding)) { return; } if (binding.MutableBinding) { diagnostics.Add(SemanticError.CantRebindMutableBinding(file, syn.NameSpan)); } else if (syn.Symbol.IsMutableBinding) { diagnostics.Add(SemanticError.CantRebindAsMutableBinding(file, syn.NameSpan)); } return; } case INameExpression syn: { // This checks for cases where a variable was shadowed, but then used later if (!bindingScope.Lookup(syn.ReferencedSymbol.Name, out var binding)) { return; } if (binding.WasShadowedBy.Any()) { diagnostics.Add(SemanticError.CantShadow(file, binding.WasShadowedBy[^ 1].NameSpan, syn.Span));
protected override void WalkNonNull(IAbstractSyntax syntax, bool isLValue) { // TODO this doesn't handle loops correctly switch (syntax) { case IReachabilityAnnotationSyntax _: // Ignore for now return; case IConcreteInvocableDeclaration exp: checker = strategy.BeginAnalysis(exp, symbolTree, diagnostics); currentState = checker.StartState(); break; case IFieldDeclaration exp: checker = strategy.BeginAnalysis(exp, symbolTree, diagnostics); currentState = checker.StartState(); break; case IAssignmentExpression exp: WalkNonNull(exp.LeftOperand, true); WalkNonNull(exp.RightOperand, false); currentState = checker !.Assignment(exp, currentState !); return; case INameExpression exp: if (isLValue) { return; // ignore } currentState = checker !.IdentifierName(exp, currentState !); return; case IVariableDeclarationStatement exp: WalkChildren(exp, false); currentState = checker !.VariableDeclaration(exp, currentState !); return; case IForeachExpression exp: WalkNonNull(exp.InExpression, isLValue); currentState = checker !.VariableDeclaration(exp, currentState !); WalkNonNull(exp.Block, isLValue); return; case IFieldAccessExpression exp: WalkNonNull(exp.Context, isLValue); // Don't walk the field name, it shouldn't be treated as a variable return; case IDeclaration _: throw new InvalidOperationException($"Analyze data flow of declaration of type {syntax.GetType().Name}"); } WalkChildren(syntax, false); }
public Reference AddNewObject( Ownership ownership, Access declaredAccess, IAbstractSyntax syntax, bool isContext, bool isOriginOfMutability) { var reference = Reference.ToNewObject(this, ownership, declaredAccess, syntax, isContext, isOriginOfMutability); var referent = reference.Referent; objects.Add(referent.OriginSyntax, referent); Dirty(); return(reference); }
internal static Reference ToNewObject( IReferenceGraph graph, Ownership ownership, Access declaredAccess, IAbstractSyntax syntax, bool isContext, bool isOriginOfMutability) { var reference = new Reference(ownership, declaredAccess); var originOfMutability = isOriginOfMutability ? reference : null; reference.Referent = new Object(graph, isContext, syntax, originOfMutability); return(reference); }
internal Object(IReferenceGraph graph, bool isContext, IAbstractSyntax syntax, Reference?originOfMutability) : base(graph, syntax, originOfMutability) { IsContext = isContext; }
protected abstract void WalkNonNull(IAbstractSyntax syntax, T arg);
public static IEnumerable <IAbstractSyntax> Children(this IAbstractSyntax node) { switch (node) { default: throw ExhaustiveMatch.Failed(node); case IClassDeclaration n: foreach (var child in n.Members) { yield return(child); } yield break; case IFunctionDeclaration n: foreach (var child in n.Parameters) { yield return(child); } yield return(n.ReachabilityAnnotations); yield return(n.Body); yield break; case IAbstractMethodDeclaration n: yield return(n.SelfParameter); foreach (var child in n.Parameters) { yield return(child); } yield return(n.ReachabilityAnnotations); yield break; case IConcreteMethodDeclaration n: yield return(n.SelfParameter); foreach (var child in n.Parameters) { yield return(child); } yield return(n.ReachabilityAnnotations); yield return(n.Body); yield break; case IConstructorDeclaration n: yield return(n.ImplicitSelfParameter); foreach (var child in n.Parameters) { yield return(child); } yield return(n.ReachabilityAnnotations); yield return(n.Body); yield break; case IFieldDeclaration n: yield break; case IAssociatedFunctionDeclaration n: foreach (var child in n.Parameters) { yield return(child); } yield return(n.ReachabilityAnnotations); yield return(n.Body); yield break; case INamedParameter n: if (!(n.DefaultValue is null)) { yield return(n.DefaultValue); } yield break; case ISelfParameter n: yield break; case IFieldParameter n: if (!(n.DefaultValue is null)) { yield return(n.DefaultValue); } yield break; case IReachabilityAnnotations n: if (!(n.ReachableFromAnnotation is null)) { yield return(n.ReachableFromAnnotation); } if (!(n.CanReachAnnotation is null)) { yield return(n.CanReachAnnotation); } yield break; case IReachableFromAnnotation n: foreach (var child in n.Parameters) { yield return(child); } yield break; case ICanReachAnnotation n: foreach (var child in n.Parameters) { yield return(child); } yield break; case INamedParameterName n: yield break; case ISelfParameterName n: yield break; case IBody n: foreach (var child in n.Statements) { yield return(child); } yield break; case IResultStatement n: yield return(n.Expression); yield break; case IVariableDeclarationStatement n: if (!(n.Initializer is null)) { yield return(n.Initializer); } yield break; case IExpressionStatement n: yield return(n.Expression); yield break; case IBlockExpression n: foreach (var child in n.Statements) { yield return(child); } yield break; case INewObjectExpression n: foreach (var child in n.Arguments) { yield return(child); } yield break; case IUnsafeExpression n: yield return(n.Expression); yield break; case IBoolLiteralExpression n: yield break; case IIntegerLiteralExpression n: yield break; case INoneLiteralExpression n: yield break; case IStringLiteralExpression n: yield break; case IAssignmentExpression n: yield return(n.LeftOperand); yield return(n.RightOperand); yield break; case IBinaryOperatorExpression n: yield return(n.LeftOperand); yield return(n.RightOperand); yield break; case IUnaryOperatorExpression n: yield return(n.Operand); yield break; case IIfExpression n: yield return(n.Condition); yield return(n.ThenBlock); if (!(n.ElseClause is null)) { yield return(n.ElseClause); } yield break; case ILoopExpression n: yield return(n.Block); yield break; case IWhileExpression n: yield return(n.Condition); yield return(n.Block); yield break; case IForeachExpression n: yield return(n.InExpression); yield return(n.Block); yield break; case IBreakExpression n: if (!(n.Value is null)) { yield return(n.Value); } yield break; case INextExpression n: yield break; case IReturnExpression n: if (!(n.Value is null)) { yield return(n.Value); } yield break; case IImplicitImmutabilityConversionExpression n: yield return(n.Expression); yield break; case IImplicitNoneConversionExpression n: yield return(n.Expression); yield break; case IImplicitNumericConversionExpression n: yield return(n.Expression); yield break; case IImplicitOptionalConversionExpression n: yield return(n.Expression); yield break; case IFunctionInvocationExpression n: foreach (var child in n.Arguments) { yield return(child); } yield break; case IMethodInvocationExpression n: yield return(n.Context); foreach (var child in n.Arguments) { yield return(child); } yield break; case INameExpression n: yield break; case ISelfExpression n: yield break; case IFieldAccessExpression n: yield return(n.Context); yield break; case IBorrowExpression n: yield return(n.Referent); yield break; case IMoveExpression n: yield return(n.Referent); yield break; case IShareExpression n: yield return(n.Referent); yield break; } }