forked from cerc-io/plugeth
289b30715d
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
279 lines
7.1 KiB
Go
279 lines
7.1 KiB
Go
package ast
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/robertkrimen/otto/file"
|
|
)
|
|
|
|
// CommentPosition determines where the comment is in a given context
|
|
type CommentPosition int
|
|
|
|
const (
|
|
_ CommentPosition = iota
|
|
LEADING // Before the pertinent expression
|
|
TRAILING // After the pertinent expression
|
|
KEY // Before a key in an object
|
|
COLON // After a colon in a field declaration
|
|
FINAL // Final comments in a block, not belonging to a specific expression or the comment after a trailing , in an array or object literal
|
|
IF // After an if keyword
|
|
WHILE // After a while keyword
|
|
DO // After do keyword
|
|
FOR // After a for keyword
|
|
WITH // After a with keyword
|
|
TBD
|
|
)
|
|
|
|
// Comment contains the data of the comment
|
|
type Comment struct {
|
|
Begin file.Idx
|
|
Text string
|
|
Position CommentPosition
|
|
}
|
|
|
|
// NewComment creates a new comment
|
|
func NewComment(text string, idx file.Idx) *Comment {
|
|
comment := &Comment{
|
|
Begin: idx,
|
|
Text: text,
|
|
Position: TBD,
|
|
}
|
|
|
|
return comment
|
|
}
|
|
|
|
// String returns a stringified version of the position
|
|
func (cp CommentPosition) String() string {
|
|
switch cp {
|
|
case LEADING:
|
|
return "Leading"
|
|
case TRAILING:
|
|
return "Trailing"
|
|
case KEY:
|
|
return "Key"
|
|
case COLON:
|
|
return "Colon"
|
|
case FINAL:
|
|
return "Final"
|
|
case IF:
|
|
return "If"
|
|
case WHILE:
|
|
return "While"
|
|
case DO:
|
|
return "Do"
|
|
case FOR:
|
|
return "For"
|
|
case WITH:
|
|
return "With"
|
|
default:
|
|
return "???"
|
|
}
|
|
}
|
|
|
|
// String returns a stringified version of the comment
|
|
func (c Comment) String() string {
|
|
return fmt.Sprintf("Comment: %v", c.Text)
|
|
}
|
|
|
|
// Comments defines the current view of comments from the parser
|
|
type Comments struct {
|
|
// CommentMap is a reference to the parser comment map
|
|
CommentMap CommentMap
|
|
// Comments lists the comments scanned, not linked to a node yet
|
|
Comments []*Comment
|
|
// future lists the comments after a line break during a sequence of comments
|
|
future []*Comment
|
|
// Current is node for which comments are linked to
|
|
Current Expression
|
|
|
|
// wasLineBreak determines if a line break occured while scanning for comments
|
|
wasLineBreak bool
|
|
// primary determines whether or not processing a primary expression
|
|
primary bool
|
|
// afterBlock determines whether or not being after a block statement
|
|
afterBlock bool
|
|
}
|
|
|
|
func NewComments() *Comments {
|
|
comments := &Comments{
|
|
CommentMap: CommentMap{},
|
|
}
|
|
|
|
return comments
|
|
}
|
|
|
|
func (c *Comments) String() string {
|
|
return fmt.Sprintf("NODE: %v, Comments: %v, Future: %v(LINEBREAK:%v)", c.Current, len(c.Comments), len(c.future), c.wasLineBreak)
|
|
}
|
|
|
|
// FetchAll returns all the currently scanned comments,
|
|
// including those from the next line
|
|
func (c *Comments) FetchAll() []*Comment {
|
|
defer func() {
|
|
c.Comments = nil
|
|
c.future = nil
|
|
}()
|
|
|
|
return append(c.Comments, c.future...)
|
|
}
|
|
|
|
// Fetch returns all the currently scanned comments
|
|
func (c *Comments) Fetch() []*Comment {
|
|
defer func() {
|
|
c.Comments = nil
|
|
}()
|
|
|
|
return c.Comments
|
|
}
|
|
|
|
// ResetLineBreak marks the beginning of a new statement
|
|
func (c *Comments) ResetLineBreak() {
|
|
c.wasLineBreak = false
|
|
}
|
|
|
|
// MarkPrimary will mark the context as processing a primary expression
|
|
func (c *Comments) MarkPrimary() {
|
|
c.primary = true
|
|
c.wasLineBreak = false
|
|
}
|
|
|
|
// AfterBlock will mark the context as being after a block.
|
|
func (c *Comments) AfterBlock() {
|
|
c.afterBlock = true
|
|
}
|
|
|
|
// AddComment adds a comment to the view.
|
|
// Depending on the context, comments are added normally or as post line break.
|
|
func (c *Comments) AddComment(comment *Comment) {
|
|
if c.primary {
|
|
if !c.wasLineBreak {
|
|
c.Comments = append(c.Comments, comment)
|
|
} else {
|
|
c.future = append(c.future, comment)
|
|
}
|
|
} else {
|
|
if !c.wasLineBreak || (c.Current == nil && !c.afterBlock) {
|
|
c.Comments = append(c.Comments, comment)
|
|
} else {
|
|
c.future = append(c.future, comment)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MarkComments will mark the found comments as the given position.
|
|
func (c *Comments) MarkComments(position CommentPosition) {
|
|
for _, comment := range c.Comments {
|
|
if comment.Position == TBD {
|
|
comment.Position = position
|
|
}
|
|
}
|
|
for _, c := range c.future {
|
|
if c.Position == TBD {
|
|
c.Position = position
|
|
}
|
|
}
|
|
}
|
|
|
|
// Unset the current node and apply the comments to the current expression.
|
|
// Resets context variables.
|
|
func (c *Comments) Unset() {
|
|
if c.Current != nil {
|
|
c.applyComments(c.Current, c.Current, TRAILING)
|
|
c.Current = nil
|
|
}
|
|
c.wasLineBreak = false
|
|
c.primary = false
|
|
c.afterBlock = false
|
|
}
|
|
|
|
// SetExpression sets the current expression.
|
|
// It is applied the found comments, unless the previous expression has not been unset.
|
|
// It is skipped if the node is already set or if it is a part of the previous node.
|
|
func (c *Comments) SetExpression(node Expression) {
|
|
// Skipping same node
|
|
if c.Current == node {
|
|
return
|
|
}
|
|
if c.Current != nil && c.Current.Idx1() == node.Idx1() {
|
|
c.Current = node
|
|
return
|
|
}
|
|
previous := c.Current
|
|
c.Current = node
|
|
|
|
// Apply the found comments and futures to the node and the previous.
|
|
c.applyComments(node, previous, TRAILING)
|
|
}
|
|
|
|
// PostProcessNode applies all found comments to the given node
|
|
func (c *Comments) PostProcessNode(node Node) {
|
|
c.applyComments(node, nil, TRAILING)
|
|
}
|
|
|
|
// applyComments applies both the comments and the future comments to the given node and the previous one,
|
|
// based on the context.
|
|
func (c *Comments) applyComments(node, previous Node, position CommentPosition) {
|
|
if previous != nil {
|
|
c.CommentMap.AddComments(previous, c.Comments, position)
|
|
c.Comments = nil
|
|
} else {
|
|
c.CommentMap.AddComments(node, c.Comments, position)
|
|
c.Comments = nil
|
|
}
|
|
// Only apply the future comments to the node if the previous is set.
|
|
// This is for detecting end of line comments and which node comments on the following lines belongs to
|
|
if previous != nil {
|
|
c.CommentMap.AddComments(node, c.future, position)
|
|
c.future = nil
|
|
}
|
|
}
|
|
|
|
// AtLineBreak will mark a line break
|
|
func (c *Comments) AtLineBreak() {
|
|
c.wasLineBreak = true
|
|
}
|
|
|
|
// CommentMap is the data structure where all found comments are stored
|
|
type CommentMap map[Node][]*Comment
|
|
|
|
// AddComment adds a single comment to the map
|
|
func (cm CommentMap) AddComment(node Node, comment *Comment) {
|
|
list := cm[node]
|
|
list = append(list, comment)
|
|
|
|
cm[node] = list
|
|
}
|
|
|
|
// AddComments adds a slice of comments, given a node and an updated position
|
|
func (cm CommentMap) AddComments(node Node, comments []*Comment, position CommentPosition) {
|
|
for _, comment := range comments {
|
|
if comment.Position == TBD {
|
|
comment.Position = position
|
|
}
|
|
cm.AddComment(node, comment)
|
|
}
|
|
}
|
|
|
|
// Size returns the size of the map
|
|
func (cm CommentMap) Size() int {
|
|
size := 0
|
|
for _, comments := range cm {
|
|
size += len(comments)
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// MoveComments moves comments with a given position from a node to another
|
|
func (cm CommentMap) MoveComments(from, to Node, position CommentPosition) {
|
|
for i, c := range cm[from] {
|
|
if c.Position == position {
|
|
cm.AddComment(to, c)
|
|
|
|
// Remove the comment from the "from" slice
|
|
cm[from][i] = cm[from][len(cm[from])-1]
|
|
cm[from][len(cm[from])-1] = nil
|
|
cm[from] = cm[from][:len(cm[from])-1]
|
|
}
|
|
}
|
|
}
|