add new parser

pull/2908/head
filip mertens 2 years ago
parent 52386ff94d
commit 6380739517
  1. 7
      apps/remix-ide/src/app/plugins/parser/code-parser.tsx
  2. 44
      apps/remix-ide/src/app/plugins/parser/services/code-parser-antlr-service.ts
  3. 42251
      apps/remix-ide/src/assets/js/parser/index.iife.js
  4. 7
      apps/remix-ide/src/assets/js/parser/index.iife.js.map
  5. 2
      apps/remix-ide/src/index.html
  6. 12
      libs/remix-ui/editor/src/lib/providers/completionProvider.ts

@ -90,7 +90,10 @@ export class CodeParser extends Plugin {
async handleChangeEvents() { async handleChangeEvents() {
const completionSettings = await this.call('config', 'getAppParameter', 'auto-completion') const completionSettings = await this.call('config', 'getAppParameter', 'auto-completion')
if (completionSettings) { if (completionSettings) {
await this.antlrService.getCurrentFileAST() // current timestamp
console.log('get ast', Date.now())
//this.antlrService.getCurrentFileAST()
console.log('done', Date.now())
} }
const showGasSettings = await this.call('config', 'getAppParameter', 'show-gas') const showGasSettings = await this.call('config', 'getAppParameter', 'show-gas')
const showErrorSettings = await this.call('config', 'getAppParameter', 'display-errors') const showErrorSettings = await this.call('config', 'getAppParameter', 'display-errors')
@ -551,7 +554,7 @@ export class CodeParser extends Plugin {
async getNodeLink(node: genericASTNode) { async getNodeLink(node: genericASTNode) {
const lineColumn = await this.getLineColumnOfNode(node) const lineColumn = await this.getLineColumnOfNode(node)
const position = await this.positionOfDefinition(node) const position = await this.positionOfDefinition(node)
if (this.compilerAbstract && this.compilerAbstract.source) { if (this.compilerAbstract && this.compilerAbstract.source && position) {
const fileName = this.compilerAbstract.getSourceName(position.file) const fileName = this.compilerAbstract.getSourceName(position.file)
return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null
} }

@ -33,7 +33,7 @@ export default class CodeParserAntlrService {
if (!this.plugin.currentFile) return if (!this.plugin.currentFile) return
const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile) const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile)
try { try {
const ast = await this.parseSolidity(fileContent) const ast = (SolidityParser as any).parse(fileContent, { loc: true, range: true, tolerant: true })
this.plugin.antlrParserResult = ast this.plugin.antlrParserResult = ast
} catch (e) { } catch (e) {
// do nothing // do nothing
@ -127,6 +127,22 @@ export default class CodeParserAntlrService {
} }
return lastNode return lastNode
} }
/*
* get the code blocks of the current file
*/
async getCurrentFileBlocks(text: string | null = null) {
this.plugin.currentFile = await this.plugin.call('fileManager', 'file')
if (this.plugin.currentFile && this.plugin.currentFile.endsWith('.sol')) {
if (!this.plugin.currentFile) return
const fileContent = text || await this.plugin.call('fileManager', 'readFile', this.plugin.currentFile)
try {
const blocks = (SolidityParser as any).parseBlock(fileContent, { loc: true, range: true, tolerant: true })
return blocks
} catch (e) {
// do nothing
}
}
}
/** /**
* Returns the block surrounding the given position * Returns the block surrounding the given position
@ -136,23 +152,21 @@ export default class CodeParserAntlrService {
* @return {any} * @return {any}
* */ * */
async getANTLRBlockAtPosition(position: any, text: string = null) { async getANTLRBlockAtPosition(position: any, text: string = null) {
await this.getCurrentFileAST(text) const blocks = await this.getCurrentFileBlocks(text)
const allowedTypes = ['SourceUnit', 'ContractDefinition', 'FunctionDefinition'] const walkAst = (blocks) => {
const walkAst = (node: any) => { let nodeFound = null
if (node.loc.start.line <= position.lineNumber && node.loc.end.line >= position.lineNumber) { for(const object of blocks){
const children = node.children || node.subNodes if(object.start <= position && object.end >= position){
if (children && allowedTypes.indexOf(node.type) !== -1) { nodeFound = object
for (const child of children) { break
const result = walkAst(child)
if (result) return result
}
} }
return node
} }
return null return nodeFound
} }
if (!this.plugin.antlrParserResult) return if (!blocks) return
return walkAst(this.plugin.antlrParserResult) const block = walkAst(blocks)
console.log(block)
return block
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -41,7 +41,7 @@
<script type="text/javascript" src="assets/js/loader.js"></script> <script type="text/javascript" src="assets/js/loader.js"></script>
<script src="https://kit.fontawesome.com/41dd021e94.js" crossorigin="anonymous"></script> <script src="https://kit.fontawesome.com/41dd021e94.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/intro.min.js"></script> <script type="text/javascript" src="assets/js/intro.min.js"></script>
<script type="text/javascript" src="assets/js/parser/antlr.js"></script> <script type="text/javascript" src="assets/js/parser/index.iife.js"></script>
</body> </body>
</html> </html>

@ -228,12 +228,10 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
} }
} }
private getBlockNodesAtPosition = async (position: Position) => { private getBlockNodesAtPosition = async (position: Position, ANTLRBlock) => {
let nodes: any[] = [] let nodes: any[] = []
const cursorPosition = this.props.editorAPI.getCursorPosition() const cursorPosition = this.props.editorAPI.getCursorPosition()
const nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', cursorPosition) const nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', cursorPosition)
// try to get the block from ANTLR of which the position is in
const ANTLRBlock = await this.props.plugin.call('codeParser', 'getANTLRBlockAtPosition', position, null)
// if the block has a name and a type we can maybe find it in the contract nodes // if the block has a name and a type we can maybe find it in the contract nodes
const fileNodes = await this.props.plugin.call('codeParser', 'getCurrentFileNodes') const fileNodes = await this.props.plugin.call('codeParser', 'getCurrentFileNodes')
@ -275,7 +273,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
nodes = nodes.filter(node => { nodes = nodes.filter(node => {
if (node.src) { if (node.src) {
const position = sourceMappingDecoder.decode(node.src) const position = sourceMappingDecoder.decode(node.src)
if (position.start >= ANTLRBlock.range[0] && (position.start + position.length) <= ANTLRBlock.range[1]) { if (position.start >= ANTLRBlock.start && (position.start + position.length) <= ANTLRBlock.end) {
return true return true
} }
} }
@ -291,10 +289,10 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
const cursorPosition = this.props.editorAPI.getCursorPosition() const cursorPosition = this.props.editorAPI.getCursorPosition()
let nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', cursorPosition) let nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', cursorPosition)
// if no nodes exits at position, try to get the block of which the position is in // if no nodes exits at position, try to get the block of which the position is in
const block = await this.props.plugin.call('codeParser', 'getANTLRBlockAtPosition', position, null) const block = await this.props.plugin.call('codeParser', 'getANTLRBlockAtPosition', cursorPosition, null)
if (!nodesAtPosition.length) { if (!nodesAtPosition.length) {
if (block) { if (block) {
nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', block.range[0]) nodesAtPosition = await this.props.plugin.call('codeParser', 'nodesAtPosition', block.start)
} }
} }
// find the contract and get the nodes of the contract and the base contracts and imports // find the contract and get the nodes of the contract and the base contracts and imports
@ -309,7 +307,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
nodes = [...Object.values(contractNodes.baseNodesWithBaseContractScope), ...nodes] nodes = [...Object.values(contractNodes.baseNodesWithBaseContractScope), ...nodes]
nodes = [...Object.values(fileNodes.imports), ...nodes] nodes = [...Object.values(fileNodes.imports), ...nodes]
// at the nodes at the block itself // at the nodes at the block itself
nodes = [...nodes, ...await this.getBlockNodesAtPosition(position)] nodes = [...nodes, ...await this.getBlockNodesAtPosition(position, block)]
// filter private nodes, only allow them when contract ID is the same as the current contract // filter private nodes, only allow them when contract ID is the same as the current contract
nodes = nodes.filter(node => { nodes = nodes.filter(node => {
if (node.visibility) { if (node.visibility) {

Loading…
Cancel
Save