Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Voice of Code - COSCUP 2018

Yo-An Lin
August 12, 2018

The Voice of Code - COSCUP 2018

Nowadays, the screen readers are used for the blind people to read the text on the screen. The speech speed of the screen reader is usually incredibly fast, and it reads almost everything on the screen. Also, the generated speech is not so friendly for the users.

However, it's important for people to quickly get the meaningful summary of the current source code navigation, even for people with average eye-sight.

This talk introduces you the design of the navigation assistant, and the technical implementation details of the tool.

The assistant is implemented in Go, and its language parser is used to generate a short comprehensive summary, and the text will be converted to voice speech to improve your source code navigation experience.

Yo-An Lin

August 12, 2018

More Decks by Yo-An Lin

Other Decks in Technology


  1. If left paren x equals five right paren left brace

    print left paren quote hello world exclaim quote right paren right brace. if (x == 5) { print("Hello World!") }
  2. Difficulties • You need to confirm every input. • You

    need to confirm the current location on the screen. • You need to search the components that is displayed on the screen.
  3. Difficulties for Coders • How do you read through huge

    amount of console logs? • How do you read JSON? • How do you separate shell prompts and the current input without seeing it?
  4. MongoDB shell version v3.4.10 connecting to: mongodb:// MongoDB server version:

    3.4.10 Server has startup warnings: 2018-07-30T15:02:31.783+0800 I CONTROL [initandlisten] 2018-07-30T15:02:31.783+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-07-30T15:02:31.783+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-07-30T15:02:31.783+0800 I CONTROL [initandlisten] >
  5. func TestProxy(t *testing.T) { func test proxy left paren T

    星號 testing dot T right paren left brace
  6. If left paren x equals five right paren left brace

    print left paren quote hello world exclaim quote right paren right brace.
  7. If left paren x equals five right paren left brace

    print left paren quote hello world exclaim quote right paren right brace.
  8. There are ~1k lines of code in this file. 2

    Struct Types, 12 Public Functions, 3 Private Functions and 14 Constants.
  9. func TestProxy [[char LTRL]] (* [[char NORM]] testing [[char LTRL]]

    . [[char NORM]] T [[char LTRL]] ) [[char NORM]]
  10. Gracula • Run as a JSON-RPC server • Generate summary

    for files, types and statements. • Generate readable transcripts for voice synthesizer to read. • Integrate voice synthesizers for different platforms. • Ability of adjusting resolution. • Support LSP (Language Server Protocol)
  11. Language Server Protocol • JSON-RPC based protocol. • Major languages

    are supported. • Major IDEs and Editors are supported. • Supported by Microsoft.
  12. Go • Pure Go Parser for Go since Go 1.5.

    • AST structures in Go. • JSON RPC server is ready. • Mature language. • Tool Guru
  13. Guru Commands • callees - show possible targets of selected

    function call • callers - show possible callers of selected function • callstack - show path from callgraph root to selected function • definition - show declaration of selected identifier • describe - describe selected syntax: definition, methods, etc • what - show basic information about the selected syntax node
  14. Language Query guru -json describe /Users/c9s/src/golang.org/x/tools/cmd/guru/callers.go:#5096 { "desc": "identifier", "pos":

    "/Users/c9s/src/golang.org/x/tools/cmd/guru/callers.go:186:6", "detail": "value", "value": { "type": "[]golang.org/x/tools/cmd/guru/serial.Caller", "objpos": "/Users/c9s/src/golang.org/x/tools/cmd/guru/callers.go:186:6" } }
  15. go/parser filepath := "src/golang.org/x/tools/cmd/guru/main.go" fset := token.NewFileSet() f, err :=

    parser.ParseFile(fset, filepath, nil, parser.ParseComments) if err != nil { log.Fatal(err) return }
  16. go/parser for _, decl := range f.Decls { switch e

    := decl.(type) { case *ast.FuncDecl: case *ast.GenDecl: for _, spec := range e.Specs { switch s := spec.(type) { case *ast.TypeSpec: fmt.Printf(" type spec: name=%+v type=%v\n", s.Name, s.Type) switch t := s.Type.(type) { case *ast.StructType: case *ast.FuncType: case *ast.InterfaceType: case *ast.ArrayType: } case *ast.ValueSpec: fmt.Printf(" value spec: names=%v values=%v\n", s.Names, s.Values) case *ast.ImportSpec: fmt.Printf(" import spec: path=%v\n", s.Path.Value) } } default: fmt.Printf(" decl: %+v\n", e) } }
  17. Q&A