Esempio n. 1
0
                public override void Visit(ExternalDeclarationNode node)
                {
                    foreach (var param in node.ParameterList.Parameters.Nodes)
                    {
                        var name = param.NameToken;

                        if (name.IsMissing)
                        {
                            continue;
                        }

                        var duplicate = false;

                        foreach (var param2 in node.ParameterList.Parameters.Nodes)
                        {
                            if (param2 != param && param2.NameToken.Text == name.Text)
                            {
                                duplicate = true;
                                break;
                            }
                        }

                        if (!duplicate)
                        {
                            continue;
                        }

                        Error(param, SyntaxDiagnosticKind.DuplicateParameter, name.Location,
                              $"Function parameter '{name}' (of '{node.NameToken}') declared multiple times");
                    }

                    base.Visit(node);
                }
Esempio n. 2
0
        public override IEnumerable <(SyntaxNode, SyntaxDiagnostic)> Run(NamedDeclarationNode node)
        {
            if (node.VisibilityKeywordToken?.Kind != SyntaxTokenKind.PubKeyword)
            {
                yield break;
            }

            var type = node switch
            {
                ConstantDeclarationNode _ => "constant",
                FunctionDeclarationNode _ => "function",
                ExternalDeclarationNode _ => "function",
                _ => throw DebugAssert.Unreachable(),
            };

            var ident = node.NameToken;

            if (ident.IsMissing)
            {
                yield break;
            }

            var diag = CheckDocAttribute(node.Attributes, ident.Location, $"Public {type} {ident} is undocumented");

            if (diag != null)
            {
                yield return(node, diag);
            }
        }
Esempio n. 3
0
        internal External(Module module, ExternalDeclarationNode node)
            : base(module, node)
        {
            var parms = ImmutableArray <Parameter> .Empty;
            var i     = 0;

            foreach (var param in node.ParameterList.Parameters.Nodes)
            {
                parms = parms.Add(new Parameter(this, param.Attributes, param.NameToken.Text, i,
                                                param.DotDotToken != null));

                i++;
            }

            Parameters = parms;
        }
Esempio n. 4
0
        internal Module(ModuleLoader loader, ModulePath path, ProgramNode node)
            : base(node.Attributes)
        {
            Loader = loader;
            Path   = path;

            var decls = ImmutableArray <Declaration> .Empty;

            foreach (var decl in node.Declarations)
            {
                if (decl is UseDeclarationNode)
                {
                    continue;
                }

                decls = decls.Add(decl switch
                {
                    ConstantDeclarationNode c => (Declaration) new Constant(this, c),
                    FunctionDeclarationNode f => new Function(this, f),
                    ExternalDeclarationNode e => new External(this, e),
                    TestDeclarationNode t => new Test(this, t),
                    _ => throw DebugAssert.Unreachable(),
                });
Esempio n. 5
0
                public override void Visit(ProgramNode node)
                {
                    _path = CreatePath(node.Path);

                    foreach (var decl in node.Declarations)
                    {
                        if (!(decl is UseDeclarationNode use))
                        {
                            continue;
                        }

                        var path = CreateCorrectPath(use.Path);

                        if (path == null)
                        {
                            continue;
                        }

                        if (use.Alias is UseDeclarationAliasNode alias && !alias.NameToken.IsMissing)
                        {
                            var name      = alias.NameToken;
                            var duplicate = false;

                            foreach (var decl2 in node.Declarations)
                            {
                                if (decl2 is UseDeclarationNode use2 && use2.Alias is UseDeclarationAliasNode alias2 &&
                                    alias2 != alias && alias2.NameToken.Text == name.Text)
                                {
                                    duplicate = true;
                                    break;
                                }
                            }

                            if (!duplicate)
                            {
                                _aliases.Add(name.Text, path);
                            }
                            else
                            {
                                Error(alias, SyntaxDiagnosticKind.DuplicateUseDeclarationAlias, name.Location,
                                      $"Module alias '{name}' declared multiple times");
                            }
                        }

                        if (!(LoadModule(use, use.Path.ComponentTokens.Tokens[0].Location, path) is Module mod))
                        {
                            continue;
                        }

                        // Don't import symbols if the module is aliased.
                        if (use.Alias != null)
                        {
                            continue;
                        }

                        foreach (var mdecl in mod.Declarations)
                        {
                            if (!mdecl.IsPublic)
                            {
                                continue;
                            }

                            var sym = mdecl switch
                            {
                                Constant _ => SyntaxSymbolKind.Constant,
                                Function _ => SyntaxSymbolKind.Function,
                                External _ => SyntaxSymbolKind.External,
                                _ => (SyntaxSymbolKind?)null,
                            };

                            if (sym is SyntaxSymbolKind kind)
                            {
                                _scope.Define(kind, path, null, mdecl.Name);
                            }
                        }
                    }

                    foreach (var decl in node.Declarations)
                    {
                        if (!(decl is NamedDeclarationNode named) || decl is MissingNamedDeclarationNode)
                        {
                            continue;
                        }

                        var name = named.NameToken;

                        if (name.IsMissing)
                        {
                            continue;
                        }

                        if (name.Text.StartsWith('_'))
                        {
                            Error(named, SyntaxDiagnosticKind.InvalidDeclarationName, name.Location,
                                  $"Declaration '{name}' is invalid; declaration names cannot start with '_'");
                            continue;
                        }

                        var duplicate = false;

                        foreach (var decl2 in node.Declarations)
                        {
                            if (decl2 == decl || !(decl2 is NamedDeclarationNode named2) ||
                                decl2 is MissingNamedDeclarationNode)
                            {
                                continue;
                            }

                            var name2 = named2.NameToken;

                            if (name2.Text != name.Text)
                            {
                                continue;
                            }

                            duplicate = true;
                        }

                        if (duplicate)
                        {
                            Error(named, SyntaxDiagnosticKind.DuplicateDeclaration, name.Location,
                                  $"Declaration name '{name}' declared multiple times");
                            continue;
                        }

                        var sym = decl switch
                        {
                            ConstantDeclarationNode _ => SyntaxSymbolKind.Constant,
                            FunctionDeclarationNode _ => SyntaxSymbolKind.Function,
                            ExternalDeclarationNode _ => SyntaxSymbolKind.External,
                            _ => (SyntaxSymbolKind?)null,
                        };

                        if (sym is SyntaxSymbolKind kind)
                        {
                            _scope.Define(kind, _path, decl, name.Text);
                        }
                    }

                    foreach (var decl in node.Declarations)
                    {
                        if (!(decl is TestDeclarationNode test))
                        {
                            continue;
                        }

                        var name = test.NameToken;

                        if (name.Text.StartsWith('_'))
                        {
                            Error(test, SyntaxDiagnosticKind.InvalidDeclarationName, name.Location,
                                  $"Test name '{name}' is invalid; test names cannot start with '_'");
                            continue;
                        }

                        var duplicate = false;

                        foreach (var decl2 in node.Declarations)
                        {
                            if (decl2 != decl && decl2 is TestDeclarationNode test2 &&
                                test2.NameToken.Text == name.Text)
                            {
                                duplicate = true;
                                break;
                            }
                        }

                        if (duplicate)
                        {
                            Error(test, SyntaxDiagnosticKind.DuplicateDeclaration, name.Location,
                                  $"Test '{name}' declared multiple times");
                            continue;
                        }
                    }

                    base.Visit(node);
                }