Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
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
guxukai
baas-ide
Commits
f8e66ad6
Commit
f8e66ad6
authored
Jun 18, 2019
by
rocky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add more position conversion functions
- type LineColPosition, - type LineColRange, - function lineColPositionFromOffset - function srcToLineColumnRange And associated tests for these
parent
a600b30a
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
177 additions
and
27 deletions
+177
-27
package.json
remix-astwalker/package.json
+1
-0
index.d.ts
remix-astwalker/src/@types/remix-lib/index.d.ts
+7
-0
sourceMappings.ts
remix-astwalker/src/sourceMappings.ts
+68
-12
types.ts
remix-astwalker/src/types.ts
+18
-0
test.sol
remix-astwalker/tests/resources/test.sol
+17
-0
sourceMappings.ts
remix-astwalker/tests/sourceMappings.ts
+63
-14
tsconfig.json
remix-astwalker/tsconfig.json
+3
-1
No files found.
remix-astwalker/package.json
View file @
f8e66ad6
...
...
@@ -32,6 +32,7 @@
]
},
"dependencies"
:
{
"remix-lib"
:
"^0.4.6"
,
"@types/tape"
:
"^4.2.33"
,
"nyc"
:
"^13.3.0"
,
"tape"
:
"^4.10.1"
,
...
...
remix-astwalker/src/@types/remix-lib/index.d.ts
0 → 100644
View file @
f8e66ad6
// Type definitiosn for the things we need from remix-lib
declare
module
"remix-lib"
{
export
module
util
{
export
function
findLowerBound
(
target
:
number
,
array
:
Array
<
number
>
):
number
;
}
}
remix-astwalker/src/sourceMappings.ts
View file @
f8e66ad6
import
{
isAstNode
,
AstWalker
}
from
'./astWalker'
;
import
{
AstNode
,
Location
}
from
"./types"
;
import
{
AstNode
,
LineColPosition
,
LineColRange
,
Location
}
from
"./types"
;
import
{
util
}
from
"remix-lib"
;
export
declare
interface
SourceMappings
{
new
():
SourceMappings
;
}
/**
* Break out fields of an AST's "src" attribute string (s:l:f)
* into its "start", "length", and "file index" components.
* Turn an character offset into a "LineColPosition".
*
* @param {AstNode} astNode - the object to convert.
* @param offset The character offset to convert.
*/
export
function
lineColPositionFromOffset
(
offset
:
number
,
lineBreaks
:
Array
<
number
>
):
LineColPosition
{
let
line
:
number
=
util
.
findLowerBound
(
offset
,
lineBreaks
);
if
(
lineBreaks
[
line
]
!==
offset
)
{
line
+=
1
;
}
const
beginColumn
=
line
===
0
?
0
:
(
lineBreaks
[
line
-
1
]
+
1
);
return
<
LineColPosition
>
{
line
:
line
+
1
,
character
:
(
offset
-
beginColumn
)
+
1
}
}
/**
* Turn a solc AST's "src" attribute string (s:l:f)
* into a Location
*
* @param astNode The object to convert.
*/
export
function
sourceLocationFromAstNode
(
astNode
:
AstNode
):
Location
|
null
{
if
(
isAstNode
(
astNode
)
&&
astNode
.
src
)
{
var
split
=
astNode
.
src
.
split
(
':'
)
return
sourceLocationFromSrc
(
astNode
.
src
)
}
return
null
;
}
/**
* Break out fields of solc AST's "src" attribute string (s:l:f)
* into its "start", "length", and "file index" components
* and return that as a Location
*
* @param src A solc "src" field.
* @returns {Location}
*/
export
function
sourceLocationFromSrc
(
src
:
string
):
Location
{
const
split
=
src
.
split
(
':'
)
return
<
Location
>
{
start
:
parseInt
(
split
[
0
],
10
),
length
:
parseInt
(
split
[
1
],
10
),
file
:
parseInt
(
split
[
2
],
10
)
}
}
return
null
;
}
/**
* Routines for retrieving AST object(s) using some criteria, usually
* Routines for retrieving
solc
AST object(s) using some criteria, usually
* includng "src' information.
*/
export
class
SourceMappings
{
...
...
@@ -45,11 +75,10 @@ export class SourceMappings {
};
/**
*
get a list of nodes that are at the given @arg position
*
Get a list of nodes that are at the given "position".
*
* @param {String} astNodeType - type of node to return or null
* @param {Int} position - character offset
* @return {Object} ast object given by the compiler
* @param astNodeType Type of node to return or null.
* @param position Character offset where AST node should be located.
*/
nodesAtPosition
(
astNodeType
:
string
|
null
,
position
:
Location
,
ast
:
AstNode
):
Array
<
AstNode
>
{
const
astWalker
=
new
AstWalker
()
...
...
@@ -70,6 +99,12 @@ export class SourceMappings {
return
found
;
}
/**
* Retrieve the first "astNodeType" that includes the source map at arg instIndex, or "null" if none found.
*
* @param astNodeType nodeType that a found ASTNode must be. Use "null" if any ASTNode can match.
* @param sourceLocation "src" location that the AST node must match.
*/
findNodeAtSourceLocation
(
astNodeType
:
string
|
undefined
,
sourceLocation
:
Location
,
ast
:
AstNode
|
null
):
AstNode
|
null
{
const
astWalker
=
new
AstWalker
()
let
found
=
null
;
...
...
@@ -90,4 +125,25 @@ export class SourceMappings {
astWalker
.
walkFull
(
ast
,
callback
);
return
found
;
}
/**
* Retrieve the line/column range position for the given source-mapping string.
*
* @param src Solc "src" object containing attributes {source} and {length}.
*/
srcToLineColumnRange
(
src
:
string
):
LineColRange
{
const
sourceLocation
=
sourceLocationFromSrc
(
src
);
if
(
sourceLocation
.
start
>=
0
&&
sourceLocation
.
length
>=
0
)
{
return
<
LineColRange
>
{
start
:
lineColPositionFromOffset
(
sourceLocation
.
start
,
this
.
lineBreaks
),
end
:
lineColPositionFromOffset
(
sourceLocation
.
start
+
sourceLocation
.
length
,
this
.
lineBreaks
)
}
}
else
{
return
<
LineColRange
>
{
start
:
null
,
end
:
null
}
}
}
}
remix-astwalker/src/types.ts
View file @
f8e66ad6
// FIXME: should this be renamed to indicate its offset/length orientation?
// Add "reaadonly property"?
export
interface
Location
{
start
:
number
;
length
:
number
;
file
:
number
;
// Would it be clearer to call this a file index?
}
// This is intended to be compatibile with VScode's Position.
// However it is pretty common with other things too.
// Note: File index is missing here
export
interface
LineColPosition
{
readonly
line
:
number
;
readonly
character
:
number
;
}
// This is intended to be compatibile with vscode's Range
// However it is pretty common with other things too.
// Note: File index is missing here
export
interface
LineColRange
{
readonly
start
:
LineColPosition
;
readonly
end
:
LineColPosition
;
}
export
interface
Node
{
ast
?:
AstNode
;
legacyAST
?:
AstNodeLegacy
;
...
...
remix-astwalker/tests/resources/test.sol
0 → 100644
View file @
f8e66ad6
contract test {
int x;
int y;
function set(int _x) returns (int _r)
{
x = _x;
y = 10;
_r = x;
}
function get() returns (uint x, uint y)
{
}
}
remix-astwalker/tests/sourceMappings.ts
View file @
f8e66ad6
import
tape
from
"tape"
;
import
{
AstNode
,
isAstNode
,
SourceMappings
,
sourceLocationFromAstNode
}
from
"../src"
;
import
{
AstNode
,
isAstNode
,
LineColPosition
,
lineColPositionFromOffset
,
LineColRange
,
Location
,
SourceMappings
,
sourceLocationFromAstNode
,
sourceLocationFromSrc
}
from
"../src"
;
import
node
from
"./resources/newAST"
;
tape
(
"SourceMappings"
,
(
t
:
tape
.
Test
)
=>
{
const
source
=
node
.
source
;
const
srcMappings
=
new
SourceMappings
(
source
);
t
.
test
(
"SourceMappings conversions"
,
(
st
:
tape
.
Test
)
=>
{
st
.
plan
(
9
);
const
loc
=
<
Location
>
{
start
:
32
,
length
:
6
,
file
:
0
};
const
ast
=
node
.
ast
;
st
.
deepEqual
(
lineColPositionFromOffset
(
0
,
srcMappings
.
lineBreaks
),
<
LineColPosition
>
{
line
:
1
,
character
:
1
},
"lineColPositionFromOffset degenerate case"
);
st
.
deepEqual
(
lineColPositionFromOffset
(
200
,
srcMappings
.
lineBreaks
),
<
LineColPosition
>
{
line
:
17
,
character
:
1
},
"lineColPositionFromOffset conversion"
);
/* Typescript will keep us from calling sourceLocationFromAstNode
with the wrong type. However, for non-typescript uses, we add
this test which casts to an AST to check that there is a
run-time check in walkFull.
*/
st
.
notOk
(
sourceLocationFromAstNode
(
<
AstNode
>
null
),
"sourceLocationFromAstNode rejects an invalid astNode"
);
st
.
deepEqual
(
sourceLocationFromAstNode
(
ast
.
nodes
[
0
]),
{
start
:
0
,
length
:
31
,
file
:
0
},
"sourceLocationFromAstNode extracts a location"
);
st
.
deepEqual
(
sourceLocationFromSrc
(
"32:6:0"
),
loc
,
"sourceLocationFromSrc conversion"
);
const
startLC
=
<
LineColPosition
>
{
line
:
6
,
character
:
6
};
st
.
deepEqual
(
srcMappings
.
srcToLineColumnRange
(
"45:96:0"
),
<
LineColRange
>
{
start
:
startLC
,
end
:
<
LineColPosition
>
{
line
:
11
,
character
:
6
}
},
"srcToLineColumnRange end of line"
);
st
.
deepEqual
(
srcMappings
.
srcToLineColumnRange
(
"45:97:0"
),
<
LineColRange
>
{
start
:
startLC
,
end
:
<
LineColPosition
>
{
line
:
12
,
character
:
1
}
},
"srcToLineColumnRange beginning of next line"
);
st
.
deepEqual
(
srcMappings
.
srcToLineColumnRange
(
"45:98:0"
),
<
LineColRange
>
{
start
:
startLC
,
end
:
<
LineColPosition
>
{
line
:
13
,
character
:
1
}
},
"srcToLineColumnRange skip over empty line"
);
st
.
deepEqual
(
srcMappings
.
srcToLineColumnRange
(
"-1:0:0"
),
<
LineColRange
>
{
start
:
null
,
end
:
null
},
"srcToLineColumnRange invalid range"
);
st
.
end
();
});
t
.
test
(
"SourceMappings constructor"
,
(
st
:
tape
.
Test
)
=>
{
st
.
plan
(
2
)
st
.
plan
(
2
)
;
st
.
equal
(
srcMappings
.
source
,
source
,
"sourceMappings object has source-code string"
);
st
.
deepEqual
(
srcMappings
.
lineBreaks
,
[
15
,
26
,
27
,
38
,
39
,
81
,
87
,
103
,
119
,
135
,
141
,
142
,
186
,
192
,
193
,
199
],
...
...
@@ -14,19 +74,9 @@ tape("SourceMappings", (t: tape.Test) => {
st
.
end
();
});
t
.
test
(
"SourceMappings functions"
,
(
st
:
tape
.
Test
)
=>
{
// st.plan(2)
st
.
plan
(
5
);
const
ast
=
node
.
ast
;
st
.
deepEqual
(
sourceLocationFromAstNode
(
ast
.
nodes
[
0
]),
{
start
:
0
,
length
:
31
,
file
:
0
},
"sourceLocationFromAstNode extracts a location"
);
/* Typescript will keep us from calling sourceLocationFromAstNode
with the wrong type. However, for non-typescript uses, we add
this test which casts to an AST to check that there is a
run-time check in walkFull.
*/
st
.
notOk
(
sourceLocationFromAstNode
(
<
AstNode
>
null
),
"sourceLocationFromAstNode rejects an invalid astNode"
);
const
loc
=
{
start
:
267
,
length
:
20
,
file
:
0
};
let
astNode
=
srcMappings
.
findNodeAtSourceLocation
(
'ExpressionStatement'
,
loc
,
ast
);
st
.
ok
(
isAstNode
(
astNode
),
"findsNodeAtSourceLocation finds something"
);
...
...
@@ -36,7 +86,6 @@ tape("SourceMappings", (t: tape.Test) => {
let
astNodes
=
srcMappings
.
nodesAtPosition
(
null
,
loc
,
ast
);
st
.
equal
(
astNodes
.
length
,
2
,
"nodesAtPosition should find more than one astNode"
);
st
.
ok
(
isAstNode
(
astNodes
[
0
]),
"nodesAtPosition returns only AST nodes"
);
// console.log(astNodes[0]);
astNodes
=
srcMappings
.
nodesAtPosition
(
"ExpressionStatement"
,
loc
,
ast
);
st
.
equal
(
astNodes
.
length
,
1
,
"nodesAtPosition filtered to a single nodeType"
);
st
.
end
();
...
...
remix-astwalker/tsconfig.json
View file @
f8e66ad6
{
"include"
:
[
"src"
],
"exclude"
:
[
"node_modules"
,
"src/@types"
],
"compilerOptions"
:
{
/*
Basic
Options
*/
"target"
:
"es5"
,
/*
Specify
ECMAScript
target
version
:
'ES
3
'
(default)
,
'ES
5
'
,
'ES
2015
'
,
'ES
2016
'
,
'ES
2017
'
,
'ES
2018
'
or
'ESNEXT'.
*/
...
...
@@ -8,6 +9,7 @@
"declaration"
:
true
,
/*
Generates
corresponding
'.d.ts'
file.
*/
"sourceMap"
:
true
,
/*
Generates
corresponding
'.map'
file.
*/
"outDir"
:
"./dist"
,
/*
Redirect
output
structure
to
the
directory.
*/
/*
Strict
Type-Checking
Options
*/
"strict"
:
true
,
/*
Enable
all
strict
type-checking
options.
*/
"noImplicitAny"
:
false
,
/*
Raise
error
on
expressions
and
declarations
with
an
implied
'any'
type.
*/
...
...
@@ -15,7 +17,7 @@
/*
Module
Resolution
Options
*/
"baseUrl"
:
"./src"
,
/*
Base
directory
to
resolve
non-absolute
module
names.
*/
"paths"
:
{
"remix-tests"
:
[
"./"
]
},
/*
A
series
of
entries
which
re-map
imports
to
lookup
locations
relative
to
the
'baseUrl'.
*/
"typeRoots"
:
[
"
node_modules/@types"
],
/*
List
of
folders
to
include
type
definitions
from.
*/
"typeRoots"
:
[
"
./@types"
,
"node_modules/@types"
],
/*
List
of
folders
to
include
type
definitions
from.
*/
"esModuleInterop"
:
true
,
/*
Enables
emit
interoperability
between
CommonJS
and
ES
Modules
via
creation
of
namespace
objects
for
all
imports.
Implies
'allowSyntheticDefaultImports'.
*/
"types"
:
[
"node"
...
...
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