LuaLS / LuaLS/lua-language-server

[Library] A native Luals parser

Ouverte
#2,910 9 commentaires 10 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

rust
Langage dominant
Lua
Étoiles
4.4k
Forks
442
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

I have completed most of the work, but there may still be many bugs in the details that I will gradually fix in future use. I will implement a new language server based on this. If you are interested, you can continue to follow my progress.

the library: https://crates.io/crates/emmylua_parser

a simple example:

let code = r#"
    local a = 1
    local b = 2
    local function foo(x)
        return x + 1
    end
    function f()
    end
    local c = foo(a + b)
    if c > 2 then
        print(c)
    elseif c == 2 then
    else
        print("c is not greater than 2")
    end
    for i = 1, 10 do
        print(i)
    end
    for i, v in ipairs({1, 2, 3}) do
        print(i, v)
    end
    while c < 10 do
        c = c + 1
    end
    repeat
        c = c - 1
    until c == 0
    ::ll::
    goto ll
    local a = c["string"]
"#;
let tree = LuaParser::parse(code, ParserConfig::default());
let chunk = tree.get_chunk_node();
for node in chunk.descendants::<LuaAst>() {
    match node {
        LuaAst::LuaChunk(lua_chunk) => {
            assert!(lua_chunk.get_block().is_some());
        }
        LuaAst::LuaBlock(lua_block) => {
            assert!(lua_block.get_stats().next().is_some());
        }
        LuaAst::LuaAssignStat(lua_assign_stat) => {
            let (var_list, expr_list) = lua_assign_stat.get_var_and_expr_list();
            assert!(var_list.len() > 0);
            assert!(expr_list.len() > 0);
        }
        LuaAst::LuaLocalStat(lua_local_stat) => {
            let mut name_list = lua_local_stat.get_local_name_list();
            let local_name = name_list.next().unwrap();
            assert!(local_name.get_name_token().is_some());
            let mut expr_list = lua_local_stat.get_value_exprs();
            assert!(expr_list.next().is_some());
        }
        LuaAst::LuaCallExprStat(lua_call_expr_stat) => {
            assert!(lua_call_expr_stat.get_call_expr().is_some());
        }
        LuaAst::LuaLabelStat(lua_label_stat) => {
            assert!(lua_label_stat.get_label_name_token().is_some());
            assert_eq!(
                lua_label_stat
                    .get_label_name_token()
                    .unwrap()
                    .get_name_text(),
                "ll"
            );
        }
        LuaAst::LuaGotoStat(lua_goto_stat) => {
            assert!(lua_goto_stat.get_label_name_token().is_some());
            assert_eq!(
                lua_goto_stat
                    .get_label_name_token()
                    .unwrap()
                    .get_name_text(),
                "ll"
            );
        }
        LuaAst::LuaDoStat(lua_do_stat) => {
            assert!(lua_do_stat.get_block().is_some());
        }
        LuaAst::LuaWhileStat(lua_while_stat) => {
            assert!(lua_while_stat.get_condition_expr().is_some());
            assert!(lua_while_stat.get_block().is_some());
        }
        LuaAst::LuaRepeatStat(lua_repeat_stat) => {
            assert!(lua_repeat_stat.get_block().is_some());
            assert!(lua_repeat_stat.get_condition_expr().is_some());
        }
        LuaAst::LuaIfStat(lua_if_stat) => {
            assert!(lua_if_stat.get_condition_expr().is_some());
            assert!(lua_if_stat.get_block().is_some());
            assert!(lua_if_stat.get_else_if_clause_list().next().is_some());
            assert!(lua_if_stat.get_else_clause().is_some());
        }
        LuaAst::LuaForStat(lua_for_stat) => {
            assert!(lua_for_stat.get_var_name().is_some());
            assert!(lua_for_stat.get_block().is_some());
            assert_eq!(lua_for_stat.get_iter_expr().count(), 2);
        }
        LuaAst::LuaForRangeStat(lua_for_range_stat) => {
            assert_eq!(lua_for_range_stat.get_var_name_list().count(), 2);
            assert!(lua_for_range_stat.get_block().is_some());
            assert!(lua_for_range_stat.get_expr_list().next().is_some());
        }
        LuaAst::LuaFuncStat(lua_func_stat) => {
            assert!(lua_func_stat.get_func_name().is_some());
            assert!(lua_func_stat.get_closure().is_some());
        }
        LuaAst::LuaLocalFuncStat(lua_local_func_stat) => {
            assert!(lua_local_func_stat.get_local_name().is_some());
            assert!(lua_local_func_stat.get_closure().is_some());
        }
        LuaAst::LuaReturnStat(lua_return_stat) => {
            assert!(lua_return_stat.get_expr_list().next().is_some());
        }
        LuaAst::LuaNameExpr(lua_name_expr) => {
            assert!(lua_name_expr.get_name_token().is_some());
        }
        LuaAst::LuaIndexExpr(lua_index_expr) => {
            assert!(lua_index_expr.get_prefix_expr().is_some());
            assert!(lua_index_expr.get_indexed_expr().is_some());
        }
        LuaAst::LuaTableExpr(lua_table_expr) => {
            assert!(lua_table_expr.is_array());
        }
        _ => {}
    }
}

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par la crate emmylua_parser liée et l’exemple qui utilise LuaParser::parse et get_chunk_node(), puis comparez sa couverture de l’AST avec le dépôt du language server. L’issue ne nomme ni fichiers du dépôt, ni tests, ni points d’intégration, ni critères d’acceptation ; la définition de done reste donc floue.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
lua, rust
Domaine
compilers, devtools
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
18/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.