Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
774b6d48
Commit
774b6d48
authored
Apr 15, 2016
by
Mike Danese
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix the build
parent
ff1da767
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
0 additions
and
2276 deletions
+0
-2276
Godeps.json
Godeps/Godeps.json
+0
-8
LICENSES
Godeps/LICENSES
+0
-64
LICENSE
Godeps/_workspace/src/golang.org/x/tools/LICENSE
+0
-27
PATENTS
Godeps/_workspace/src/golang.org/x/tools/PATENTS
+0
-22
enclosing.go
...kspace/src/golang.org/x/tools/go/ast/astutil/enclosing.go
+0
-625
imports.go
...orkspace/src/golang.org/x/tools/go/ast/astutil/imports.go
+0
-359
util.go
.../_workspace/src/golang.org/x/tools/go/ast/astutil/util.go
+0
-14
fix.go
Godeps/_workspace/src/golang.org/x/tools/imports/fix.go
+0
-387
imports.go
Godeps/_workspace/src/golang.org/x/tools/imports/imports.go
+0
-279
mkindex.go
Godeps/_workspace/src/golang.org/x/tools/imports/mkindex.go
+0
-173
mkstdlib.go
Godeps/_workspace/src/golang.org/x/tools/imports/mkstdlib.go
+0
-90
sortimports.go
.../_workspace/src/golang.org/x/tools/imports/sortimports.go
+0
-214
sortimports_compat.go
...pace/src/golang.org/x/tools/imports/sortimports_compat.go
+0
-14
zstdlib.go
Godeps/_workspace/src/golang.org/x/tools/imports/zstdlib.go
+0
-0
No files found.
Godeps/Godeps.json
View file @
774b6d48
...
...
@@ -1079,14 +1079,6 @@
"Rev"
:
"833a04a10549a95dc34458c195cbad61bbb6cb4d"
},
{
"ImportPath"
:
"golang.org/x/tools/go/ast/astutil"
,
"Rev"
:
"4f50f44d7a3206e9e28b984e023efce2a4a75369"
},
{
"ImportPath"
:
"golang.org/x/tools/imports"
,
"Rev"
:
"4f50f44d7a3206e9e28b984e023efce2a4a75369"
},
{
"ImportPath"
:
"google.golang.org/api/cloudmonitoring/v2beta2"
,
"Rev"
:
"77e7d383beb96054547729f49c372b3d01e196ff"
},
...
...
Godeps/LICENSES
View file @
774b6d48
...
...
@@ -36532,70 +36532,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
= Godeps/_workspace/src/golang.org/x/tools/go/ast/astutil licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
= Godeps/_workspace/src/golang.org/x/tools/imports licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
= Godeps/_workspace/src/google.golang.org/api/cloudmonitoring/v2beta2 licensed under: =
Copyright (c) 2011 Google Inc. All rights reserved.
Godeps/_workspace/src/golang.org/x/tools/LICENSE
deleted
100644 → 0
View file @
ff1da767
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Godeps/_workspace/src/golang.org/x/tools/PATENTS
deleted
100644 → 0
View file @
ff1da767
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.
Godeps/_workspace/src/golang.org/x/tools/go/ast/astutil/enclosing.go
deleted
100644 → 0
View file @
ff1da767
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
astutil
// This file defines utilities for working with source positions.
import
(
"fmt"
"go/ast"
"go/token"
"sort"
)
// PathEnclosingInterval returns the node that encloses the source
// interval [start, end), and all its ancestors up to the AST root.
//
// The definition of "enclosing" used by this function considers
// additional whitespace abutting a node to be enclosed by it.
// In this example:
//
// z := x + y // add them
// <-A->
// <----B----->
//
// the ast.BinaryExpr(+) node is considered to enclose interval B
// even though its [Pos()..End()) is actually only interval A.
// This behaviour makes user interfaces more tolerant of imperfect
// input.
//
// This function treats tokens as nodes, though they are not included
// in the result. e.g. PathEnclosingInterval("+") returns the
// enclosing ast.BinaryExpr("x + y").
//
// If start==end, the 1-char interval following start is used instead.
//
// The 'exact' result is true if the interval contains only path[0]
// and perhaps some adjacent whitespace. It is false if the interval
// overlaps multiple children of path[0], or if it contains only
// interior whitespace of path[0].
// In this example:
//
// z := x + y // add them
// <--C--> <---E-->
// ^
// D
//
// intervals C, D and E are inexact. C is contained by the
// z-assignment statement, because it spans three of its children (:=,
// x, +). So too is the 1-char interval D, because it contains only
// interior whitespace of the assignment. E is considered interior
// whitespace of the BlockStmt containing the assignment.
//
// Precondition: [start, end) both lie within the same file as root.
// TODO(adonovan): return (nil, false) in this case and remove precond.
// Requires FileSet; see loader.tokenFileContainsPos.
//
// Postcondition: path is never nil; it always contains at least 'root'.
//
func
PathEnclosingInterval
(
root
*
ast
.
File
,
start
,
end
token
.
Pos
)
(
path
[]
ast
.
Node
,
exact
bool
)
{
// fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
// Precondition: node.[Pos..End) and adjoining whitespace contain [start, end).
var
visit
func
(
node
ast
.
Node
)
bool
visit
=
func
(
node
ast
.
Node
)
bool
{
path
=
append
(
path
,
node
)
nodePos
:=
node
.
Pos
()
nodeEnd
:=
node
.
End
()
// fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging
// Intersect [start, end) with interval of node.
if
start
<
nodePos
{
start
=
nodePos
}
if
end
>
nodeEnd
{
end
=
nodeEnd
}
// Find sole child that contains [start, end).
children
:=
childrenOf
(
node
)
l
:=
len
(
children
)
for
i
,
child
:=
range
children
{
// [childPos, childEnd) is unaugmented interval of child.
childPos
:=
child
.
Pos
()
childEnd
:=
child
.
End
()
// [augPos, augEnd) is whitespace-augmented interval of child.
augPos
:=
childPos
augEnd
:=
childEnd
if
i
>
0
{
augPos
=
children
[
i
-
1
]
.
End
()
// start of preceding whitespace
}
if
i
<
l
-
1
{
nextChildPos
:=
children
[
i
+
1
]
.
Pos
()
// Does [start, end) lie between child and next child?
if
start
>=
augEnd
&&
end
<=
nextChildPos
{
return
false
// inexact match
}
augEnd
=
nextChildPos
// end of following whitespace
}
// fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n",
// i, augPos, augEnd, start, end) // debugging
// Does augmented child strictly contain [start, end)?
if
augPos
<=
start
&&
end
<=
augEnd
{
_
,
isToken
:=
child
.
(
tokenNode
)
return
isToken
||
visit
(
child
)
}
// Does [start, end) overlap multiple children?
// i.e. left-augmented child contains start
// but LR-augmented child does not contain end.
if
start
<
childEnd
&&
end
>
augEnd
{
break
}
}
// No single child contained [start, end),
// so node is the result. Is it exact?
// (It's tempting to put this condition before the
// child loop, but it gives the wrong result in the
// case where a node (e.g. ExprStmt) and its sole
// child have equal intervals.)
if
start
==
nodePos
&&
end
==
nodeEnd
{
return
true
// exact match
}
return
false
// inexact: overlaps multiple children
}
if
start
>
end
{
start
,
end
=
end
,
start
}
if
start
<
root
.
End
()
&&
end
>
root
.
Pos
()
{
if
start
==
end
{
end
=
start
+
1
// empty interval => interval of size 1
}
exact
=
visit
(
root
)
// Reverse the path:
for
i
,
l
:=
0
,
len
(
path
);
i
<
l
/
2
;
i
++
{
path
[
i
],
path
[
l
-
1
-
i
]
=
path
[
l
-
1
-
i
],
path
[
i
]
}
}
else
{
// Selection lies within whitespace preceding the
// first (or following the last) declaration in the file.
// The result nonetheless always includes the ast.File.
path
=
append
(
path
,
root
)
}
return
}
// tokenNode is a dummy implementation of ast.Node for a single token.
// They are used transiently by PathEnclosingInterval but never escape
// this package.
//
type
tokenNode
struct
{
pos
token
.
Pos
end
token
.
Pos
}
func
(
n
tokenNode
)
Pos
()
token
.
Pos
{
return
n
.
pos
}
func
(
n
tokenNode
)
End
()
token
.
Pos
{
return
n
.
end
}
func
tok
(
pos
token
.
Pos
,
len
int
)
ast
.
Node
{
return
tokenNode
{
pos
,
pos
+
token
.
Pos
(
len
)}
}
// childrenOf returns the direct non-nil children of ast.Node n.
// It may include fake ast.Node implementations for bare tokens.
// it is not safe to call (e.g.) ast.Walk on such nodes.
//
func
childrenOf
(
n
ast
.
Node
)
[]
ast
.
Node
{
var
children
[]
ast
.
Node
// First add nodes for all true subtrees.
ast
.
Inspect
(
n
,
func
(
node
ast
.
Node
)
bool
{
if
node
==
n
{
// push n
return
true
// recur
}
if
node
!=
nil
{
// push child
children
=
append
(
children
,
node
)
}
return
false
// no recursion
})
// Then add fake Nodes for bare tokens.
switch
n
:=
n
.
(
type
)
{
case
*
ast
.
ArrayType
:
children
=
append
(
children
,
tok
(
n
.
Lbrack
,
len
(
"["
)),
tok
(
n
.
Elt
.
End
(),
len
(
"]"
)))
case
*
ast
.
AssignStmt
:
children
=
append
(
children
,
tok
(
n
.
TokPos
,
len
(
n
.
Tok
.
String
())))
case
*
ast
.
BasicLit
:
children
=
append
(
children
,
tok
(
n
.
ValuePos
,
len
(
n
.
Value
)))
case
*
ast
.
BinaryExpr
:
children
=
append
(
children
,
tok
(
n
.
OpPos
,
len
(
n
.
Op
.
String
())))
case
*
ast
.
BlockStmt
:
children
=
append
(
children
,
tok
(
n
.
Lbrace
,
len
(
"{"
)),
tok
(
n
.
Rbrace
,
len
(
"}"
)))
case
*
ast
.
BranchStmt
:
children
=
append
(
children
,
tok
(
n
.
TokPos
,
len
(
n
.
Tok
.
String
())))
case
*
ast
.
CallExpr
:
children
=
append
(
children
,
tok
(
n
.
Lparen
,
len
(
"("
)),
tok
(
n
.
Rparen
,
len
(
")"
)))
if
n
.
Ellipsis
!=
0
{
children
=
append
(
children
,
tok
(
n
.
Ellipsis
,
len
(
"..."
)))
}
case
*
ast
.
CaseClause
:
if
n
.
List
==
nil
{
children
=
append
(
children
,
tok
(
n
.
Case
,
len
(
"default"
)))
}
else
{
children
=
append
(
children
,
tok
(
n
.
Case
,
len
(
"case"
)))
}
children
=
append
(
children
,
tok
(
n
.
Colon
,
len
(
":"
)))
case
*
ast
.
ChanType
:
switch
n
.
Dir
{
case
ast
.
RECV
:
children
=
append
(
children
,
tok
(
n
.
Begin
,
len
(
"<-chan"
)))
case
ast
.
SEND
:
children
=
append
(
children
,
tok
(
n
.
Begin
,
len
(
"chan<-"
)))
case
ast
.
RECV
|
ast
.
SEND
:
children
=
append
(
children
,
tok
(
n
.
Begin
,
len
(
"chan"
)))
}
case
*
ast
.
CommClause
:
if
n
.
Comm
==
nil
{
children
=
append
(
children
,
tok
(
n
.
Case
,
len
(
"default"
)))
}
else
{
children
=
append
(
children
,
tok
(
n
.
Case
,
len
(
"case"
)))
}
children
=
append
(
children
,
tok
(
n
.
Colon
,
len
(
":"
)))
case
*
ast
.
Comment
:
// nop
case
*
ast
.
CommentGroup
:
// nop
case
*
ast
.
CompositeLit
:
children
=
append
(
children
,
tok
(
n
.
Lbrace
,
len
(
"{"
)),
tok
(
n
.
Rbrace
,
len
(
"{"
)))
case
*
ast
.
DeclStmt
:
// nop
case
*
ast
.
DeferStmt
:
children
=
append
(
children
,
tok
(
n
.
Defer
,
len
(
"defer"
)))
case
*
ast
.
Ellipsis
:
children
=
append
(
children
,
tok
(
n
.
Ellipsis
,
len
(
"..."
)))
case
*
ast
.
EmptyStmt
:
// nop
case
*
ast
.
ExprStmt
:
// nop
case
*
ast
.
Field
:
// TODO(adonovan): Field.{Doc,Comment,Tag}?
case
*
ast
.
FieldList
:
children
=
append
(
children
,
tok
(
n
.
Opening
,
len
(
"("
)),
tok
(
n
.
Closing
,
len
(
")"
)))
case
*
ast
.
File
:
// TODO test: Doc
children
=
append
(
children
,
tok
(
n
.
Package
,
len
(
"package"
)))
case
*
ast
.
ForStmt
:
children
=
append
(
children
,
tok
(
n
.
For
,
len
(
"for"
)))
case
*
ast
.
FuncDecl
:
// TODO(adonovan): FuncDecl.Comment?
// Uniquely, FuncDecl breaks the invariant that
// preorder traversal yields tokens in lexical order:
// in fact, FuncDecl.Recv precedes FuncDecl.Type.Func.
//
// As a workaround, we inline the case for FuncType
// here and order things correctly.
//
children
=
nil
// discard ast.Walk(FuncDecl) info subtrees
children
=
append
(
children
,
tok
(
n
.
Type
.
Func
,
len
(
"func"
)))
if
n
.
Recv
!=
nil
{
children
=
append
(
children
,
n
.
Recv
)
}
children
=
append
(
children
,
n
.
Name
)
if
n
.
Type
.
Params
!=
nil
{
children
=
append
(
children
,
n
.
Type
.
Params
)
}
if
n
.
Type
.
Results
!=
nil
{
children
=
append
(
children
,
n
.
Type
.
Results
)
}
if
n
.
Body
!=
nil
{
children
=
append
(
children
,
n
.
Body
)
}
case
*
ast
.
FuncLit
:
// nop
case
*
ast
.
FuncType
:
if
n
.
Func
!=
0
{
children
=
append
(
children
,
tok
(
n
.
Func
,
len
(
"func"
)))
}
case
*
ast
.
GenDecl
:
children
=
append
(
children
,
tok
(
n
.
TokPos
,
len
(
n
.
Tok
.
String
())))
if
n
.
Lparen
!=
0
{
children
=
append
(
children
,
tok
(
n
.
Lparen
,
len
(
"("
)),
tok
(
n
.
Rparen
,
len
(
")"
)))
}
case
*
ast
.
GoStmt
:
children
=
append
(
children
,
tok
(
n
.
Go
,
len
(
"go"
)))
case
*
ast
.
Ident
:
children
=
append
(
children
,
tok
(
n
.
NamePos
,
len
(
n
.
Name
)))
case
*
ast
.
IfStmt
:
children
=
append
(
children
,
tok
(
n
.
If
,
len
(
"if"
)))
case
*
ast
.
ImportSpec
:
// TODO(adonovan): ImportSpec.{Doc,EndPos}?
case
*
ast
.
IncDecStmt
:
children
=
append
(
children
,
tok
(
n
.
TokPos
,
len
(
n
.
Tok
.
String
())))
case
*
ast
.
IndexExpr
:
children
=
append
(
children
,
tok
(
n
.
Lbrack
,
len
(
"{"
)),
tok
(
n
.
Rbrack
,
len
(
"}"
)))
case
*
ast
.
InterfaceType
:
children
=
append
(
children
,
tok
(
n
.
Interface
,
len
(
"interface"
)))
case
*
ast
.
KeyValueExpr
:
children
=
append
(
children
,
tok
(
n
.
Colon
,
len
(
":"
)))
case
*
ast
.
LabeledStmt
:
children
=
append
(
children
,
tok
(
n
.
Colon
,
len
(
":"
)))
case
*
ast
.
MapType
:
children
=
append
(
children
,
tok
(
n
.
Map
,
len
(
"map"
)))
case
*
ast
.
ParenExpr
:
children
=
append
(
children
,
tok
(
n
.
Lparen
,
len
(
"("
)),
tok
(
n
.
Rparen
,
len
(
")"
)))
case
*
ast
.
RangeStmt
:
children
=
append
(
children
,
tok
(
n
.
For
,
len
(
"for"
)),
tok
(
n
.
TokPos
,
len
(
n
.
Tok
.
String
())))
case
*
ast
.
ReturnStmt
:
children
=
append
(
children
,
tok
(
n
.
Return
,
len
(
"return"
)))
case
*
ast
.
SelectStmt
:
children
=
append
(
children
,
tok
(
n
.
Select
,
len
(
"select"
)))
case
*
ast
.
SelectorExpr
:
// nop
case
*
ast
.
SendStmt
:
children
=
append
(
children
,
tok
(
n
.
Arrow
,
len
(
"<-"
)))
case
*
ast
.
SliceExpr
:
children
=
append
(
children
,
tok
(
n
.
Lbrack
,
len
(
"["
)),
tok
(
n
.
Rbrack
,
len
(
"]"
)))
case
*
ast
.
StarExpr
:
children
=
append
(
children
,
tok
(
n
.
Star
,
len
(
"*"
)))
case
*
ast
.
StructType
:
children
=
append
(
children
,
tok
(
n
.
Struct
,
len
(
"struct"
)))
case
*
ast
.
SwitchStmt
:
children
=
append
(
children
,
tok
(
n
.
Switch
,
len
(
"switch"
)))
case
*
ast
.
TypeAssertExpr
:
children
=
append
(
children
,
tok
(
n
.
Lparen
-
1
,
len
(
"."
)),
tok
(
n
.
Lparen
,
len
(
"("
)),
tok
(
n
.
Rparen
,
len
(
")"
)))
case
*
ast
.
TypeSpec
:
// TODO(adonovan): TypeSpec.{Doc,Comment}?
case
*
ast
.
TypeSwitchStmt
:
children
=
append
(
children
,
tok
(
n
.
Switch
,
len
(
"switch"
)))
case
*
ast
.
UnaryExpr
:
children
=
append
(
children
,
tok
(
n
.
OpPos
,
len
(
n
.
Op
.
String
())))
case
*
ast
.
ValueSpec
:
// TODO(adonovan): ValueSpec.{Doc,Comment}?
default
:
// Includes *ast.BadDecl, *ast.BadExpr, *ast.BadStmt.
panic
(
fmt
.
Sprintf
(
"unexpected node type %T"
,
n
))
}
// TODO(adonovan): opt: merge the logic of ast.Inspect() into
// the switch above so we can make interleaved callbacks for
// both Nodes and Tokens in the right order and avoid the need
// to sort.
sort
.
Sort
(
byPos
(
children
))
return
children
}
type
byPos
[]
ast
.
Node
func
(
sl
byPos
)
Len
()
int
{
return
len
(
sl
)
}
func
(
sl
byPos
)
Less
(
i
,
j
int
)
bool
{
return
sl
[
i
]
.
Pos
()
<
sl
[
j
]
.
Pos
()
}
func
(
sl
byPos
)
Swap
(
i
,
j
int
)
{
sl
[
i
],
sl
[
j
]
=
sl
[
j
],
sl
[
i
]
}
// NodeDescription returns a description of the concrete type of n suitable
// for a user interface.
//
// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
// StarExpr) we could be much more specific given the path to the AST
// root. Perhaps we should do that.
//
func
NodeDescription
(
n
ast
.
Node
)
string
{
switch
n
:=
n
.
(
type
)
{
case
*
ast
.
ArrayType
:
return
"array type"
case
*
ast
.
AssignStmt
:
return
"assignment"
case
*
ast
.
BadDecl
:
return
"bad declaration"
case
*
ast
.
BadExpr
:
return
"bad expression"
case
*
ast
.
BadStmt
:
return
"bad statement"
case
*
ast
.
BasicLit
:
return
"basic literal"
case
*
ast
.
BinaryExpr
:
return
fmt
.
Sprintf
(
"binary %s operation"
,
n
.
Op
)
case
*
ast
.
BlockStmt
:
return
"block"
case
*
ast
.
BranchStmt
:
switch
n
.
Tok
{
case
token
.
BREAK
:
return
"break statement"
case
token
.
CONTINUE
:
return
"continue statement"
case
token
.
GOTO
:
return
"goto statement"
case
token
.
FALLTHROUGH
:
return
"fall-through statement"
}
case
*
ast
.
CallExpr
:
return
"function call (or conversion)"
case
*
ast
.
CaseClause
:
return
"case clause"
case
*
ast
.
ChanType
:
return
"channel type"
case
*
ast
.
CommClause
:
return
"communication clause"
case
*
ast
.
Comment
:
return
"comment"
case
*
ast
.
CommentGroup
:
return
"comment group"
case
*
ast
.
CompositeLit
:
return
"composite literal"
case
*
ast
.
DeclStmt
:
return
NodeDescription
(
n
.
Decl
)
+
" statement"
case
*
ast
.
DeferStmt
:
return
"defer statement"
case
*
ast
.
Ellipsis
:
return
"ellipsis"
case
*
ast
.
EmptyStmt
:
return
"empty statement"
case
*
ast
.
ExprStmt
:
return
"expression statement"
case
*
ast
.
Field
:
// Can be any of these:
// struct {x, y int} -- struct field(s)
// struct {T} -- anon struct field
// interface {I} -- interface embedding
// interface {f()} -- interface method
// func (A) func(B) C -- receiver, param(s), result(s)
return
"field/method/parameter"
case
*
ast
.
FieldList
:
return
"field/method/parameter list"
case
*
ast
.
File
:
return
"source file"
case
*
ast
.
ForStmt
:
return
"for loop"
case
*
ast
.
FuncDecl
:
return
"function declaration"
case
*
ast
.
FuncLit
:
return
"function literal"
case
*
ast
.
FuncType
:
return
"function type"
case
*
ast
.
GenDecl
:
switch
n
.
Tok
{
case
token
.
IMPORT
:
return
"import declaration"
case
token
.
CONST
:
return
"constant declaration"
case
token
.
TYPE
:
return
"type declaration"
case
token
.
VAR
:
return
"variable declaration"
}
case
*
ast
.
GoStmt
:
return
"go statement"
case
*
ast
.
Ident
:
return
"identifier"
case
*
ast
.
IfStmt
:
return
"if statement"
case
*
ast
.
ImportSpec
:
return
"import specification"
case
*
ast
.
IncDecStmt
:
if
n
.
Tok
==
token
.
INC
{
return
"increment statement"
}
return
"decrement statement"
case
*
ast
.
IndexExpr
:
return
"index expression"
case
*
ast
.
InterfaceType
:
return
"interface type"
case
*
ast
.
KeyValueExpr
:
return
"key/value association"
case
*
ast
.
LabeledStmt
:
return
"statement label"
case
*
ast
.
MapType
:
return
"map type"
case
*
ast
.
Package
:
return
"package"
case
*
ast
.
ParenExpr
:
return
"parenthesized "
+
NodeDescription
(
n
.
X
)
case
*
ast
.
RangeStmt
:
return
"range loop"
case
*
ast
.
ReturnStmt
:
return
"return statement"
case
*
ast
.
SelectStmt
:
return
"select statement"
case
*
ast
.
SelectorExpr
:
return
"selector"
case
*
ast
.
SendStmt
:
return
"channel send"
case
*
ast
.
SliceExpr
:
return
"slice expression"
case
*
ast
.
StarExpr
:
return
"*-operation"
// load/store expr or pointer type
case
*
ast
.
StructType
:
return
"struct type"
case
*
ast
.
SwitchStmt
:
return
"switch statement"
case
*
ast
.
TypeAssertExpr
:
return
"type assertion"
case
*
ast
.
TypeSpec
:
return
"type specification"
case
*
ast
.
TypeSwitchStmt
:
return
"type switch"
case
*
ast
.
UnaryExpr
:
return
fmt
.
Sprintf
(
"unary %s operation"
,
n
.
Op
)
case
*
ast
.
ValueSpec
:
return
"value specification"
}
panic
(
fmt
.
Sprintf
(
"unexpected node type: %T"
,
n
))
}
Godeps/_workspace/src/golang.org/x/tools/go/ast/astutil/imports.go
deleted
100644 → 0
View file @
ff1da767
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package astutil contains common utilities for working with the Go AST.
package
astutil
import
(
"fmt"
"go/ast"
"go/token"
"strconv"
"strings"
)
// AddImport adds the import path to the file f, if absent.
func
AddImport
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
,
ipath
string
)
(
added
bool
)
{
return
AddNamedImport
(
fset
,
f
,
""
,
ipath
)
}
// AddNamedImport adds the import path to the file f, if absent.
// If name is not empty, it is used to rename the import.
//
// For example, calling
// AddNamedImport(fset, f, "pathpkg", "path")
// adds
// import pathpkg "path"
func
AddNamedImport
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
,
name
,
ipath
string
)
(
added
bool
)
{
if
imports
(
f
,
ipath
)
{
return
false
}
newImport
:=
&
ast
.
ImportSpec
{
Path
:
&
ast
.
BasicLit
{
Kind
:
token
.
STRING
,
Value
:
strconv
.
Quote
(
ipath
),
},
}
if
name
!=
""
{
newImport
.
Name
=
&
ast
.
Ident
{
Name
:
name
}
}
// Find an import decl to add to.
// The goal is to find an existing import
// whose import path has the longest shared
// prefix with ipath.
var
(
bestMatch
=
-
1
// length of longest shared prefix
lastImport
=
-
1
// index in f.Decls of the file's final import decl
impDecl
*
ast
.
GenDecl
// import decl containing the best match
impIndex
=
-
1
// spec index in impDecl containing the best match
)
for
i
,
decl
:=
range
f
.
Decls
{
gen
,
ok
:=
decl
.
(
*
ast
.
GenDecl
)
if
ok
&&
gen
.
Tok
==
token
.
IMPORT
{
lastImport
=
i
// Do not add to import "C", to avoid disrupting the
// association with its doc comment, breaking cgo.
if
declImports
(
gen
,
"C"
)
{
continue
}
// Match an empty import decl if that's all that is available.
if
len
(
gen
.
Specs
)
==
0
&&
bestMatch
==
-
1
{
impDecl
=
gen
}
// Compute longest shared prefix with imports in this group.
for
j
,
spec
:=
range
gen
.
Specs
{
impspec
:=
spec
.
(
*
ast
.
ImportSpec
)
n
:=
matchLen
(
importPath
(
impspec
),
ipath
)
if
n
>
bestMatch
{
bestMatch
=
n
impDecl
=
gen
impIndex
=
j
}
}
}
}
// If no import decl found, add one after the last import.
if
impDecl
==
nil
{
impDecl
=
&
ast
.
GenDecl
{
Tok
:
token
.
IMPORT
,
}
if
lastImport
>=
0
{
impDecl
.
TokPos
=
f
.
Decls
[
lastImport
]
.
End
()
}
else
{
// There are no existing imports.
// Our new import goes after the package declaration and after
// the comment, if any, that starts on the same line as the
// package declaration.
impDecl
.
TokPos
=
f
.
Package
file
:=
fset
.
File
(
f
.
Package
)
pkgLine
:=
file
.
Line
(
f
.
Package
)
for
_
,
c
:=
range
f
.
Comments
{
if
file
.
Line
(
c
.
Pos
())
>
pkgLine
{
break
}
impDecl
.
TokPos
=
c
.
End
()
}
}
f
.
Decls
=
append
(
f
.
Decls
,
nil
)
copy
(
f
.
Decls
[
lastImport
+
2
:
],
f
.
Decls
[
lastImport
+
1
:
])
f
.
Decls
[
lastImport
+
1
]
=
impDecl
}
// Insert new import at insertAt.
insertAt
:=
0
if
impIndex
>=
0
{
// insert after the found import
insertAt
=
impIndex
+
1
}
impDecl
.
Specs
=
append
(
impDecl
.
Specs
,
nil
)
copy
(
impDecl
.
Specs
[
insertAt
+
1
:
],
impDecl
.
Specs
[
insertAt
:
])
impDecl
.
Specs
[
insertAt
]
=
newImport
pos
:=
impDecl
.
Pos
()
if
insertAt
>
0
{
// Assign same position as the previous import,
// so that the sorter sees it as being in the same block.
pos
=
impDecl
.
Specs
[
insertAt
-
1
]
.
Pos
()
}
if
newImport
.
Name
!=
nil
{
newImport
.
Name
.
NamePos
=
pos
}
newImport
.
Path
.
ValuePos
=
pos
newImport
.
EndPos
=
pos
// Clean up parens. impDecl contains at least one spec.
if
len
(
impDecl
.
Specs
)
==
1
{
// Remove unneeded parens.
impDecl
.
Lparen
=
token
.
NoPos
}
else
if
!
impDecl
.
Lparen
.
IsValid
()
{
// impDecl needs parens added.
impDecl
.
Lparen
=
impDecl
.
Specs
[
0
]
.
Pos
()
}
f
.
Imports
=
append
(
f
.
Imports
,
newImport
)
return
true
}
// DeleteImport deletes the import path from the file f, if present.
func
DeleteImport
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
,
path
string
)
(
deleted
bool
)
{
var
delspecs
[]
*
ast
.
ImportSpec
// Find the import nodes that import path, if any.
for
i
:=
0
;
i
<
len
(
f
.
Decls
);
i
++
{
decl
:=
f
.
Decls
[
i
]
gen
,
ok
:=
decl
.
(
*
ast
.
GenDecl
)
if
!
ok
||
gen
.
Tok
!=
token
.
IMPORT
{
continue
}
for
j
:=
0
;
j
<
len
(
gen
.
Specs
);
j
++
{
spec
:=
gen
.
Specs
[
j
]
impspec
:=
spec
.
(
*
ast
.
ImportSpec
)
if
importPath
(
impspec
)
!=
path
{
continue
}
// We found an import spec that imports path.
// Delete it.
delspecs
=
append
(
delspecs
,
impspec
)
deleted
=
true
copy
(
gen
.
Specs
[
j
:
],
gen
.
Specs
[
j
+
1
:
])
gen
.
Specs
=
gen
.
Specs
[
:
len
(
gen
.
Specs
)
-
1
]
// If this was the last import spec in this decl,
// delete the decl, too.
if
len
(
gen
.
Specs
)
==
0
{
copy
(
f
.
Decls
[
i
:
],
f
.
Decls
[
i
+
1
:
])
f
.
Decls
=
f
.
Decls
[
:
len
(
f
.
Decls
)
-
1
]
i
--
break
}
else
if
len
(
gen
.
Specs
)
==
1
{
gen
.
Lparen
=
token
.
NoPos
// drop parens
}
if
j
>
0
{
lastImpspec
:=
gen
.
Specs
[
j
-
1
]
.
(
*
ast
.
ImportSpec
)
lastLine
:=
fset
.
Position
(
lastImpspec
.
Path
.
ValuePos
)
.
Line
line
:=
fset
.
Position
(
impspec
.
Path
.
ValuePos
)
.
Line
// We deleted an entry but now there may be
// a blank line-sized hole where the import was.
if
line
-
lastLine
>
1
{
// There was a blank line immediately preceding the deleted import,
// so there's no need to close the hole.
// Do nothing.
}
else
{
// There was no blank line. Close the hole.
fset
.
File
(
gen
.
Rparen
)
.
MergeLine
(
line
)
}
}
j
--
}
}
// Delete them from f.Imports.
for
i
:=
0
;
i
<
len
(
f
.
Imports
);
i
++
{
imp
:=
f
.
Imports
[
i
]
for
j
,
del
:=
range
delspecs
{
if
imp
==
del
{
copy
(
f
.
Imports
[
i
:
],
f
.
Imports
[
i
+
1
:
])
f
.
Imports
=
f
.
Imports
[
:
len
(
f
.
Imports
)
-
1
]
copy
(
delspecs
[
j
:
],
delspecs
[
j
+
1
:
])
delspecs
=
delspecs
[
:
len
(
delspecs
)
-
1
]
i
--
break
}
}
}
if
len
(
delspecs
)
>
0
{
panic
(
fmt
.
Sprintf
(
"deleted specs from Decls but not Imports: %v"
,
delspecs
))
}
return
}
// RewriteImport rewrites any import of path oldPath to path newPath.
func
RewriteImport
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
,
oldPath
,
newPath
string
)
(
rewrote
bool
)
{
for
_
,
imp
:=
range
f
.
Imports
{
if
importPath
(
imp
)
==
oldPath
{
rewrote
=
true
// record old End, because the default is to compute
// it using the length of imp.Path.Value.
imp
.
EndPos
=
imp
.
End
()
imp
.
Path
.
Value
=
strconv
.
Quote
(
newPath
)
}
}
return
}
// UsesImport reports whether a given import is used.
func
UsesImport
(
f
*
ast
.
File
,
path
string
)
(
used
bool
)
{
spec
:=
importSpec
(
f
,
path
)
if
spec
==
nil
{
return
}
name
:=
spec
.
Name
.
String
()
switch
name
{
case
"<nil>"
:
// If the package name is not explicitly specified,
// make an educated guess. This is not guaranteed to be correct.
lastSlash
:=
strings
.
LastIndex
(
path
,
"/"
)
if
lastSlash
==
-
1
{
name
=
path
}
else
{
name
=
path
[
lastSlash
+
1
:
]
}
case
"_"
,
"."
:
// Not sure if this import is used - err on the side of caution.
return
true
}
ast
.
Walk
(
visitFn
(
func
(
n
ast
.
Node
)
{
sel
,
ok
:=
n
.
(
*
ast
.
SelectorExpr
)
if
ok
&&
isTopName
(
sel
.
X
,
name
)
{
used
=
true
}
}),
f
)
return
}
type
visitFn
func
(
node
ast
.
Node
)
func
(
fn
visitFn
)
Visit
(
node
ast
.
Node
)
ast
.
Visitor
{
fn
(
node
)
return
fn
}
// imports returns true if f imports path.
func
imports
(
f
*
ast
.
File
,
path
string
)
bool
{
return
importSpec
(
f
,
path
)
!=
nil
}
// importSpec returns the import spec if f imports path,
// or nil otherwise.
func
importSpec
(
f
*
ast
.
File
,
path
string
)
*
ast
.
ImportSpec
{
for
_
,
s
:=
range
f
.
Imports
{
if
importPath
(
s
)
==
path
{
return
s
}
}
return
nil
}
// importPath returns the unquoted import path of s,
// or "" if the path is not properly quoted.
func
importPath
(
s
*
ast
.
ImportSpec
)
string
{
t
,
err
:=
strconv
.
Unquote
(
s
.
Path
.
Value
)
if
err
==
nil
{
return
t
}
return
""
}
// declImports reports whether gen contains an import of path.
func
declImports
(
gen
*
ast
.
GenDecl
,
path
string
)
bool
{
if
gen
.
Tok
!=
token
.
IMPORT
{
return
false
}
for
_
,
spec
:=
range
gen
.
Specs
{
impspec
:=
spec
.
(
*
ast
.
ImportSpec
)
if
importPath
(
impspec
)
==
path
{
return
true
}
}
return
false
}
// matchLen returns the length of the longest path segment prefix shared by x and y.
func
matchLen
(
x
,
y
string
)
int
{
n
:=
0
for
i
:=
0
;
i
<
len
(
x
)
&&
i
<
len
(
y
)
&&
x
[
i
]
==
y
[
i
];
i
++
{
if
x
[
i
]
==
'/'
{
n
++
}
}
return
n
}
// isTopName returns true if n is a top-level unresolved identifier with the given name.
func
isTopName
(
n
ast
.
Expr
,
name
string
)
bool
{
id
,
ok
:=
n
.
(
*
ast
.
Ident
)
return
ok
&&
id
.
Name
==
name
&&
id
.
Obj
==
nil
}
// Imports returns the file imports grouped by paragraph.
func
Imports
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
)
[][]
*
ast
.
ImportSpec
{
var
groups
[][]
*
ast
.
ImportSpec
for
_
,
decl
:=
range
f
.
Decls
{
genDecl
,
ok
:=
decl
.
(
*
ast
.
GenDecl
)
if
!
ok
||
genDecl
.
Tok
!=
token
.
IMPORT
{
break
}
group
:=
[]
*
ast
.
ImportSpec
{}
var
lastLine
int
for
_
,
spec
:=
range
genDecl
.
Specs
{
importSpec
:=
spec
.
(
*
ast
.
ImportSpec
)
pos
:=
importSpec
.
Path
.
ValuePos
line
:=
fset
.
Position
(
pos
)
.
Line
if
lastLine
>
0
&&
pos
>
0
&&
line
-
lastLine
>
1
{
groups
=
append
(
groups
,
group
)
group
=
[]
*
ast
.
ImportSpec
{}
}
group
=
append
(
group
,
importSpec
)
lastLine
=
line
}
groups
=
append
(
groups
,
group
)
}
return
groups
}
Godeps/_workspace/src/golang.org/x/tools/go/ast/astutil/util.go
deleted
100644 → 0
View file @
ff1da767
package
astutil
import
"go/ast"
// Unparen returns e with any enclosing parentheses stripped.
func
Unparen
(
e
ast
.
Expr
)
ast
.
Expr
{
for
{
p
,
ok
:=
e
.
(
*
ast
.
ParenExpr
)
if
!
ok
{
return
e
}
e
=
p
.
X
}
}
Godeps/_workspace/src/golang.org/x/tools/imports/fix.go
deleted
100644 → 0
View file @
ff1da767
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
imports
import
(
"fmt"
"go/ast"
"go/build"
"go/parser"
"go/token"
"os"
"path"
"path/filepath"
"strings"
"sync"
"golang.org/x/tools/go/ast/astutil"
)
// importToGroup is a list of functions which map from an import path to
// a group number.
var
importToGroup
=
[]
func
(
importPath
string
)
(
num
int
,
ok
bool
){
func
(
importPath
string
)
(
num
int
,
ok
bool
)
{
if
strings
.
HasPrefix
(
importPath
,
"appengine"
)
{
return
2
,
true
}
return
},
func
(
importPath
string
)
(
num
int
,
ok
bool
)
{
if
strings
.
Contains
(
importPath
,
"."
)
{
return
1
,
true
}
return
},
}
func
importGroup
(
importPath
string
)
int
{
for
_
,
fn
:=
range
importToGroup
{
if
n
,
ok
:=
fn
(
importPath
);
ok
{
return
n
}
}
return
0
}
func
fixImports
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
)
(
added
[]
string
,
err
error
)
{
// refs are a set of possible package references currently unsatisfied by imports.
// first key: either base package (e.g. "fmt") or renamed package
// second key: referenced package symbol (e.g. "Println")
refs
:=
make
(
map
[
string
]
map
[
string
]
bool
)
// decls are the current package imports. key is base package or renamed package.
decls
:=
make
(
map
[
string
]
*
ast
.
ImportSpec
)
// collect potential uses of packages.
var
visitor
visitFn
visitor
=
visitFn
(
func
(
node
ast
.
Node
)
ast
.
Visitor
{
if
node
==
nil
{
return
visitor
}
switch
v
:=
node
.
(
type
)
{
case
*
ast
.
ImportSpec
:
if
v
.
Name
!=
nil
{
decls
[
v
.
Name
.
Name
]
=
v
}
else
{
local
:=
importPathToName
(
strings
.
Trim
(
v
.
Path
.
Value
,
`\"`
))
decls
[
local
]
=
v
}
case
*
ast
.
SelectorExpr
:
xident
,
ok
:=
v
.
X
.
(
*
ast
.
Ident
)
if
!
ok
{
break
}
if
xident
.
Obj
!=
nil
{
// if the parser can resolve it, it's not a package ref
break
}
pkgName
:=
xident
.
Name
if
refs
[
pkgName
]
==
nil
{
refs
[
pkgName
]
=
make
(
map
[
string
]
bool
)
}
if
decls
[
pkgName
]
==
nil
{
refs
[
pkgName
][
v
.
Sel
.
Name
]
=
true
}
}
return
visitor
})
ast
.
Walk
(
visitor
,
f
)
// Nil out any unused ImportSpecs, to be removed in following passes
unusedImport
:=
map
[
string
]
bool
{}
for
pkg
,
is
:=
range
decls
{
if
refs
[
pkg
]
==
nil
&&
pkg
!=
"_"
&&
pkg
!=
"."
{
unusedImport
[
strings
.
Trim
(
is
.
Path
.
Value
,
`"`
)]
=
true
}
}
for
ipath
:=
range
unusedImport
{
if
ipath
==
"C"
{
// Don't remove cgo stuff.
continue
}
astutil
.
DeleteImport
(
fset
,
f
,
ipath
)
}
// Search for imports matching potential package references.
searches
:=
0
type
result
struct
{
ipath
string
name
string
err
error
}
results
:=
make
(
chan
result
)
for
pkgName
,
symbols
:=
range
refs
{
if
len
(
symbols
)
==
0
{
continue
// skip over packages already imported
}
go
func
(
pkgName
string
,
symbols
map
[
string
]
bool
)
{
ipath
,
rename
,
err
:=
findImport
(
pkgName
,
symbols
)
r
:=
result
{
ipath
:
ipath
,
err
:
err
}
if
rename
{
r
.
name
=
pkgName
}
results
<-
r
}(
pkgName
,
symbols
)
searches
++
}
for
i
:=
0
;
i
<
searches
;
i
++
{
result
:=
<-
results
if
result
.
err
!=
nil
{
return
nil
,
result
.
err
}
if
result
.
ipath
!=
""
{
if
result
.
name
!=
""
{
astutil
.
AddNamedImport
(
fset
,
f
,
result
.
name
,
result
.
ipath
)
}
else
{
astutil
.
AddImport
(
fset
,
f
,
result
.
ipath
)
}
added
=
append
(
added
,
result
.
ipath
)
}
}
return
added
,
nil
}
// importPathToName returns the package name for the given import path.
var
importPathToName
=
importPathToNameGoPath
// importPathToNameBasic assumes the package name is the base of import path.
func
importPathToNameBasic
(
importPath
string
)
(
packageName
string
)
{
return
path
.
Base
(
importPath
)
}
// importPathToNameGoPath finds out the actual package name, as declared in its .go files.
// If there's a problem, it falls back to using importPathToNameBasic.
func
importPathToNameGoPath
(
importPath
string
)
(
packageName
string
)
{
if
buildPkg
,
err
:=
build
.
Import
(
importPath
,
""
,
0
);
err
==
nil
{
return
buildPkg
.
Name
}
else
{
return
importPathToNameBasic
(
importPath
)
}
}
type
pkg
struct
{
importpath
string
// full pkg import path, e.g. "net/http"
dir
string
// absolute file path to pkg directory e.g. "/usr/lib/go/src/fmt"
}
var
pkgIndexOnce
sync
.
Once
var
pkgIndex
struct
{
sync
.
Mutex
m
map
[
string
][]
pkg
// shortname => []pkg, e.g "http" => "net/http"
}
// gate is a semaphore for limiting concurrency.
type
gate
chan
struct
{}
func
(
g
gate
)
enter
()
{
g
<-
struct
{}{}
}
func
(
g
gate
)
leave
()
{
<-
g
}
// fsgate protects the OS & filesystem from too much concurrency.
// Too much disk I/O -> too many threads -> swapping and bad scheduling.
var
fsgate
=
make
(
gate
,
8
)
func
loadPkgIndex
()
{
pkgIndex
.
Lock
()
pkgIndex
.
m
=
make
(
map
[
string
][]
pkg
)
pkgIndex
.
Unlock
()
var
wg
sync
.
WaitGroup
for
_
,
path
:=
range
build
.
Default
.
SrcDirs
()
{
fsgate
.
enter
()
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
fsgate
.
leave
()
fmt
.
Fprint
(
os
.
Stderr
,
err
)
continue
}
children
,
err
:=
f
.
Readdir
(
-
1
)
f
.
Close
()
fsgate
.
leave
()
if
err
!=
nil
{
fmt
.
Fprint
(
os
.
Stderr
,
err
)
continue
}
for
_
,
child
:=
range
children
{
if
child
.
IsDir
()
{
wg
.
Add
(
1
)
go
func
(
path
,
name
string
)
{
defer
wg
.
Done
()
loadPkg
(
&
wg
,
path
,
name
)
}(
path
,
child
.
Name
())
}
}
}
wg
.
Wait
()
}
func
loadPkg
(
wg
*
sync
.
WaitGroup
,
root
,
pkgrelpath
string
)
{
importpath
:=
filepath
.
ToSlash
(
pkgrelpath
)
dir
:=
filepath
.
Join
(
root
,
importpath
)
fsgate
.
enter
()
defer
fsgate
.
leave
()
pkgDir
,
err
:=
os
.
Open
(
dir
)
if
err
!=
nil
{
return
}
children
,
err
:=
pkgDir
.
Readdir
(
-
1
)
pkgDir
.
Close
()
if
err
!=
nil
{
return
}
// hasGo tracks whether a directory actually appears to be a
// Go source code directory. If $GOPATH == $HOME, and
// $HOME/src has lots of other large non-Go projects in it,
// then the calls to importPathToName below can be expensive.
hasGo
:=
false
for
_
,
child
:=
range
children
{
// Avoid .foo, _foo, and testdata directory trees.
name
:=
child
.
Name
()
if
name
==
""
||
name
[
0
]
==
'.'
||
name
[
0
]
==
'_'
||
name
==
"testdata"
{
continue
}
if
strings
.
HasSuffix
(
name
,
".go"
)
{
hasGo
=
true
}
if
child
.
IsDir
()
{
wg
.
Add
(
1
)
go
func
(
root
,
name
string
)
{
defer
wg
.
Done
()
loadPkg
(
wg
,
root
,
name
)
}(
root
,
filepath
.
Join
(
importpath
,
name
))
}
}
if
hasGo
{
shortName
:=
importPathToName
(
importpath
)
pkgIndex
.
Lock
()
pkgIndex
.
m
[
shortName
]
=
append
(
pkgIndex
.
m
[
shortName
],
pkg
{
importpath
:
importpath
,
dir
:
dir
,
})
pkgIndex
.
Unlock
()
}
}
// loadExports returns a list exports for a package.
var
loadExports
=
loadExportsGoPath
func
loadExportsGoPath
(
dir
string
)
map
[
string
]
bool
{
exports
:=
make
(
map
[
string
]
bool
)
buildPkg
,
err
:=
build
.
ImportDir
(
dir
,
0
)
if
err
!=
nil
{
if
strings
.
Contains
(
err
.
Error
(),
"no buildable Go source files in"
)
{
return
nil
}
fmt
.
Fprintf
(
os
.
Stderr
,
"could not import %q: %v
\n
"
,
dir
,
err
)
return
nil
}
fset
:=
token
.
NewFileSet
()
for
_
,
files
:=
range
[
...
][]
string
{
buildPkg
.
GoFiles
,
buildPkg
.
CgoFiles
}
{
for
_
,
file
:=
range
files
{
f
,
err
:=
parser
.
ParseFile
(
fset
,
filepath
.
Join
(
dir
,
file
),
nil
,
0
)
if
err
!=
nil
{
fmt
.
Fprintf
(
os
.
Stderr
,
"could not parse %q: %v
\n
"
,
file
,
err
)
continue
}
for
name
:=
range
f
.
Scope
.
Objects
{
if
ast
.
IsExported
(
name
)
{
exports
[
name
]
=
true
}
}
}
}
return
exports
}
// findImport searches for a package with the given symbols.
// If no package is found, findImport returns "".
// Declared as a variable rather than a function so goimports can be easily
// extended by adding a file with an init function.
var
findImport
=
findImportGoPath
func
findImportGoPath
(
pkgName
string
,
symbols
map
[
string
]
bool
)
(
string
,
bool
,
error
)
{
// Fast path for the standard library.
// In the common case we hopefully never have to scan the GOPATH, which can
// be slow with moving disks.
if
pkg
,
rename
,
ok
:=
findImportStdlib
(
pkgName
,
symbols
);
ok
{
return
pkg
,
rename
,
nil
}
// TODO(sameer): look at the import lines for other Go files in the
// local directory, since the user is likely to import the same packages
// in the current Go file. Return rename=true when the other Go files
// use a renamed package that's also used in the current file.
pkgIndexOnce
.
Do
(
loadPkgIndex
)
// Collect exports for packages with matching names.
var
wg
sync
.
WaitGroup
var
pkgsMu
sync
.
Mutex
// guards pkgs
// full importpath => exported symbol => True
// e.g. "net/http" => "Client" => True
pkgs
:=
make
(
map
[
string
]
map
[
string
]
bool
)
pkgIndex
.
Lock
()
for
_
,
pkg
:=
range
pkgIndex
.
m
[
pkgName
]
{
wg
.
Add
(
1
)
go
func
(
importpath
,
dir
string
)
{
defer
wg
.
Done
()
exports
:=
loadExports
(
dir
)
if
exports
!=
nil
{
pkgsMu
.
Lock
()
pkgs
[
importpath
]
=
exports
pkgsMu
.
Unlock
()
}
}(
pkg
.
importpath
,
pkg
.
dir
)
}
pkgIndex
.
Unlock
()
wg
.
Wait
()
// Filter out packages missing required exported symbols.
for
symbol
:=
range
symbols
{
for
importpath
,
exports
:=
range
pkgs
{
if
!
exports
[
symbol
]
{
delete
(
pkgs
,
importpath
)
}
}
}
if
len
(
pkgs
)
==
0
{
return
""
,
false
,
nil
}
// If there are multiple candidate packages, the shortest one wins.
// This is a heuristic to prefer the standard library (e.g. "bytes")
// over e.g. "github.com/foo/bar/bytes".
shortest
:=
""
for
importPath
:=
range
pkgs
{
if
shortest
==
""
||
len
(
importPath
)
<
len
(
shortest
)
{
shortest
=
importPath
}
}
return
shortest
,
false
,
nil
}
type
visitFn
func
(
node
ast
.
Node
)
ast
.
Visitor
func
(
fn
visitFn
)
Visit
(
node
ast
.
Node
)
ast
.
Visitor
{
return
fn
(
node
)
}
func
findImportStdlib
(
shortPkg
string
,
symbols
map
[
string
]
bool
)
(
importPath
string
,
rename
,
ok
bool
)
{
for
symbol
:=
range
symbols
{
path
:=
stdlib
[
shortPkg
+
"."
+
symbol
]
if
path
==
""
{
return
""
,
false
,
false
}
if
importPath
!=
""
&&
importPath
!=
path
{
// Ambiguous. Symbols pointed to different things.
return
""
,
false
,
false
}
importPath
=
path
}
return
importPath
,
false
,
importPath
!=
""
}
Godeps/_workspace/src/golang.org/x/tools/imports/imports.go
deleted
100644 → 0
View file @
ff1da767
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package imports implements a Go pretty-printer (like package "go/format")
// that also adds or removes import statements as necessary.
package
imports
import
(
"bufio"
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/printer"
"go/token"
"io"
"regexp"
"strconv"
"strings"
"golang.org/x/tools/go/ast/astutil"
)
// Options specifies options for processing files.
type
Options
struct
{
Fragment
bool
// Accept fragment of a source file (no package statement)
AllErrors
bool
// Report all errors (not just the first 10 on different lines)
Comments
bool
// Print comments (true if nil *Options provided)
TabIndent
bool
// Use tabs for indent (true if nil *Options provided)
TabWidth
int
// Tab width (8 if nil *Options provided)
}
// Process formats and adjusts imports for the provided file.
// If opt is nil the defaults are used.
func
Process
(
filename
string
,
src
[]
byte
,
opt
*
Options
)
([]
byte
,
error
)
{
if
opt
==
nil
{
opt
=
&
Options
{
Comments
:
true
,
TabIndent
:
true
,
TabWidth
:
8
}
}
fileSet
:=
token
.
NewFileSet
()
file
,
adjust
,
err
:=
parse
(
fileSet
,
filename
,
src
,
opt
)
if
err
!=
nil
{
return
nil
,
err
}
_
,
err
=
fixImports
(
fileSet
,
file
)
if
err
!=
nil
{
return
nil
,
err
}
sortImports
(
fileSet
,
file
)
imps
:=
astutil
.
Imports
(
fileSet
,
file
)
var
spacesBefore
[]
string
// import paths we need spaces before
for
_
,
impSection
:=
range
imps
{
// Within each block of contiguous imports, see if any
// import lines are in different group numbers. If so,
// we'll need to put a space between them so it's
// compatible with gofmt.
lastGroup
:=
-
1
for
_
,
importSpec
:=
range
impSection
{
importPath
,
_
:=
strconv
.
Unquote
(
importSpec
.
Path
.
Value
)
groupNum
:=
importGroup
(
importPath
)
if
groupNum
!=
lastGroup
&&
lastGroup
!=
-
1
{
spacesBefore
=
append
(
spacesBefore
,
importPath
)
}
lastGroup
=
groupNum
}
}
printerMode
:=
printer
.
UseSpaces
if
opt
.
TabIndent
{
printerMode
|=
printer
.
TabIndent
}
printConfig
:=
&
printer
.
Config
{
Mode
:
printerMode
,
Tabwidth
:
opt
.
TabWidth
}
var
buf
bytes
.
Buffer
err
=
printConfig
.
Fprint
(
&
buf
,
fileSet
,
file
)
if
err
!=
nil
{
return
nil
,
err
}
out
:=
buf
.
Bytes
()
if
adjust
!=
nil
{
out
=
adjust
(
src
,
out
)
}
if
len
(
spacesBefore
)
>
0
{
out
=
addImportSpaces
(
bytes
.
NewReader
(
out
),
spacesBefore
)
}
out
,
err
=
format
.
Source
(
out
)
if
err
!=
nil
{
return
nil
,
err
}
return
out
,
nil
}
// parse parses src, which was read from filename,
// as a Go source file or statement list.
func
parse
(
fset
*
token
.
FileSet
,
filename
string
,
src
[]
byte
,
opt
*
Options
)
(
*
ast
.
File
,
func
(
orig
,
src
[]
byte
)
[]
byte
,
error
)
{
parserMode
:=
parser
.
Mode
(
0
)
if
opt
.
Comments
{
parserMode
|=
parser
.
ParseComments
}
if
opt
.
AllErrors
{
parserMode
|=
parser
.
AllErrors
}
// Try as whole source file.
file
,
err
:=
parser
.
ParseFile
(
fset
,
filename
,
src
,
parserMode
)
if
err
==
nil
{
return
file
,
nil
,
nil
}
// If the error is that the source file didn't begin with a
// package line and we accept fragmented input, fall through to
// try as a source fragment. Stop and return on any other error.
if
!
opt
.
Fragment
||
!
strings
.
Contains
(
err
.
Error
(),
"expected 'package'"
)
{
return
nil
,
nil
,
err
}
// If this is a declaration list, make it a source file
// by inserting a package clause.
// Insert using a ;, not a newline, so that the line numbers
// in psrc match the ones in src.
psrc
:=
append
([]
byte
(
"package main;"
),
src
...
)
file
,
err
=
parser
.
ParseFile
(
fset
,
filename
,
psrc
,
parserMode
)
if
err
==
nil
{
// If a main function exists, we will assume this is a main
// package and leave the file.
if
containsMainFunc
(
file
)
{
return
file
,
nil
,
nil
}
adjust
:=
func
(
orig
,
src
[]
byte
)
[]
byte
{
// Remove the package clause.
// Gofmt has turned the ; into a \n.
src
=
src
[
len
(
"package main
\n
"
)
:
]
return
matchSpace
(
orig
,
src
)
}
return
file
,
adjust
,
nil
}
// If the error is that the source file didn't begin with a
// declaration, fall through to try as a statement list.
// Stop and return on any other error.
if
!
strings
.
Contains
(
err
.
Error
(),
"expected declaration"
)
{
return
nil
,
nil
,
err
}
// If this is a statement list, make it a source file
// by inserting a package clause and turning the list
// into a function body. This handles expressions too.
// Insert using a ;, not a newline, so that the line numbers
// in fsrc match the ones in src.
fsrc
:=
append
(
append
([]
byte
(
"package p; func _() {"
),
src
...
),
'}'
)
file
,
err
=
parser
.
ParseFile
(
fset
,
filename
,
fsrc
,
parserMode
)
if
err
==
nil
{
adjust
:=
func
(
orig
,
src
[]
byte
)
[]
byte
{
// Remove the wrapping.
// Gofmt has turned the ; into a \n\n.
src
=
src
[
len
(
"package p
\n\n
func _() {"
)
:
]
src
=
src
[
:
len
(
src
)
-
len
(
"}
\n
"
)]
// Gofmt has also indented the function body one level.
// Remove that indent.
src
=
bytes
.
Replace
(
src
,
[]
byte
(
"
\n\t
"
),
[]
byte
(
"
\n
"
),
-
1
)
return
matchSpace
(
orig
,
src
)
}
return
file
,
adjust
,
nil
}
// Failed, and out of options.
return
nil
,
nil
,
err
}
// containsMainFunc checks if a file contains a function declaration with the
// function signature 'func main()'
func
containsMainFunc
(
file
*
ast
.
File
)
bool
{
for
_
,
decl
:=
range
file
.
Decls
{
if
f
,
ok
:=
decl
.
(
*
ast
.
FuncDecl
);
ok
{
if
f
.
Name
.
Name
!=
"main"
{
continue
}
if
len
(
f
.
Type
.
Params
.
List
)
!=
0
{
continue
}
if
f
.
Type
.
Results
!=
nil
&&
len
(
f
.
Type
.
Results
.
List
)
!=
0
{
continue
}
return
true
}
}
return
false
}
func
cutSpace
(
b
[]
byte
)
(
before
,
middle
,
after
[]
byte
)
{
i
:=
0
for
i
<
len
(
b
)
&&
(
b
[
i
]
==
' '
||
b
[
i
]
==
'\t'
||
b
[
i
]
==
'\n'
)
{
i
++
}
j
:=
len
(
b
)
for
j
>
0
&&
(
b
[
j
-
1
]
==
' '
||
b
[
j
-
1
]
==
'\t'
||
b
[
j
-
1
]
==
'\n'
)
{
j
--
}
if
i
<=
j
{
return
b
[
:
i
],
b
[
i
:
j
],
b
[
j
:
]
}
return
nil
,
nil
,
b
[
j
:
]
}
// matchSpace reformats src to use the same space context as orig.
// 1) If orig begins with blank lines, matchSpace inserts them at the beginning of src.
// 2) matchSpace copies the indentation of the first non-blank line in orig
// to every non-blank line in src.
// 3) matchSpace copies the trailing space from orig and uses it in place
// of src's trailing space.
func
matchSpace
(
orig
[]
byte
,
src
[]
byte
)
[]
byte
{
before
,
_
,
after
:=
cutSpace
(
orig
)
i
:=
bytes
.
LastIndex
(
before
,
[]
byte
{
'\n'
})
before
,
indent
:=
before
[
:
i
+
1
],
before
[
i
+
1
:
]
_
,
src
,
_
=
cutSpace
(
src
)
var
b
bytes
.
Buffer
b
.
Write
(
before
)
for
len
(
src
)
>
0
{
line
:=
src
if
i
:=
bytes
.
IndexByte
(
line
,
'\n'
);
i
>=
0
{
line
,
src
=
line
[
:
i
+
1
],
line
[
i
+
1
:
]
}
else
{
src
=
nil
}
if
len
(
line
)
>
0
&&
line
[
0
]
!=
'\n'
{
// not blank
b
.
Write
(
indent
)
}
b
.
Write
(
line
)
}
b
.
Write
(
after
)
return
b
.
Bytes
()
}
var
impLine
=
regexp
.
MustCompile
(
`^\s+(?:[\w\.]+\s+)?"(.+)"`
)
func
addImportSpaces
(
r
io
.
Reader
,
breaks
[]
string
)
[]
byte
{
var
out
bytes
.
Buffer
sc
:=
bufio
.
NewScanner
(
r
)
inImports
:=
false
done
:=
false
for
sc
.
Scan
()
{
s
:=
sc
.
Text
()
if
!
inImports
&&
!
done
&&
strings
.
HasPrefix
(
s
,
"import"
)
{
inImports
=
true
}
if
inImports
&&
(
strings
.
HasPrefix
(
s
,
"var"
)
||
strings
.
HasPrefix
(
s
,
"func"
)
||
strings
.
HasPrefix
(
s
,
"const"
)
||
strings
.
HasPrefix
(
s
,
"type"
))
{
done
=
true
inImports
=
false
}
if
inImports
&&
len
(
breaks
)
>
0
{
if
m
:=
impLine
.
FindStringSubmatch
(
s
);
m
!=
nil
{
if
m
[
1
]
==
string
(
breaks
[
0
])
{
out
.
WriteByte
(
'\n'
)
breaks
=
breaks
[
1
:
]
}
}
}
fmt
.
Fprintln
(
&
out
,
s
)
}
return
out
.
Bytes
()
}
Godeps/_workspace/src/golang.org/x/tools/imports/mkindex.go
deleted
100644 → 0
View file @
ff1da767
// +build ignore
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Command mkindex creates the file "pkgindex.go" containing an index of the Go
// standard library. The file is intended to be built as part of the imports
// package, so that the package may be used in environments where a GOROOT is
// not available (such as App Engine).
package
main
import
(
"bytes"
"fmt"
"go/ast"
"go/build"
"go/format"
"go/parser"
"go/token"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"strings"
)
var
(
pkgIndex
=
make
(
map
[
string
][]
pkg
)
exports
=
make
(
map
[
string
]
map
[
string
]
bool
)
)
func
main
()
{
// Don't use GOPATH.
ctx
:=
build
.
Default
ctx
.
GOPATH
=
""
// Populate pkgIndex global from GOROOT.
for
_
,
path
:=
range
ctx
.
SrcDirs
()
{
f
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
log
.
Print
(
err
)
continue
}
children
,
err
:=
f
.
Readdir
(
-
1
)
f
.
Close
()
if
err
!=
nil
{
log
.
Print
(
err
)
continue
}
for
_
,
child
:=
range
children
{
if
child
.
IsDir
()
{
loadPkg
(
path
,
child
.
Name
())
}
}
}
// Populate exports global.
for
_
,
ps
:=
range
pkgIndex
{
for
_
,
p
:=
range
ps
{
e
:=
loadExports
(
p
.
dir
)
if
e
!=
nil
{
exports
[
p
.
dir
]
=
e
}
}
}
// Construct source file.
var
buf
bytes
.
Buffer
fmt
.
Fprint
(
&
buf
,
pkgIndexHead
)
fmt
.
Fprintf
(
&
buf
,
"var pkgIndexMaster = %#v
\n
"
,
pkgIndex
)
fmt
.
Fprintf
(
&
buf
,
"var exportsMaster = %#v
\n
"
,
exports
)
src
:=
buf
.
Bytes
()
// Replace main.pkg type name with pkg.
src
=
bytes
.
Replace
(
src
,
[]
byte
(
"main.pkg"
),
[]
byte
(
"pkg"
),
-
1
)
// Replace actual GOROOT with "/go".
src
=
bytes
.
Replace
(
src
,
[]
byte
(
ctx
.
GOROOT
),
[]
byte
(
"/go"
),
-
1
)
// Add some line wrapping.
src
=
bytes
.
Replace
(
src
,
[]
byte
(
"}, "
),
[]
byte
(
"},
\n
"
),
-
1
)
src
=
bytes
.
Replace
(
src
,
[]
byte
(
"true, "
),
[]
byte
(
"true,
\n
"
),
-
1
)
var
err
error
src
,
err
=
format
.
Source
(
src
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
// Write out source file.
err
=
ioutil
.
WriteFile
(
"pkgindex.go"
,
src
,
0644
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
}
const
pkgIndexHead
=
`package imports
func init() {
pkgIndexOnce.Do(func() {
pkgIndex.m = pkgIndexMaster
})
loadExports = func(dir string) map[string]bool {
return exportsMaster[dir]
}
}
`
type
pkg
struct
{
importpath
string
// full pkg import path, e.g. "net/http"
dir
string
// absolute file path to pkg directory e.g. "/usr/lib/go/src/fmt"
}
var
fset
=
token
.
NewFileSet
()
func
loadPkg
(
root
,
importpath
string
)
{
shortName
:=
path
.
Base
(
importpath
)
if
shortName
==
"testdata"
{
return
}
dir
:=
filepath
.
Join
(
root
,
importpath
)
pkgIndex
[
shortName
]
=
append
(
pkgIndex
[
shortName
],
pkg
{
importpath
:
importpath
,
dir
:
dir
,
})
pkgDir
,
err
:=
os
.
Open
(
dir
)
if
err
!=
nil
{
return
}
children
,
err
:=
pkgDir
.
Readdir
(
-
1
)
pkgDir
.
Close
()
if
err
!=
nil
{
return
}
for
_
,
child
:=
range
children
{
name
:=
child
.
Name
()
if
name
==
""
{
continue
}
if
c
:=
name
[
0
];
c
==
'.'
||
(
'0'
<=
c
&&
c
<=
'9'
)
{
continue
}
if
child
.
IsDir
()
{
loadPkg
(
root
,
filepath
.
Join
(
importpath
,
name
))
}
}
}
func
loadExports
(
dir
string
)
map
[
string
]
bool
{
exports
:=
make
(
map
[
string
]
bool
)
buildPkg
,
err
:=
build
.
ImportDir
(
dir
,
0
)
if
err
!=
nil
{
if
strings
.
Contains
(
err
.
Error
(),
"no buildable Go source files in"
)
{
return
nil
}
log
.
Printf
(
"could not import %q: %v"
,
dir
,
err
)
return
nil
}
for
_
,
file
:=
range
buildPkg
.
GoFiles
{
f
,
err
:=
parser
.
ParseFile
(
fset
,
filepath
.
Join
(
dir
,
file
),
nil
,
0
)
if
err
!=
nil
{
log
.
Printf
(
"could not parse %q: %v"
,
file
,
err
)
continue
}
for
name
:=
range
f
.
Scope
.
Objects
{
if
ast
.
IsExported
(
name
)
{
exports
[
name
]
=
true
}
}
}
return
exports
}
Godeps/_workspace/src/golang.org/x/tools/imports/mkstdlib.go
deleted
100644 → 0
View file @
ff1da767
// +build ignore
// mkstdlib generates the zstdlib.go file, containing the Go standard
// library API symbols. It's baked into the binary to avoid scanning
// GOPATH in the common case.
package
main
import
(
"bufio"
"bytes"
"fmt"
"go/format"
"io"
"log"
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strings"
)
func
mustOpen
(
name
string
)
io
.
Reader
{
f
,
err
:=
os
.
Open
(
name
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
return
f
}
func
api
(
base
string
)
string
{
return
filepath
.
Join
(
os
.
Getenv
(
"GOROOT"
),
"api"
,
base
)
}
var
sym
=
regexp
.
MustCompile
(
`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`
)
func
main
()
{
var
buf
bytes
.
Buffer
outf
:=
func
(
format
string
,
args
...
interface
{})
{
fmt
.
Fprintf
(
&
buf
,
format
,
args
...
)
}
outf
(
"// AUTO-GENERATED BY mkstdlib.go
\n\n
"
)
outf
(
"package imports
\n
"
)
outf
(
"var stdlib = map[string]string{
\n
"
)
f
:=
io
.
MultiReader
(
mustOpen
(
api
(
"go1.txt"
)),
mustOpen
(
api
(
"go1.1.txt"
)),
mustOpen
(
api
(
"go1.2.txt"
)),
)
sc
:=
bufio
.
NewScanner
(
f
)
fullImport
:=
map
[
string
]
string
{}
// "zip.NewReader" => "archive/zip"
ambiguous
:=
map
[
string
]
bool
{}
var
keys
[]
string
for
sc
.
Scan
()
{
l
:=
sc
.
Text
()
has
:=
func
(
v
string
)
bool
{
return
strings
.
Contains
(
l
,
v
)
}
if
has
(
"struct, "
)
||
has
(
"interface, "
)
||
has
(
", method ("
)
{
continue
}
if
m
:=
sym
.
FindStringSubmatch
(
l
);
m
!=
nil
{
full
:=
m
[
1
]
key
:=
path
.
Base
(
full
)
+
"."
+
m
[
2
]
if
exist
,
ok
:=
fullImport
[
key
];
ok
{
if
exist
!=
full
{
ambiguous
[
key
]
=
true
}
}
else
{
fullImport
[
key
]
=
full
keys
=
append
(
keys
,
key
)
}
}
}
if
err
:=
sc
.
Err
();
err
!=
nil
{
log
.
Fatal
(
err
)
}
sort
.
Strings
(
keys
)
for
_
,
key
:=
range
keys
{
if
ambiguous
[
key
]
{
outf
(
"
\t
// %q is ambiguous
\n
"
,
key
)
}
else
{
outf
(
"
\t
%q: %q,
\n
"
,
key
,
fullImport
[
key
])
}
}
outf
(
"}
\n
"
)
fmtbuf
,
err
:=
format
.
Source
(
buf
.
Bytes
())
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
os
.
Stdout
.
Write
(
fmtbuf
)
}
Godeps/_workspace/src/golang.org/x/tools/imports/sortimports.go
deleted
100644 → 0
View file @
ff1da767
// +build go1.2
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Hacked up copy of go/ast/import.go
package
imports
import
(
"go/ast"
"go/token"
"sort"
"strconv"
)
// sortImports sorts runs of consecutive import lines in import blocks in f.
// It also removes duplicate imports when it is possible to do so without data loss.
func
sortImports
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
)
{
for
i
,
d
:=
range
f
.
Decls
{
d
,
ok
:=
d
.
(
*
ast
.
GenDecl
)
if
!
ok
||
d
.
Tok
!=
token
.
IMPORT
{
// Not an import declaration, so we're done.
// Imports are always first.
break
}
if
len
(
d
.
Specs
)
==
0
{
// Empty import block, remove it.
f
.
Decls
=
append
(
f
.
Decls
[
:
i
],
f
.
Decls
[
i
+
1
:
]
...
)
}
if
!
d
.
Lparen
.
IsValid
()
{
// Not a block: sorted by default.
continue
}
// Identify and sort runs of specs on successive lines.
i
:=
0
specs
:=
d
.
Specs
[
:
0
]
for
j
,
s
:=
range
d
.
Specs
{
if
j
>
i
&&
fset
.
Position
(
s
.
Pos
())
.
Line
>
1
+
fset
.
Position
(
d
.
Specs
[
j
-
1
]
.
End
())
.
Line
{
// j begins a new run. End this one.
specs
=
append
(
specs
,
sortSpecs
(
fset
,
f
,
d
.
Specs
[
i
:
j
])
...
)
i
=
j
}
}
specs
=
append
(
specs
,
sortSpecs
(
fset
,
f
,
d
.
Specs
[
i
:
])
...
)
d
.
Specs
=
specs
// Deduping can leave a blank line before the rparen; clean that up.
if
len
(
d
.
Specs
)
>
0
{
lastSpec
:=
d
.
Specs
[
len
(
d
.
Specs
)
-
1
]
lastLine
:=
fset
.
Position
(
lastSpec
.
Pos
())
.
Line
if
rParenLine
:=
fset
.
Position
(
d
.
Rparen
)
.
Line
;
rParenLine
>
lastLine
+
1
{
fset
.
File
(
d
.
Rparen
)
.
MergeLine
(
rParenLine
-
1
)
}
}
}
}
func
importPath
(
s
ast
.
Spec
)
string
{
t
,
err
:=
strconv
.
Unquote
(
s
.
(
*
ast
.
ImportSpec
)
.
Path
.
Value
)
if
err
==
nil
{
return
t
}
return
""
}
func
importName
(
s
ast
.
Spec
)
string
{
n
:=
s
.
(
*
ast
.
ImportSpec
)
.
Name
if
n
==
nil
{
return
""
}
return
n
.
Name
}
func
importComment
(
s
ast
.
Spec
)
string
{
c
:=
s
.
(
*
ast
.
ImportSpec
)
.
Comment
if
c
==
nil
{
return
""
}
return
c
.
Text
()
}
// collapse indicates whether prev may be removed, leaving only next.
func
collapse
(
prev
,
next
ast
.
Spec
)
bool
{
if
importPath
(
next
)
!=
importPath
(
prev
)
||
importName
(
next
)
!=
importName
(
prev
)
{
return
false
}
return
prev
.
(
*
ast
.
ImportSpec
)
.
Comment
==
nil
}
type
posSpan
struct
{
Start
token
.
Pos
End
token
.
Pos
}
func
sortSpecs
(
fset
*
token
.
FileSet
,
f
*
ast
.
File
,
specs
[]
ast
.
Spec
)
[]
ast
.
Spec
{
// Can't short-circuit here even if specs are already sorted,
// since they might yet need deduplication.
// A lone import, however, may be safely ignored.
if
len
(
specs
)
<=
1
{
return
specs
}
// Record positions for specs.
pos
:=
make
([]
posSpan
,
len
(
specs
))
for
i
,
s
:=
range
specs
{
pos
[
i
]
=
posSpan
{
s
.
Pos
(),
s
.
End
()}
}
// Identify comments in this range.
// Any comment from pos[0].Start to the final line counts.
lastLine
:=
fset
.
Position
(
pos
[
len
(
pos
)
-
1
]
.
End
)
.
Line
cstart
:=
len
(
f
.
Comments
)
cend
:=
len
(
f
.
Comments
)
for
i
,
g
:=
range
f
.
Comments
{
if
g
.
Pos
()
<
pos
[
0
]
.
Start
{
continue
}
if
i
<
cstart
{
cstart
=
i
}
if
fset
.
Position
(
g
.
End
())
.
Line
>
lastLine
{
cend
=
i
break
}
}
comments
:=
f
.
Comments
[
cstart
:
cend
]
// Assign each comment to the import spec preceding it.
importComment
:=
map
[
*
ast
.
ImportSpec
][]
*
ast
.
CommentGroup
{}
specIndex
:=
0
for
_
,
g
:=
range
comments
{
for
specIndex
+
1
<
len
(
specs
)
&&
pos
[
specIndex
+
1
]
.
Start
<=
g
.
Pos
()
{
specIndex
++
}
s
:=
specs
[
specIndex
]
.
(
*
ast
.
ImportSpec
)
importComment
[
s
]
=
append
(
importComment
[
s
],
g
)
}
// Sort the import specs by import path.
// Remove duplicates, when possible without data loss.
// Reassign the import paths to have the same position sequence.
// Reassign each comment to abut the end of its spec.
// Sort the comments by new position.
sort
.
Sort
(
byImportSpec
(
specs
))
// Dedup. Thanks to our sorting, we can just consider
// adjacent pairs of imports.
deduped
:=
specs
[
:
0
]
for
i
,
s
:=
range
specs
{
if
i
==
len
(
specs
)
-
1
||
!
collapse
(
s
,
specs
[
i
+
1
])
{
deduped
=
append
(
deduped
,
s
)
}
else
{
p
:=
s
.
Pos
()
fset
.
File
(
p
)
.
MergeLine
(
fset
.
Position
(
p
)
.
Line
)
}
}
specs
=
deduped
// Fix up comment positions
for
i
,
s
:=
range
specs
{
s
:=
s
.
(
*
ast
.
ImportSpec
)
if
s
.
Name
!=
nil
{
s
.
Name
.
NamePos
=
pos
[
i
]
.
Start
}
s
.
Path
.
ValuePos
=
pos
[
i
]
.
Start
s
.
EndPos
=
pos
[
i
]
.
End
for
_
,
g
:=
range
importComment
[
s
]
{
for
_
,
c
:=
range
g
.
List
{
c
.
Slash
=
pos
[
i
]
.
End
}
}
}
sort
.
Sort
(
byCommentPos
(
comments
))
return
specs
}
type
byImportSpec
[]
ast
.
Spec
// slice of *ast.ImportSpec
func
(
x
byImportSpec
)
Len
()
int
{
return
len
(
x
)
}
func
(
x
byImportSpec
)
Swap
(
i
,
j
int
)
{
x
[
i
],
x
[
j
]
=
x
[
j
],
x
[
i
]
}
func
(
x
byImportSpec
)
Less
(
i
,
j
int
)
bool
{
ipath
:=
importPath
(
x
[
i
])
jpath
:=
importPath
(
x
[
j
])
igroup
:=
importGroup
(
ipath
)
jgroup
:=
importGroup
(
jpath
)
if
igroup
!=
jgroup
{
return
igroup
<
jgroup
}
if
ipath
!=
jpath
{
return
ipath
<
jpath
}
iname
:=
importName
(
x
[
i
])
jname
:=
importName
(
x
[
j
])
if
iname
!=
jname
{
return
iname
<
jname
}
return
importComment
(
x
[
i
])
<
importComment
(
x
[
j
])
}
type
byCommentPos
[]
*
ast
.
CommentGroup
func
(
x
byCommentPos
)
Len
()
int
{
return
len
(
x
)
}
func
(
x
byCommentPos
)
Swap
(
i
,
j
int
)
{
x
[
i
],
x
[
j
]
=
x
[
j
],
x
[
i
]
}
func
(
x
byCommentPos
)
Less
(
i
,
j
int
)
bool
{
return
x
[
i
]
.
Pos
()
<
x
[
j
]
.
Pos
()
}
Godeps/_workspace/src/golang.org/x/tools/imports/sortimports_compat.go
deleted
100644 → 0
View file @
ff1da767
// +build !go1.2
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
imports
import
"go/ast"
// Go 1.1 users don't get fancy package grouping.
// But this is still gofmt-compliant:
var
sortImports
=
ast
.
SortImports
Godeps/_workspace/src/golang.org/x/tools/imports/zstdlib.go
deleted
100644 → 0
View file @
ff1da767
This source diff could not be displayed because it is too large. You can
view the blob
instead.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment