1
0
mirror of https://github.com/golang/go synced 2024-11-19 06:04:39 -07:00
Commit Graph

31 Commits

Author SHA1 Message Date
Alan Donovan
8ae5d36d2a go.tools: clear DeclarationErrors flag; it's redundant w.r.t go/types checking.
R=gri
CC=golang-dev
https://golang.org/cl/14147043
2013-10-08 10:34:36 -04:00
Alan Donovan
2bd0ec31c0 go.tools/oracle: fix minor but confusing bug in test driver.
Since rev 4c5f46cc7b9d, error messages no longer contain
"file:line:col: " prefixes, so applying stripLocation to them
is incorrect.

Also: add rationale comment to callgraph2.go test.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13888044
2013-10-01 10:17:26 -04:00
Alan Donovan
06c4192423 go.tools/pointer: minor API simplifications.
Details:
- Warnings are reported as values in Result, not a callback in Config.
- remove TODO to eliminate Print callback.  It's better than the alternative.
- remove unused Config.root field.
- hang Result off analysis object (impl. detail)
- reword TODO.

R=crawshaw
CC=golang-dev
https://golang.org/cl/14128043
2013-09-30 12:39:54 -04:00
Alan Donovan
d7287a0289 go.tool.pointer: fix regression in pointer.cgraph.Root().
The previous CL made the assumption that Root is the first
node, which is false for programs that import "reflect".
Reverted to the previous way: an explicit root field.

Added regression test (callgraph2) via oracle.

R=crawshaw
TBR=crawshaw
CC=golang-dev
https://golang.org/cl/13967043
2013-09-26 09:31:39 -04:00
Alan Donovan
785cfaa938 go.tools/pointer: use new callgraph API.
Also: pointer.Analyze now returns a pointer.Result object,
containing the callgraph and the results of ssa.Value queries.

The oracle has been updated to use the new call and pointer APIs.

R=crawshaw, gri
CC=golang-dev
https://golang.org/cl/13915043
2013-09-25 17:17:42 -04:00
Alan Donovan
3a4c0462d8 go.tools/oracle: change -mode argument into subcommand.
e.g. "oracle callgraph <package>"

Also: simplified error handling.
Eliminated oracle.errorf because it prepends "file:line:col: "
to the error message so the main function can't safely prepend "Error: ".
The position wasn't interesting though: it was just -pos, more or less.

