Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(815)

Side by Side Diff: src/cmd/api/goapi.go

Issue 6845058: code review 6845058: cmd/api: speed up API check by 2x, caching parser.Parse... (Closed)
Patch Set: diff -r a26a8ada8f6e https://go.googlecode.com/hg/ Created 11 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Api computes the exported API of a set of Go packages. 5 // Api computes the exported API of a set of Go packages.
6 // 6 //
7 // BUG(bradfitz): Note that this tool is only currently suitable 7 // BUG(bradfitz): Note that this tool is only currently suitable
8 // for use on the Go standard library, not arbitrary packages. 8 // for use on the Go standard library, not arbitrary packages.
9 // Once the Go AST has type information, this tool will be more 9 // Once the Go AST has type information, this tool will be more
10 // reliable without hard-coded hacks throughout. 10 // reliable without hard-coded hacks throughout.
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 if err != nil { 346 if err != nil {
347 log.Fatalf("error unquoting import string %q: %v", is.Pa th.Value, err) 347 log.Fatalf("error unquoting import string %q: %v", is.Pa th.Value, err)
348 } 348 }
349 if fpkg != "C" { 349 if fpkg != "C" {
350 pkgs = append(pkgs, fpkg) 350 pkgs = append(pkgs, fpkg)
351 } 351 }
352 } 352 }
353 return 353 return
354 } 354 }
355 355
356 var parsedFileCache = make(map[string]*ast.File)
357
358 func parseFile(filename string) (*ast.File, error) {
359 f, ok := parsedFileCache[filename]
360 if !ok {
361 var err error
362 f, err = parser.ParseFile(fset, filename, nil, 0)
363 if err != nil {
364 return nil, err
365 }
366 parsedFileCache[filename] = f
367 }
368 return clone(f).(*ast.File), nil
369 }
370
356 // WalkPackage walks all files in package `name'. 371 // WalkPackage walks all files in package `name'.
357 // WalkPackage does nothing if the package has already been loaded. 372 // WalkPackage does nothing if the package has already been loaded.
358 func (w *Walker) WalkPackage(name string) { 373 func (w *Walker) WalkPackage(name string) {
359 switch w.packageState[name] { 374 switch w.packageState[name] {
360 case loading: 375 case loading:
361 log.Fatalf("import cycle loading package %q?", name) 376 log.Fatalf("import cycle loading package %q?", name)
362 case loaded: 377 case loaded:
363 return 378 return
364 } 379 }
365 w.packageState[name] = loading 380 w.packageState[name] = loading
(...skipping 13 matching lines...) Expand all
379 } 394 }
380 log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err) 395 log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err)
381 } 396 }
382 397
383 apkg := &ast.Package{ 398 apkg := &ast.Package{
384 Files: make(map[string]*ast.File), 399 Files: make(map[string]*ast.File),
385 } 400 }
386 401
387 files := append(append([]string{}, info.GoFiles...), info.CgoFiles...) 402 files := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
388 for _, file := range files { 403 for _, file := range files {
389 » » f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0) 404 » » f, err := parseFile(filepath.Join(dir, file))
390 if err != nil { 405 if err != nil {
391 log.Fatalf("error parsing package %s, file %s: %v", name , file, err) 406 log.Fatalf("error parsing package %s, file %s: %v", name , file, err)
392 } 407 }
393 apkg.Files[file] = f 408 apkg.Files[file] = f
394 409
395 for _, dep := range fileDeps(f) { 410 for _, dep := range fileDeps(f) {
396 w.WalkPackage(dep) 411 w.WalkPackage(dep)
397 } 412 }
398 } 413 }
399 414
(...skipping 23 matching lines...) Expand all
423 for _, afile := range apkg.Files { 438 for _, afile := range apkg.Files {
424 w.walkFile(afile) 439 w.walkFile(afile)
425 } 440 }
426 441
427 w.resolveConstantDeps() 442 w.resolveConstantDeps()
428 443
429 // Now that we're done walking types, vars and consts 444 // Now that we're done walking types, vars and consts
430 // in the *ast.Package, use go/doc to do the rest 445 // in the *ast.Package, use go/doc to do the rest
431 // (functions and methods). This is done here because 446 // (functions and methods). This is done here because
432 // go/doc is destructive. We can't use the 447 // go/doc is destructive. We can't use the
433 // *ast.Package after this. 448 // *ast.Package after this.
minux1 2012/11/17 19:31:36 do you want to update the comment here?
bradfitz 2012/11/17 22:13:09 No. This comment is still accurate. doc.New is sti
434 dpkg := doc.New(apkg, name, doc.AllMethods) 449 dpkg := doc.New(apkg, name, doc.AllMethods)
435 450
436 for _, t := range dpkg.Types { 451 for _, t := range dpkg.Types {
437 // Move funcs up to the top-level, not hiding in the Types. 452 // Move funcs up to the top-level, not hiding in the Types.
438 dpkg.Funcs = append(dpkg.Funcs, t.Funcs...) 453 dpkg.Funcs = append(dpkg.Funcs, t.Funcs...)
439 454
440 for _, m := range t.Methods { 455 for _, m := range t.Methods {
441 w.walkFuncDecl(m.Decl) 456 w.walkFuncDecl(m.Decl)
442 } 457 }
443 } 458 }
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 } 1159 }
1145 1160
1146 func strListContains(l []string, s string) bool { 1161 func strListContains(l []string, s string) bool {
1147 for _, v := range l { 1162 for _, v := range l {
1148 if v == s { 1163 if v == s {
1149 return true 1164 return true
1150 } 1165 }
1151 } 1166 }
1152 return false 1167 return false
1153 } 1168 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b