Пример #1
0
        private static Package CheckSemantics(PackageSyntax packageSyntax)
        {
            DeclarationNumberAssigner.AssignIn(packageSyntax.AllEntityDeclarations);

            // Resolve symbols for the entities
            EntitySymbolBuilder.BuildFor(packageSyntax);

            var stringSymbol = packageSyntax.SymbolTrees
                               .GlobalSymbols
                               .OfType <ObjectTypeSymbol>()
                               .SingleOrDefault(s => s.Name == "String");

            // Basic Analysis includes: Name Binding, Type Checking, Constant Folding
            BasicAnalyzer.Check(packageSyntax, stringSymbol);

            // If there are errors from the basic analysis phase, don't continue on
            packageSyntax.Diagnostics.ThrowIfFatalErrors();

#if DEBUG
            new SymbolValidator(packageSyntax.SymbolTree).Validate(packageSyntax.AllEntityDeclarations);
            new TypeFulfillmentValidator().Validate(packageSyntax.AllEntityDeclarations);
            new TypeKnownValidator().Validate(packageSyntax.AllEntityDeclarations);
            new ExpressionSemanticsValidator().Validate(packageSyntax.AllEntityDeclarations);
#endif

            var package = new ASTBuilder().BuildPackage(packageSyntax);

            // From this point forward, analysis focuses on executable declarations (i.e. invocables and field initializers)
            var executableDeclarations = package.AllDeclarations.OfType <IExecutableDeclaration>().ToFixedSet();

            ShadowChecker.Check(executableDeclarations, package.Diagnostics);

            DataFlowAnalysis.Check(DefiniteAssignmentAnalyzer.Instance, executableDeclarations, package.SymbolTree, package.Diagnostics);

            DataFlowAnalysis.Check(BindingMutabilityAnalyzer.Instance, executableDeclarations, package.SymbolTree, package.Diagnostics);

            DataFlowAnalysis.Check(UseOfMovedValueAnalyzer.Instance, executableDeclarations, package.SymbolTree, package.Diagnostics);

            // TODO use DataFlowAnalysis to check for unused variables and report use of variables starting with `_`

            // Compute variable liveness needed by reachability analyzer
            DataFlowAnalysis.Check(LivenessAnalyzer.Instance, executableDeclarations, package.SymbolTree, package.Diagnostics);

            ReachabilityAnalyzer.Analyze(executableDeclarations, package.SymbolTree, package.Diagnostics);

            // TODO remove live variables if SaveLivenessAnalysis is false

            return(package);
        }