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));
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
Beispiel #9
0
        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;
            }
        }