R=crawshaw, dominik.honnef, r
CC=golang-dev
https://golang.org/cl/13864044
2013-09-25 14:34:39 -04:00
Alan Donovan
37f76edde8 go.tools/oracle: support -format=xml (for Eclipse)
This CL is mostly a renaming s/json/serial/, abstracting the
oracle package away from any particular data syntax.  (The
encoding/* machinery is very clean; clearly I should have
structured it this way from the outset.)

Supporting XML then becomes a one-liner in cmd/oracle/main.go.

Also: call MarshalIndent(), not Marshall() then Indent().

R=crawshaw
CC=golang-dev
https://golang.org/cl/13858046
2013-09-24 15:08:14 -04:00
Alan Donovan
318b83e376 go.tools/ssa: SSA fixes for *types.Builtin becoming an object (CL 13813043)
R=gri
CC=golang-dev
https://golang.org/cl/13848043
2013-09-23 18:18:35 -04:00
Alan Donovan
3371b79a96 go.tools/pointer: reflect, part 2: channels.
(reflect.Value).Send
        (reflect.Value).TrySend
        (reflect.Value).Recv
        (reflect.Value).TryRecv
        (reflect.Type).ChanOf
        (reflect.Type).In
        (reflect.Type).Out
        reflect.Indirect
        reflect.MakeChan

Also:
- specialize genInvoke when the receiver is a reflect.Type under the
  assumption that there's only one possible concrete type.  This
  makes all reflect.Type operations context-sensitive since the calls
  are no longer dynamic.
- Rename all variables to match the actual parameter names used in
  the reflect API.
- Add pointer.Config.Reflection flag
  (exposed in oracle as --reflect, default false) to enable reflection.
  It currently adds about 20% running time.  I'll make it true after
  the presolver is implemented.
- Simplified worklist datatype and solver main loop slightly
  (~10% speed improvement).
- Use addLabel() utility to add a label to a PTS.

(Working on my 3 yr old 2x2GHz+4GB Mac vs 8x4GHz+24GB workstation,
one really notices the cost of pointer analysis.
Note to self: time to implement presolver.)

R=crawshaw
CC=golang-dev
https://golang.org/cl/13242062
2013-09-23 16:13:01 -04:00
Alan Donovan
25a0cc4bfd go.tools/oracle: refactor Oracle API to allow repeated queries on same scope.
The existing standalone Query function builds an importer, ssa.Program, oracle,
and query position, executes the query and returns the result.
For clients (such as Frederik Zipp's web-based github.com/fzipp/pythia tool)
that wish to load the program once and make several queries, we now expose
these as separate operations too.  Here's a client, in pseudocode:

        o := oracle.New(...)
        for ... {
                qpos := o.ParseQueryPos(...)
                res := o.Query(mode, qpos)
                print result
        }

NB: this is a slight deoptimisation in the one-shot case since we have to
build the entire SSA program with debug info, not just the query package,
since we now don't know the query package at that time.

The 'exact' param to ParseQueryPos needs more thought since its
ideal value is a function of the query mode.  This will do for now.

Details:
- expose Oracle type, New() func and Query() method.
- expose QueryPos type and ParseQueryPos func.
- improved package doc comment.
- un-exposed the "needs" bits.
- added test.

R=crawshaw
CC=frederik.zipp, golang-dev
https://golang.org/cl/13810043
2013-09-23 15:02:18 -04:00
Alan Donovan
0c4a02a8c4 go.tools/oracle: improve usage messages.
Full help is only displayed when -help is requested;
CLI usage errors just remind the the user of this flag.

R=r, crawshaw
CC=golang-dev
https://golang.org/cl/13523048
2013-09-20 11:35:00 -04:00
Robert Griesemer
0e06e5845b go.tools/oracle: fix oracle tests (fix build partly)
R=adonovan
CC=golang-dev
https://golang.org/cl/13722049
2013-09-18 11:32:18 -07:00
Alan Donovan
3b5de067a1 go.tools/pointer: reflection, part 1: maps, and some core features.
Core:
        reflect.TypeOf
        reflect.ValueOf
        reflect.Zero
        reflect.Value.Interface
Maps:
        (reflect.Value).MapIndex
        (reflect.Value).MapKeys
        (reflect.Value).SetMapIndex
        (*reflect.rtype).Elem
        (*reflect.rtype).Key

+ tests:
  pointer/testdata/mapreflect.go.
  oracle/testdata/src/main/reflection.go.

Interface objects (T, V...) have been renamed "tagged objects".

Abstraction: we model reflect.Value similar to
interface{}---as a pointer that points only to tagged
objects---but a reflect.Value may also point to an "indirect
tagged object", one in which the payload V is of type *T not T.
These are required because reflect.Values can hold lvalues,
e.g. when derived via Field() or Elem(), though we won't use
them till we get to structs and pointers.

Solving: each reflection intrinsic defines a new constraint
and resolution rule.  Because of the nature of reflection,
generalizing across types, the resolution rules dynamically
create additional complex constraints during solving, where
previously only simple (copy) constraints were created.
This requires some solver changes:

  The work done before the main solver loop (to attach new
  constraints to the graph) is now done before each iteration,
  in processNewConstraints.

  Its loop over constraints is broken into two passes:
  the first handles base (addr-of) constraints,
  the second handles simple and complex constraints.

  constraint.init() has been inlined.  The only behaviour that
  varies across constraints is ptr()

Sadly this will pessimize presolver optimisations, when we get
there; such is the price of reflection.

Objects: reflection intrinsics create objects (i.e. cause
memory allocations) with no SSA operation.  We will represent
them as the cgnode of the instrinsic (e.g. reflect.New), so we
extend Labels and node.data to represent objects as a product
(not sum) of ssa.Value and cgnode and pull this out into its
own type, struct object.  This simplifies a number of
invariants and saves space.  The ntObject flag is now
represented by obj!=nil; the other flags are moved into
object.

cgnodes are now always recorded in objects/Labels for which it
is appropriate (all but those for globals, constants and the
shared contours for functions).

Also:
- Prepopulate the flattenMemo cache to consider reflect.Value
  a fake pointer, not a struct.
- Improve accessors and documentation on type Label.
- @conctypes assertions renamed @types (since dyn. types needn't be concrete).
- add oracle 'describe' test on an interface (missing, an oversight).

R=crawshaw
CC=golang-dev
https://golang.org/cl/13418048
2013-09-16 09:49:10 -04:00
Robert Griesemer
1928c01286 go.tools/go/types: separate package descriptor from package object
Includes changes by adonovan to make oracle work again
(former CL 13395050).

R=adonovan
CC=golang-dev
https://golang.org/cl/13672044
2013-09-13 09:52:57 -07:00
Alan Donovan
daa44ab970 go.oracle: freevars: don't report free identifiers defined in package scope.
The existing check rejected only free identifiers defined in
file scope, i.e. just imports.

+ regression test.

R=crawshaw, gri
CC=golang-dev
https://golang.org/cl/13256050
2013-09-12 11:00:22 -04:00
Alan Donovan
d38c09ed22 go.tools/oracle: set AllASTs=true always, and simplify.
Every one of the oracle's query modes needs to have typed ASTs
available, at least transiently, so that the -pos flag can be
interpreted.  (The only mode that doesn't need the -pos flag
is callgraph, but that needs PTA.)  So we hard-code it to true.

This change fixes a bug in the 'implements' query that causes
-pos parsing to fail.  (This wasn't exposed by the tests
because they are degenerate in that the query always occurs in
the main package, which is specified ad-hoc, i.e. as a source
file not an import path.  That's unfortunate, but this
change renders the distinction uninteresting in future.)

R=crawshaw, dominik.honnef
CC=golang-dev
https://golang.org/cl/13334050
2013-09-12 10:55:24 -04:00
Alan Donovan
c18d759e6b go.tools/oracle: describe package: simplify to use only types.Package, not ssa.Package.
R=crawshaw
CC=golang-dev
https://golang.org/cl/13396050
2013-09-10 14:19:11 -04:00
Alan Donovan
0725e5a5b3 go.tools/oracle: new query 'referrers' returns all references to an identifier.
+ test.

Also:
- provide non-nil map to Importer.doImport0() to avoid a crash.
- reorganize oracle "needs" bits.
- reduce "needs" of 'freevars' and 'implements' queries by avoiding
  ssa.Packages when types.Package suffices.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13421046
2013-09-10 14:11:42 -04:00
Alan Donovan
927e0f9da6 go.tools/oracle: describe: query content of lvalues, not their address.
Background: some ssa.Values represent lvalues, e.g.
      var g = new(string)
the *ssa.Global g is a **string, the address of what users
think of as the global g.

Querying pts(g) returns a singleton containing the object g, a
*string.  What users really want to see is what that in turn
points to, i.e. the label for the call to new().

This change now lets users make "indirect" pointer queries,
i.e. for pts(*v) where v is an ssa.Value.  The oracle makes an
indirect query if the type of the ssa.Value differs from the
source expression type by a pointer, i.e. it's an lvalue.

In other words, we're hiding the fact that compilers (e.g. ssa) internally represent globals by their address.

+ Tests.

This serendipitously fixed an outstanding bug mentioned in the
describe.go

R=crawshaw
CC=golang-dev
https://golang.org/cl/13532043
2013-09-09 21:06:25 -04:00
Alan Donovan
c6e88b1b2a go.tools/cmd/oracle: use -pos=file:#start,#end syntax to indicate half-open [start,end) extent of byte offsets.
Also: improve help message.

R=r, crawshaw, rsc
CC=golang-dev
https://golang.org/cl/13593043
2013-09-08 22:10:11 -04:00
Alan Donovan
3f2f9a7e70 go.tools/importer: generalize command-line syntax.
Motivation: pointer analysis tools (like the oracle) want the
user to specify a set of initial packages, like 'go test'.
This change enables the user to specify a set of packages on
the command line using importer.LoadInitialPackages(args).

Each argument is interpreted as either:
- a comma-separated list of *.go source files together
  comprising one non-importable ad-hoc package.
  e.g. "src/pkg/net/http/triv.go" gives us [main].
- an import path, denoting both the imported package
  and its non-importable external test package, if any.
  e.g. "fmt" gives us [fmt, fmt_test].

Current type-checker limitations mean that only the first
import path may contribute tests: multiple packages augmented
by *_test.go files could create import cycles, which 'go test'
avoids by building a separate executable for each one.
That approach is less attractive for static analysis.

Details:  (many files touched, but importer.go is the crux)

importer:
- PackageInfo.Importable boolean indicates whether
  package is importable.
- un-expose Importer.Packages; expose AllPackages() instead.
- CreatePackageFromArgs has become LoadInitialPackages.
- imports() moved to util.go, renamed importsOf().
- InitialPackagesUsage usage message exported to clients.
- the package name for ad-hoc packages now comes from the
  'package' decl, not "main".

ssa.Program:
- added CreatePackages() method
- PackagesByPath un-exposed, renamed 'imported'.
- expose AllPackages and ImportedPackage accessors.

oracle:
- describe: explain and workaround a go/types bug.

Misc:
- Removed various unnecessary error.Error() calls in Printf args.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13579043
2013-09-06 18:13:57 -04:00
Alan Donovan
a1dade8bdc go.oracle: describe: disambiguate 'func' object kinds.
The typechecker uses *types.Func for functions, concrete
methods and interface methods; and *types.Var for variables
and struct fields.  This change makes clear which kind of
function we're describing.  (We can't do it for vars since
go/types doesn't expose enough information, yet.)

Also: add "omitempty" to one JSON field.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13527044
2013-09-04 16:15:41 -04:00
Alan Donovan
f9e325b575 go.tools/oracle: change notation for byte offsets to "-pos=file.go:#123-#456"
The previous notation (sans '#') now yields an error but is
"reserved for future use", e.g. to denote line/column offsets.
Will implement as needed.

R=r, crawshaw
CC=golang-dev
https://golang.org/cl/13526043
2013-09-04 14:35:24 -04:00
Alan Donovan
e2921e188a go.tools/importer: make loading/parsing concurrent.
1. ParseFiles (in util.go) parses each file in its own goroutine.

2. (*Importer).LoadPackage asynchronously prefetches the
   import graph by scanning the imports of each loaded package
   and calling LoadPackage on each one.

   LoadPackage is now thread-safe and idempotent: it uses a
   condition variable per package; the first goroutine to
   request a package becomes responsible for loading it and
   broadcasts to the others (waiting) when it becomes ready.

ssadump runs 34% faster when loading the oracle.

Also, refactorings:
- delete SourceLoader mechanism; just expose go/build.Context directly.
- CreateSourcePackage now also returns an error directly,
  rather than via PackageInfo.Err, since every client wants that.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13509045
2013-09-04 13:15:49 -04:00
Alan Donovan
d2cdbefbfc go.tools/oracle: add option to output results in JSON syntax.
See json.go for interface specification.

Example usage:
% oracle -format=json -mode=callgraph code.google.com/p/go.tools/cmd/oracle

+ Tests, based on (small) golden files.

Overview:
  Each <query>Result structure has been "lowered" so that all
  but the most trivial logic in each display() function has
  been moved to the main query.

  Each one now has a toJSON method that populates a json.Result
  struct.  Though the <query>Result structs are similar to the
  correponding JSON protocol, they're not close enough to be
  used directly; for example, the former contain richer
  semantic entities (token.Pos, ast.Expr, ssa.Value,
  pointer.Pointer, etc) whereas JSON contains only their
  printed forms using Go basic types.

  The choices of what levels of abstractions the two sets of
  structs should have is somewhat arbitrary.  We may want
  richer information in the JSON output in future.

Details:
- oracle.Main has been split into oracle.Query() and the
  printing of the oracle.Result.
- the display() method no longer needs an *oracle param, only
  a print function.
- callees: sort the result for determinism.
- callees: compute the union across all contexts.
- callers: sort the results for determinism.
- describe(package): fixed a bug in the predicate for method
  accessibility: an unexported method defined in pkg A may
  belong to a type defined in package B (via
  embedding/promotion) and may thus be accessible to A.  New
  accessibleMethods() utility fixes this.
- describe(type): filter methods by accessibility.
- added tests of 'callgraph'.
- pointer: eliminated the 'caller CallGraphNode' parameter from
  pointer.Context.Call callback since it was redundant w.r.t
  site.Caller().
- added warning if CGO_ENABLED is unset.

R=crawshaw
CC=golang-dev
https://golang.org/cl/13270045
2013-09-03 15:29:02 -04:00
Alan Donovan
0126405cad go.tools/oracle: change -pos flag syntax from "file pos-pos" to file:pos-pos.
Pro: no shell quotation needed.
Con: can't be parsed by (the perpetually useless) Scanf.

R=crawshaw, dgryski
CC=golang-dev
https://golang.org/cl/13441043
2013-09-03 10:58:58 -04:00
Alan Donovan
a483497cf1 go.tools/oracle: address reviewer suggestions from CL 9502043
(I made these changes in the wrong workspace.)

R=crawshaw
CC=golang-dev
https://golang.org/cl/13328044
2013-08-29 21:36:59 -04:00
Rob Pike
1b67ef0078 go.tools/oracle: fix build on darwin
diff -u3: the 3 is redundant and an error on darwin; redundant and unnecessary on linux.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/13231044
2013-08-29 14:31:39 +10:00
Alex Brainman
7f887510d9 go.tools/oracle: disable TestOracle test on windows (fixes windows build)
windows does not have required /usr/bin/diff program

R=golang-dev, r
CC=adonovan, golang-dev
https://golang.org/cl/13353047
2013-08-29 14:04:05 +10:00
Alan Donovan
713699d8ad go.tools: add copyright messages to source files.
R=r
CC=golang-dev
https://golang.org/cl/13305043
2013-08-27 18:49:13 -04:00
Alan Donovan
e08d89f3ed go.tools/oracle: an oracle that answers questions about Go source code.
+ Tests.
+ Emacs integration.
+ Emacs integration test.
+ very rudimentary Vim integration.  Needs some love from a Vim user.

TODO (in follow-ups):
- More tests would be good.
  We'll need to make the output order deterministic in more places.
- Documentation.

R=gri, crawshaw, dominik.honnef
CC=golang-dev
https://golang.org/cl/9502043
2013-08-27 17:58:26 -04:00