internal/lsp: use new go/packages LoadMode to get TypesSizes

This change also fixes the corresponding code in go/packages, which was
actually not filling in the TypesSizes if the bit was set.

Change-Id: I2d5a849045768a81c94218eb41da2faec26189a3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/170010
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/go/packages/packages.go b/go/packages/packages.go
index 775dd94..36e54a3 100644
--- a/go/packages/packages.go
+++ b/go/packages/packages.go
@@ -554,6 +554,9 @@
 		if lpkg.needsrc {
 			srcPkgs = append(srcPkgs, lpkg)
 		}
+		if ld.Mode&NeedTypesSizes != 0 {
+			lpkg.TypesSizes = ld.sizes
+		}
 		stack = stack[:len(stack)-1] // pop
 		lpkg.color = black
 
diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go
index c70fec9..f49d871 100644
--- a/internal/lsp/cache/check.go
+++ b/internal/lsp/cache/check.go
@@ -92,7 +92,7 @@
 func (v *View) checkMetadata(ctx context.Context, f *File) ([]packages.Error, error) {
 	if v.reparseImports(ctx, f, f.filename) {
 		cfg := v.Config
-		cfg.Mode = packages.LoadImports
+		cfg.Mode = packages.LoadImports | packages.NeedTypesSizes
 		pkgs, err := packages.Load(&cfg, fmt.Sprintf("file=%s", f.filename))
 		if len(pkgs) == 0 {
 			if err == nil {
@@ -139,10 +139,11 @@
 	m, ok := v.mcache.packages[pkgPath]
 	if !ok {
 		m = &metadata{
-			pkgPath:  pkgPath,
-			id:       pkg.ID,
-			parents:  make(map[string]bool),
-			children: make(map[string]bool),
+			pkgPath:    pkgPath,
+			id:         pkg.ID,
+			typesSizes: pkg.TypesSizes,
+			parents:    make(map[string]bool),
+			children:   make(map[string]bool),
 		}
 		v.mcache.packages[pkgPath] = m
 	}
@@ -225,11 +226,12 @@
 		typ = types.NewPackage(meta.pkgPath, meta.name)
 	}
 	pkg := &Package{
-		id:      meta.id,
-		pkgPath: meta.pkgPath,
-		files:   meta.files,
-		imports: make(map[string]*Package),
-		types:   typ,
+		id:         meta.id,
+		pkgPath:    meta.pkgPath,
+		files:      meta.files,
+		imports:    make(map[string]*Package),
+		types:      typ,
+		typesSizes: meta.typesSizes,
 		typesInfo: &types.Info{
 			Types:      make(map[ast.Expr]types.TypeAndValue),
 			Defs:       make(map[*ast.Ident]types.Object),
diff --git a/internal/lsp/cache/pkg.go b/internal/lsp/cache/pkg.go
index 0a3c660..eb90209 100644
--- a/internal/lsp/cache/pkg.go
+++ b/internal/lsp/cache/pkg.go
@@ -21,6 +21,7 @@
 	imports     map[string]*Package
 	types       *types.Package
 	typesInfo   *types.Info
+	typesSizes  types.Sizes
 
 	// The analysis cache holds analysis information for all the packages in a view.
 	// Each graph node (action) is one unit of analysis.
@@ -118,6 +119,10 @@
 	return pkg.typesInfo
 }
 
+func (pkg *Package) GetTypesSizes() types.Sizes {
+	return pkg.typesSizes
+}
+
 func (pkg *Package) IsIllTyped() bool {
 	return pkg.types == nil && pkg.typesInfo == nil
 }
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index d0936f2..fb5e598 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -7,6 +7,7 @@
 import (
 	"context"
 	"go/token"
+	"go/types"
 	"os"
 	"sync"
 
@@ -64,6 +65,7 @@
 type metadata struct {
 	id, pkgPath, name string
 	files             []string
+	typesSizes        types.Sizes
 	parents, children map[string]bool
 }
 
diff --git a/internal/lsp/source/analysis.go b/internal/lsp/source/analysis.go
index 25f697a..6cf8df4 100644
--- a/internal/lsp/source/analysis.go
+++ b/internal/lsp/source/analysis.go
@@ -133,13 +133,12 @@
 
 	// Run the analysis.
 	pass := &analysis.Pass{
-		Analyzer:  act.Analyzer,
-		Fset:      fset,
-		Files:     act.Pkg.GetSyntax(),
-		Pkg:       act.Pkg.GetTypes(),
-		TypesInfo: act.Pkg.GetTypesInfo(),
-		// TODO(rstambler): Get real TypeSizes from go/packages (golang.org/issues/30139).
-		TypesSizes:        &types.StdSizes{},
+		Analyzer:          act.Analyzer,
+		Fset:              fset,
+		Files:             act.Pkg.GetSyntax(),
+		Pkg:               act.Pkg.GetTypes(),
+		TypesInfo:         act.Pkg.GetTypesInfo(),
+		TypesSizes:        act.Pkg.GetTypesSizes(),
 		ResultOf:          inputs,
 		Report:            func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
 		ImportObjectFact:  act.importObjectFact,
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index 54da56f..855fc2c 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -45,6 +45,7 @@
 	GetErrors() []packages.Error
 	GetTypes() *types.Package
 	GetTypesInfo() *types.Info
+	GetTypesSizes() types.Sizes
 	IsIllTyped() bool
 	GetActionGraph(ctx context.Context, a *analysis.Analyzer) (*Action, error)
 }