Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 11
feat(internal/config): reduce calling libclang mutiple times#423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
253ae7c19846fbbcc3e2eec3dfe81a3a4f44c9ccfa277bc64f22a90d2f4085b8b8b9eb39ee6de0494289aa853a526588898ae3077fbcdd58726df0c11003947844d98ba356a39cac662e25406b1c1c16f3cf470fbc22861c8484de1522a103d303d1e6de029f571c18cc752543776c37690b3f88f81a2b1102c98d429ac9a766abb1315fe97a11f7c3780339bad7b23c0263ed2ad3a378c25072File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2,11 +2,16 @@ package header_test | ||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "reflect" | ||
| "strings" | ||
| "testing" | ||
| "time" | ||
| "github.com/goplus/lib/c/clang" | ||
| clangutils "github.com/goplus/llcppg/_xtool/internal/clang" | ||
| "github.com/goplus/llcppg/_xtool/internal/clangtool" | ||
| "github.com/goplus/llcppg/_xtool/internal/header" | ||
| llconfig "github.com/goplus/llcppg/config" | ||
| ) | ||
| @@ -73,3 +78,173 @@ func TestPkgHfileInfo(t *testing.T) { | ||
| }) | ||
| } | ||
| } | ||
| func TestLongestPrefix(t *testing.T) { | ||
| testCases := []struct { | ||
| name string | ||
| strs []string | ||
| want string | ||
| }{ | ||
| { | ||
| name: "empty string 1", | ||
| strs: []string{}, | ||
| want: "", | ||
| }, | ||
| { | ||
| name: "empty string 2", | ||
| strs: []string{"", ""}, | ||
| want: ".", | ||
| }, | ||
| { | ||
| name: "one empty string(b)", | ||
| strs: []string{"/a", ""}, | ||
| want: "", | ||
| }, | ||
| { | ||
| name: "one empty string(a)", | ||
| strs: []string{"", "/a"}, | ||
| want: "", | ||
| }, | ||
| // FIXME: substring bug | ||
| // { | ||
| // name: "b is substring of a", | ||
| // strs: []string{"/usr/a/b", "/usr/a"}, | ||
| // want: "/usr/a", | ||
| // }, | ||
| // { | ||
| // name: "a is substring of b", | ||
| // strs: []string{"/usr/c", "/usr/c/b"}, | ||
| // want: "/usr/c", | ||
| // }, | ||
| { | ||
| name: "normal case 1", | ||
| strs: []string{"testdata/hfile/temp1.h", "testdata/thirdhfile/third.h"}, | ||
| want: "testdata", | ||
| }, | ||
| { | ||
| name: "normal case 2", | ||
| strs: []string{"testdata/hfile/temp1.h", "testdata/hfile/third.h"}, | ||
| want: "testdata/hfile", | ||
| }, | ||
| // FIXME: absolute path | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A Note is recommended to use "MARKER(uid): note body" format. Detailslint 解释这个lint结果提示在注释中使用“MARKER(uid): note body”格式是一个推荐的做法。这意味着在编写注释时,应该遵循这种特定的格式来提高代码的可读性和一致性。 错误用法以下是一个错误的示例,展示了不正确的注释格式: // 这是一个错误的注释格式正确用法以下是一个正确的示例,展示了符合推荐格式的注释: // MARKER(12345): 这是一个正确的注释格式
| ||
| // { | ||
| // name: "normal case 3", | ||
| // strs: []string{"/opt/homebrew/Cellar/cjson/1.7.18/include/cJSON/cJSON.h", "/opt/homebrew/Cellar/cjson/1.7.18/include/cJSON.h", "/opt/homebrew/Cellar/cjson/1.7.18/include/zlib/zlib.h"}, | ||
| // want: "/opt/homebrew/Cellar/cjson/1.7.18/include", | ||
| // }, | ||
| } | ||
| for _, tc := range testCases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| if got := header.CommonParentDir(tc.strs); got != tc.want { | ||
| t.Fatalf("unexpected longest prefix: want %s got %s", tc.want, got) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| func benchmarkFn(fn func()) time.Duration { | ||
| now := time.Now() | ||
| fn() | ||
| return time.Since(now) | ||
| } | ||
| func TestBenchmarkPkgHfileInfo(t *testing.T) { | ||
| include := []string{"temp1.h", "temp2.h"} | ||
| cflags := []string{"-I./testdata/hfile", "-I./testdata/thirdhfile"} | ||
| t1 := benchmarkFn(func() { | ||
| for i := 0; i < 100; i++ { | ||
| pkgHfileInfo(include, cflags, false) | ||
| } | ||
| }) | ||
| t2 := benchmarkFn(func() { | ||
| for i := 0; i < 100; i++ { | ||
| header.PkgHfileInfo(include, cflags, false) | ||
| } | ||
| }) | ||
| fmt.Println("old PkgHfileInfo elapsed: ", t1, "new PkgHfileInfo elasped: ", t2) | ||
| } | ||
| func pkgHfileInfo(includes []string, args []string, mix bool) *header.PkgHfilesInfo { | ||
| info := &header.PkgHfilesInfo{ | ||
| Inters: []string{}, | ||
| Impls: []string{}, | ||
| Thirds: []string{}, | ||
| } | ||
| outfile, err := os.CreateTemp("", "compose_*.h") | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| defer os.Remove(outfile.Name()) | ||
| inters := make(map[string]struct{}) | ||
| others := []string{} // impl & third | ||
| for _, f := range includes { | ||
| content := "#include <" + f + ">" | ||
| index, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{ | ||
| File: content, | ||
| Temp: true, | ||
| Args: args, | ||
| }) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| clangutils.GetInclusions(unit, func(inced clang.File, incins []clang.SourceLocation) { | ||
| if len(incins) == 1 { | ||
| filename := filepath.Clean(clang.GoString(inced.FileName())) | ||
| info.Inters = append(info.Inters, filename) | ||
| inters[filename] = struct{}{} | ||
| } | ||
| }) | ||
| unit.Dispose() | ||
| index.Dispose() | ||
| } | ||
| clangtool.ComposeIncludes(includes, outfile.Name()) | ||
| index, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{ | ||
| File: outfile.Name(), | ||
| Temp: false, | ||
| Args: args, | ||
| }) | ||
| defer unit.Dispose() | ||
| defer index.Dispose() | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| clangutils.GetInclusions(unit, func(inced clang.File, incins []clang.SourceLocation) { | ||
| // not in the first level include maybe impl or third hfile | ||
| filename := filepath.Clean(clang.GoString(inced.FileName())) | ||
| _, inter := inters[filename] | ||
| if len(incins) > 1 && !inter { | ||
| others = append(others, filename) | ||
| } | ||
| }) | ||
| if mix { | ||
| info.Thirds = others | ||
| return info | ||
| } | ||
| root, err := filepath.Abs(header.CommonParentDir(info.Inters)) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| for _, f := range others { | ||
| file, err := filepath.Abs(f) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| if strings.HasPrefix(file, root) { | ||
| info.Impls = append(info.Impls, f) | ||
| } else { | ||
| info.Thirds = append(info.Thirds, f) | ||
| } | ||
| } | ||
| return info | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| #include "tempimpl.h" | ||
| #include "temp2.h" | ||
| #include <third.h> |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Note is recommended to use "MARKER(uid): note body" format.
Details
lint 解释
这个lint结果提示在注释中使用“MARKER(uid): note body”格式是一个建议。这意味着在编写注释时,应该遵循这种特定的格式来提高代码的可读性和一致性。
错误用法
以下是一个错误的示例,展示了不正确的注释格式:
// 这是一个错误的注释格式正确用法
以下是一个正确的示例,展示了符合建议的注释格式:
// MARKER(12345): 这是一个正确的注释格式