Skip to content

Commit ddca707

Browse files
committed
feat: cxx/c parser skeleton with clangd-18
1 parent 7e80be5 commit ddca707

File tree

9 files changed

+237
-0
lines changed

9 files changed

+237
-0
lines changed

lang/collect/collect.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strings"
2323
"unicode"
2424

25+
"github.com/cloudwego/abcoder/lang/cxx"
2526
"github.com/cloudwego/abcoder/lang/log"
2627
. "github.com/cloudwego/abcoder/lang/lsp"
2728
"github.com/cloudwego/abcoder/lang/rust"
@@ -79,6 +80,8 @@ func switchSpec(l uniast.Language) LanguageSpec {
7980
switch l {
8081
case uniast.Rust:
8182
return &rust.RustSpec{}
83+
case uniast.Cxx:
84+
return &cxx.CxxSpec{}
8285
default:
8386
panic(fmt.Sprintf("unsupported language %s", l))
8487
}

lang/cxx/lib.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2025 CloudWeGo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cxx
16+
17+
import (
18+
"time"
19+
20+
"github.com/cloudwego/abcoder/lang/uniast"
21+
"github.com/cloudwego/abcoder/lang/utils"
22+
)
23+
24+
const MaxWaitDuration = 5 * time.Minute
25+
26+
func GetDefaultLSP() (lang uniast.Language, name string) {
27+
return uniast.Cxx, "clangd-18"
28+
}
29+
30+
func CheckRepo(repo string) (string, time.Duration) {
31+
openfile := ""
32+
// TODO: check if the project compiles.
33+
34+
// NOTICE: wait for Rust projects based on code files
35+
_, size := utils.CountFiles(repo, ".c", "SKIPDIR")
36+
wait := 2*time.Second + time.Second*time.Duration(size/1024)
37+
if wait > MaxWaitDuration {
38+
wait = MaxWaitDuration
39+
}
40+
return openfile, wait
41+
}

lang/cxx/spec.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2025 CloudWeGo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cxx
16+
17+
import (
18+
lsp "github.com/cloudwego/abcoder/lang/lsp"
19+
)
20+
21+
type CxxSpec struct {
22+
repo string
23+
}
24+
25+
func NewCxxSpec() *CxxSpec {
26+
return &CxxSpec{}
27+
}
28+
29+
func (c *CxxSpec) WorkSpace(root string) (map[string]string, error) {
30+
panic("TODO")
31+
}
32+
33+
func (c *CxxSpec) NameSpace(path string) (string, string, error) {
34+
panic("TODO")
35+
}
36+
37+
func (c *CxxSpec) ShouldSkip(path string) bool {
38+
panic("TODO")
39+
}
40+
41+
func (c *CxxSpec) DeclareTokenOfSymbol(sym lsp.DocumentSymbol) int {
42+
panic("TODO")
43+
}
44+
45+
func (c *CxxSpec) IsEntityToken(tok lsp.Token) bool {
46+
panic("TODO")
47+
}
48+
49+
func (c *CxxSpec) IsStdToken(tok lsp.Token) bool {
50+
panic("TODO")
51+
}
52+
53+
func (c *CxxSpec) TokenKind(tok lsp.Token) lsp.SymbolKind {
54+
panic("TODO")
55+
}
56+
57+
func (c *CxxSpec) IsMainFunction(sym lsp.DocumentSymbol) bool {
58+
panic("TODO")
59+
}
60+
61+
func (c *CxxSpec) IsEntitySymbol(sym lsp.DocumentSymbol) bool {
62+
panic("TODO")
63+
}
64+
65+
func (c *CxxSpec) IsPublicSymbol(sym lsp.DocumentSymbol) bool {
66+
panic("TODO")
67+
}
68+
69+
func (c *CxxSpec) HasImplSymbol() bool {
70+
panic("TODO")
71+
}
72+
73+
func (c *CxxSpec) ImplSymbol(sym lsp.DocumentSymbol) (int, int, int) {
74+
panic("TODO")
75+
}
76+
77+
func (c *CxxSpec) FunctionSymbol(sym lsp.DocumentSymbol) (int, []int, []int, []int) {
78+
panic("TODO")
79+
}
80+
81+
func (c *CxxSpec) GetUnloadedSymbol(from lsp.Token, define lsp.Location) (string, error) {
82+
panic("TODO")
83+
}

lang/parse.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"time"
2727

2828
"github.com/cloudwego/abcoder/lang/collect"
29+
"github.com/cloudwego/abcoder/lang/cxx"
2930
"github.com/cloudwego/abcoder/lang/golang/parser"
3031
"github.com/cloudwego/abcoder/lang/log"
3132
"github.com/cloudwego/abcoder/lang/lsp"
@@ -94,6 +95,9 @@ func checkRepoPath(repoPath string, language uniast.Language) (openfile string,
9495
case uniast.Rust:
9596
// NOTICE: open the Cargo.toml file is required for Rust projects
9697
openfile, wait = rust.CheckRepo(repoPath)
98+
case uniast.Cxx:
99+
// NOTICE: open the Cargo.toml file is required for Rust projects
100+
openfile, wait = cxx.CheckRepo(repoPath)
97101
default:
98102
openfile = ""
99103
wait = 0
@@ -107,6 +111,8 @@ func checkLSP(language uniast.Language, lspPath string) (l uniast.Language, s st
107111
switch language {
108112
case uniast.Rust:
109113
l, s = rust.GetDefaultLSP()
114+
case uniast.Cxx:
115+
l, s = cxx.GetDefaultLSP()
110116
case uniast.Golang:
111117
l = uniast.Golang
112118
s = ""

lang/uniast/ast.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Language string
2828
const (
2929
Golang Language = "go"
3030
Rust Language = "rust"
31+
Cxx Language = "cxx"
3132
Unknown Language = ""
3233
)
3334

@@ -37,6 +38,8 @@ func (l Language) String() string {
3738
return "rust"
3839
case Golang:
3940
return "go"
41+
case Cxx:
42+
return "cxx"
4043
default:
4144
return string(l)
4245
}
@@ -53,6 +56,8 @@ func NewLanguage(lang string) (l Language) {
5356
return Golang
5457
case "rust":
5558
return Rust
59+
case "cxx":
60+
return Cxx
5661
default:
5762
return Unknown
5863
}

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Action:
5050
write write the UniAST to the output directory
5151
Language:
5252
rust for rust codes
53+
cxx for c codes (cpp support is on the way)
5354
go for golang codes
5455
URI:
5556
for action parse: the directory path of the repo

testdata/cxxsimple/main.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2025 CloudWeGo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <stdio.h>
16+
17+
#include "pair.h"
18+
19+
union IntOrChar {
20+
int i;
21+
char c;
22+
};
23+
24+
extern int add(int, int);
25+
26+
#define MAXN 100
27+
int arr[MAXN];
28+
29+
int compare(const void *a, const void *b) {
30+
int int_a = *((int *)a);
31+
int int_b = *((int *)b);
32+
if (int_a < int_b) return -1;
33+
if (int_a > int_b) return 1;
34+
return 0;
35+
}
36+
37+
int main() {
38+
StructIntPair x;
39+
x.a = 5;
40+
x.b = 6;
41+
swapPair(&x);
42+
struct IntPair y = myself(&x);
43+
return y.a+y.b;
44+
}
45+

testdata/cxxsimple/pair.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2025 CloudWeGo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "pair.h"
16+
17+
void swapPair(StructIntPair *a) {
18+
int c = a->b;
19+
a->b = a->a;
20+
a->a = c;
21+
}
22+
23+
struct IntPair myself(StructIntPair *a) {
24+
return *a;
25+
}

testdata/cxxsimple/pair.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2025 CloudWeGo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef PAIR_H
16+
#define PAIR_H
17+
18+
struct IntPair {
19+
int a;
20+
int b;
21+
};
22+
typedef struct IntPair StructIntPair;
23+
24+
void swapPair(StructIntPair *a);
25+
26+
struct IntPair myself(StructIntPair *a);
27+
28+
#endif // PAIR_H

0 commit comments

Comments
 (0)