@ -1,37 +1,85 @@
'use strict'
'use strict'
import { Plugin } from '@remixproject/engine'
import { Plugin } from '@remixproject/engine'
import { sourceMappingDecoder } from '@remix-project/remix-debug'
import { sourceMappingDecoder } from '@remix-project/remix-debug'
import { CompilerAbstract } from '@remix-project/remix-solidity'
import { CompilerAbstract } from '@remix-project/remix-solidity'
import { CompilationResult } from '@remix-project/remix-solidity'
import { CompilationResult } from '@remix-project/remix-solidity'
import CodeParserGasService from './services/code-parser-gas-service'
import CodeParserGasService from './services/code-parser-gas-service'
import CodeParserCompiler from './services/code-parser-compiler'
import CodeParserCompiler from './services/code-parser-compiler'
import CodeParserAntlrService from './services/code-parser-antlr-service'
import CodeParserAntlrService from './services/code-parser-antlr-service'
import CodeParserImports , { CodeParserImportsData } from './services/code-parser-imports'
import CodeParserImports , {
CodeParserImportsData
} from './services/code-parser-imports'
import React from 'react'
import React from 'react'
import { Profile } from '@remixproject/plugin-utils'
import { Profile } from '@remixproject/plugin-utils'
import { ContractDefinitionAstNode , EventDefinitionAstNode , FunctionCallAstNode , FunctionDefinitionAstNode , IdentifierAstNode , ImportDirectiveAstNode , ModifierDefinitionAstNode , SourceUnitAstNode , StructDefinitionAstNode , VariableDeclarationAstNode } from '@remix-project/remix-analyzer'
import {
import { lastCompilationResult , RemixApi } from '@remixproject/plugin-api'
ContractDefinitionAstNode ,
import { antlr } from './types'
EventDefinitionAstNode ,
import { ParseResult } from './types/antlr-types'
FunctionCallAstNode ,
FunctionDefinitionAstNode ,
IdentifierAstNode ,
ImportDirectiveAstNode ,
ModifierDefinitionAstNode ,
SourceUnitAstNode ,
StructDefinitionAstNode ,
VariableDeclarationAstNode
} from '@remix-project/remix-analyzer'
import { lastCompilationResult , RemixApi } from '@remixproject/plugin-api'
import { antlr } from './types'
import { ParseResult } from './types/antlr-types'
const profile : Profile = {
const profile : Profile = {
name : 'codeParser' ,
name : 'codeParser' ,
methods : [ 'nodesAtPosition' , 'getContractNodes' , 'getCurrentFileNodes' , 'getLineColumnOfNode' , 'getLineColumnOfPosition' , 'getFunctionParamaters' , 'getDeclaration' , 'getFunctionReturnParameters' , 'getVariableDeclaration' , 'getNodeDocumentation' , 'getNodeLink' , 'listAstNodes' , 'getANTLRBlockAtPosition' , 'getLastNodeInLine' , 'resolveImports' , 'parseSolidity' , 'getNodesWithScope' , 'getNodesWithName' , 'getNodes' , 'compile' , 'getNodeById' , 'getLastCompilationResult' , 'positionOfDefinition' , 'definitionAtPosition' , 'jumpToDefinition' , 'referrencesAtPosition' , 'referencesOf' , 'getActiveHighlights' , 'gasEstimation' , 'declarationOf' , 'getGasEstimates' , 'getImports' ] ,
methods : [
'nodesAtPosition' ,
'getContractNodes' ,
'getCurrentFileNodes' ,
'getLineColumnOfNode' ,
'getLineColumnOfPosition' ,
'getFunctionParamaters' ,
'getDeclaration' ,
'getFunctionReturnParameters' ,
'getVariableDeclaration' ,
'getNodeDocumentation' ,
'getNodeLink' ,
'listAstNodes' ,
'getANTLRBlockAtPosition' ,
'getLastNodeInLine' ,
'resolveImports' ,
'parseSolidity' ,
'getNodesWithScope' ,
'getNodesWithName' ,
'getNodes' ,
'compile' ,
'getNodeById' ,
'getLastCompilationResult' ,
'positionOfDefinition' ,
'definitionAtPosition' ,
'jumpToDefinition' ,
'referrencesAtPosition' ,
'referencesOf' ,
'getActiveHighlights' ,
'gasEstimation' ,
'declarationOf' ,
'getGasEstimates' ,
'getImports'
] ,
events : [ ] ,
events : [ ] ,
version : '0.0.1'
version : '0.0.1'
}
}
export function isNodeDefinition ( node : genericASTNode ) {
export function isNodeDefinition ( node : genericASTNode ) {
return node . nodeType === 'ContractDefinition' ||
return (
node . nodeType === 'ContractDefinition' ||
node . nodeType === 'FunctionDefinition' ||
node . nodeType === 'FunctionDefinition' ||
node . nodeType === 'ModifierDefinition' ||
node . nodeType === 'ModifierDefinition' ||
node . nodeType === 'VariableDeclaration' ||
node . nodeType === 'VariableDeclaration' ||
node . nodeType === 'StructDefinition' ||
node . nodeType === 'StructDefinition' ||
node . nodeType === 'EventDefinition'
node . nodeType === 'EventDefinition'
)
}
}
export type genericASTNode =
export type genericASTNode =
ContractDefinitionAstNode
| ContractDefinitionAstNode
| FunctionDefinitionAstNode
| FunctionDefinitionAstNode
| ModifierDefinitionAstNode
| ModifierDefinitionAstNode
| VariableDeclarationAstNode
| VariableDeclarationAstNode
@ -51,13 +99,12 @@ interface declarationIndexNode {
}
}
interface codeParserIndex {
interface codeParserIndex {
declarations : declarationIndexNode ,
declarations : declarationIndexNode
flatReferences : flatReferenceIndexNode ,
flatReferences : flatReferenceIndexNode
nodesPerFile : any
nodesPerFile : any
}
}
export class CodeParser extends Plugin {
export class CodeParser extends Plugin {
compilerAbstract : CompilerAbstract
compilerAbstract : CompilerAbstract
currentFile : string
currentFile : string
nodeIndex : codeParserIndex
nodeIndex : codeParserIndex
@ -80,7 +127,6 @@ export class CodeParser extends Plugin {
debuggerIsOn : boolean = false
debuggerIsOn : boolean = false
constructor ( astWalker : any ) {
constructor ( astWalker : any ) {
super ( profile )
super ( profile )
this . astWalker = astWalker
this . astWalker = astWalker
@ -92,31 +138,52 @@ 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 ) {
this . antlrService . enableWorker ( )
this . antlrService . enableWorker ( )
} else {
} else {
this . antlrService . disableWorker ( )
this . antlrService . disableWorker ( )
}
}
const showGasSettings = await this . call ( 'config' , 'getAppParameter' , 'show-gas' )
const showGasSettings = await this . call (
const showErrorSettings = await this . call ( 'config' , 'getAppParameter' , 'display-errors' )
'config' ,
if ( showGasSettings || showErrorSettings || completionSettings || this . debuggerIsOn ) {
'getAppParameter' ,
'show-gas'
)
const showErrorSettings = await this . call (
'config' ,
'getAppParameter' ,
'display-errors'
)
if (
showGasSettings ||
showErrorSettings ||
completionSettings ||
this . debuggerIsOn
) {
await this . compilerService . compile ( )
await this . compilerService . compile ( )
}
}
}
}
async onActivation() {
async onActivation() {
this . gasService = new CodeParserGasService ( this )
this . gasService = new CodeParserGasService ( this )
this . compilerService = new CodeParserCompiler ( this )
this . compilerService = new CodeParserCompiler ( this )
this . antlrService = new CodeParserAntlrService ( this )
this . antlrService = new CodeParserAntlrService ( this )
this . importService = new CodeParserImports ( this )
this . importService = new CodeParserImports ( this )
this . parseSolidity = this . antlrService . parseSolidity . bind ( this . antlrService )
this . parseSolidity = this . antlrService . parseSolidity . bind ( this . antlrService )
this . getLastNodeInLine = this . antlrService . getLastNodeInLine . bind ( this . antlrService )
this . getLastNodeInLine = this . antlrService . getLastNodeInLine . bind (
this . antlrService
)
this . listAstNodes = this . antlrService . listAstNodes . bind ( this . antlrService )
this . listAstNodes = this . antlrService . listAstNodes . bind ( this . antlrService )
this . getANTLRBlockAtPosition = this . antlrService . getANTLRBlockAtPosition . bind ( this . antlrService )
this . getANTLRBlockAtPosition =
this . setCurrentFileAST = this . antlrService . setCurrentFileAST . bind ( this . antlrService )
this . antlrService . getANTLRBlockAtPosition . bind ( this . antlrService )
this . setCurrentFileAST = this . antlrService . setCurrentFileAST . bind (
this . antlrService
)
this . getImports = this . importService . getImports . bind ( this . importService )
this . getImports = this . importService . getImports . bind ( this . importService )
this . on ( 'editor' , 'didChangeFile' , async ( file ) = > {
this . on ( 'editor' , 'didChangeFile' , async ( file ) = > {
@ -138,7 +205,11 @@ export class CodeParser extends Plugin {
this . on ( 'fileManager' , 'currentFileChanged' , async ( ) = > {
this . on ( 'fileManager' , 'currentFileChanged' , async ( ) = > {
await this . call ( 'editor' , 'discardLineTexts' )
await this . call ( 'editor' , 'discardLineTexts' )
const completionSettings = await this . call ( 'config' , 'getAppParameter' , 'auto-completion' )
const completionSettings = await this . call (
'config' ,
'getAppParameter' ,
'auto-completion'
)
if ( completionSettings ) {
if ( completionSettings ) {
this . antlrService . setCurrentFileAST ( )
this . antlrService . setCurrentFileAST ( )
}
}
@ -173,7 +244,7 @@ export class CodeParser extends Plugin {
} )
} )
}
}
async reload ( ) {
async reload() {
await this . call ( 'editor' , 'discardLineTexts' )
await this . call ( 'editor' , 'discardLineTexts' )
await this . call ( 'fileDecorator' , 'clearFileDecorators' )
await this . call ( 'fileDecorator' , 'clearFileDecorators' )
await this . call ( 'editor' , 'clearErrorMarkers' , [ this . currentFile ] )
await this . call ( 'editor' , 'clearErrorMarkers' , [ this . currentFile ] )
@ -189,7 +260,7 @@ export class CodeParser extends Plugin {
}
}
getSubNodes < T extends genericASTNode > ( node : T ) : number [ ] {
getSubNodes < T extends genericASTNode > ( node : T ) : number [ ] {
return node . nodeType == "ContractDefinition" && node . contractDependencies ;
return node . nodeType == 'ContractDefinition' && node . contractDependencies
}
}
/ * *
/ * *
@ -200,7 +271,11 @@ export class CodeParser extends Plugin {
_buildIndex ( compilationResult : CompilationResult , source ) {
_buildIndex ( compilationResult : CompilationResult , source ) {
if ( compilationResult && compilationResult . sources ) {
if ( compilationResult && compilationResult . sources ) {
const callback = ( node : genericASTNode ) = > {
const callback = ( node : genericASTNode ) = > {
if ( node && ( "referencedDeclaration" in node ) && node . referencedDeclaration ) {
if (
node &&
'referencedDeclaration' in node &&
node . referencedDeclaration
) {
if ( ! this . nodeIndex . declarations [ node . referencedDeclaration ] ) {
if ( ! this . nodeIndex . declarations [ node . referencedDeclaration ] ) {
this . nodeIndex . declarations [ node . referencedDeclaration ] = [ ]
this . nodeIndex . declarations [ node . referencedDeclaration ] = [ ]
}
}
@ -211,9 +286,7 @@ export class CodeParser extends Plugin {
for ( const s in compilationResult . sources ) {
for ( const s in compilationResult . sources ) {
this . astWalker . walkFull ( compilationResult . sources [ s ] . ast , callback )
this . astWalker . walkFull ( compilationResult . sources [ s ] . ast , callback )
}
}
}
}
}
}
// NODE HELPERS
// NODE HELPERS
@ -232,16 +305,32 @@ export class CodeParser extends Plugin {
return '(' + params . toString ( ) + ')'
return '(' + params . toString ( ) + ')'
}
}
_flatNodeList (
_flatNodeList ( contractNode : ContractDefinitionAstNode , fileName : string , inScope : boolean , compilatioResult : any ) {
contractNode : ContractDefinitionAstNode ,
fileName : string ,
inScope : boolean ,
compilatioResult : any
) {
const index = { }
const index = { }
const contractName : string = contractNode . name
const contractName : string = contractNode . name
const callback = ( node ) = > {
const callback = ( node ) = > {
if ( inScope && node . scope !== contractNode . id
if (
&& ! ( node . nodeType === 'EnumDefinition' || node . nodeType === 'EventDefinition' || node . nodeType === 'ModifierDefinition' ) )
inScope &&
node . scope !== contractNode . id &&
! (
node . nodeType === 'EnumDefinition' ||
node . nodeType === 'EventDefinition' ||
node . nodeType === 'ModifierDefinition'
)
)
return
return
if ( inScope ) node . isClassNode = true ;
if ( inScope ) node . isClassNode = true
node . gasEstimate = this . _getContractGasEstimate ( node , contractName , fileName , compilatioResult )
node . gasEstimate = this . _getContractGasEstimate (
node ,
contractName ,
fileName ,
compilatioResult
)
node . functionName = node . name + this . _getInputParams ( node )
node . functionName = node . name + this . _getInputParams ( node )
node . contractName = contractName
node . contractName = contractName
node . contractId = contractNode . id
node . contractId = contractNode . id
@ -251,17 +340,37 @@ export class CodeParser extends Plugin {
return index
return index
}
}
_extractFileNodes ( fileName : string , compilationResult : lastCompilationResult ) {
_extractFileNodes (
if ( compilationResult && compilationResult . data . sources && compilationResult . data . sources [ fileName ] ) {
fileName : string ,
compilationResult : lastCompilationResult
) {
if (
compilationResult &&
compilationResult . data . sources &&
compilationResult . data . sources [ fileName ]
) {
const source = compilationResult . data . sources [ fileName ]
const source = compilationResult . data . sources [ fileName ]
const nodesByContract : any = { }
const nodesByContract : any = { }
nodesByContract . imports = { }
nodesByContract . imports = { }
nodesByContract . contracts = { }
nodesByContract . contracts = { }
this . astWalker . walkFull ( source . ast , async ( node ) = > {
this . astWalker . walkFull ( source . ast , async ( node ) = > {
if ( node . nodeType === 'ContractDefinition' ) {
if ( node . nodeType === 'ContractDefinition' ) {
const flatNodes = this . _flatNodeList ( node , fileName , false , compilationResult )
const flatNodes = this . _flatNodeList (
node . gasEstimate = this . _getContractGasEstimate ( node , node . name , fileName , compilationResult )
node ,
nodesByContract . contracts [ node . name ] = { contractDefinition : node , contractNodes : flatNodes }
fileName ,
false ,
compilationResult
)
node . gasEstimate = this . _getContractGasEstimate (
node ,
node . name ,
fileName ,
compilationResult
)
nodesByContract . contracts [ node . name ] = {
contractDefinition : node ,
contractNodes : flatNodes
}
const baseNodes = { }
const baseNodes = { }
const baseNodesWithBaseContractScope = { }
const baseNodesWithBaseContractScope = { }
if ( node . linearizedBaseContracts ) {
if ( node . linearizedBaseContracts ) {
@ -271,11 +380,12 @@ export class CodeParser extends Plugin {
const callback = ( node ) = > {
const callback = ( node ) = > {
node . contractName = ( baseContract as any ) . name
node . contractName = ( baseContract as any ) . name
node . contractId = ( baseContract as any ) . id
node . contractId = ( baseContract as any ) . id
node . isBaseNode = true ;
node . isBaseNode = true
baseNodes [ node . id ] = node
baseNodes [ node . id ] = node
if ( ( node . scope && node . scope === baseContract . id )
if (
|| node . nodeType === 'EnumDefinition'
( node . scope && node . scope === baseContract . id ) ||
|| node . nodeType === 'EventDefinition'
node . nodeType === 'EnumDefinition' ||
node . nodeType === 'EventDefinition'
) {
) {
baseNodesWithBaseContractScope [ node . id ] = node
baseNodesWithBaseContractScope [ node . id ] = node
}
}
@ -283,7 +393,7 @@ export class CodeParser extends Plugin {
for ( const member of node . members ) {
for ( const member of node . members ) {
member . contractName = ( baseContract as any ) . name
member . contractName = ( baseContract as any ) . name
member . contractId = ( baseContract as any ) . id
member . contractId = ( baseContract as any ) . id
member . isBaseNode = true ;
member . isBaseNode = true
}
}
}
}
}
}
@ -292,14 +402,15 @@ export class CodeParser extends Plugin {
}
}
}
}
nodesByContract . contracts [ node . name ] . baseNodes = baseNodes
nodesByContract . contracts [ node . name ] . baseNodes = baseNodes
nodesByContract . contracts [ node . name ] . baseNodesWithBaseContractScope = baseNodesWithBaseContractScope
nodesByContract . contracts [ node . name ] . baseNodesWithBaseContractScope =
nodesByContract . contracts [ node . name ] . contractScopeNodes = this . _flatNodeList ( node , fileName , true , compilationResult )
baseNodesWithBaseContractScope
nodesByContract . contracts [ node . name ] . contractScopeNodes =
this . _flatNodeList ( node , fileName , true , compilationResult )
}
}
if ( node . nodeType === 'ImportDirective' ) {
if ( node . nodeType === 'ImportDirective' ) {
const imported = await this . resolveImports ( node , { } )
const imported = await this . resolveImports ( node , { } )
for ( const importedNode of ( Object . values ( imported ) as any ) ) {
for ( const importedNode of Object . values ( imported ) as any ) {
if ( importedNode . nodes )
if ( importedNode . nodes )
for ( const subNode of importedNode . nodes ) {
for ( const subNode of importedNode . nodes ) {
nodesByContract . imports [ subNode . id ] = subNode
nodesByContract . imports [ subNode . id ] = subNode
@ -311,9 +422,15 @@ export class CodeParser extends Plugin {
}
}
}
}
_getContractGasEstimate ( node : ContractDefinitionAstNode | FunctionDefinitionAstNode , contractName : string , fileName : string , compilationResult : lastCompilationResult ) {
_getContractGasEstimate (
node : ContractDefinitionAstNode | FunctionDefinitionAstNode ,
const contracts = compilationResult . data . contracts && compilationResult . data . contracts [ this . currentFile ]
contractName : string ,
fileName : string ,
compilationResult : lastCompilationResult
) {
const contracts =
compilationResult . data . contracts &&
compilationResult . data . contracts [ this . currentFile ]
for ( const name in contracts ) {
for ( const name in contracts ) {
if ( name === contractName ) {
if ( name === contractName ) {
const contract = contracts [ name ]
const contract = contracts [ name ]
@ -327,15 +444,21 @@ export class CodeParser extends Plugin {
const fn = fnName + this . _getInputParams ( node )
const fn = fnName + this . _getInputParams ( node )
if ( visibility === 'public' || visibility === 'external' ) {
if ( visibility === 'public' || visibility === 'external' ) {
executionCost = estimationObj === null ? '-' : estimationObj . external [ fn ]
executionCost =
estimationObj === null ? '-' : estimationObj . external [ fn ]
} else if ( visibility === 'private' || visibility === 'internal' ) {
} else if ( visibility === 'private' || visibility === 'internal' ) {
executionCost = estimationObj === null ? '-' : estimationObj . internal [ fn ]
executionCost =
estimationObj === null ? '-' : estimationObj . internal [ fn ]
}
}
return { executionCost }
return { executionCost }
} else {
} else {
return {
return {
creationCost : estimationObj === null ? '-' : estimationObj . creation . totalCost ,
creationCost :
codeDepositCost : estimationObj === null ? '-' : estimationObj . creation . codeDepositCost ,
estimationObj === null ? '-' : estimationObj . creation . totalCost ,
codeDepositCost :
estimationObj === null
? '-'
: estimationObj . creation . codeDepositCost
}
}
}
}
}
}
@ -349,16 +472,38 @@ export class CodeParser extends Plugin {
* @param type
* @param type
* @returns
* @returns
* /
* /
async nodesAtPosition ( position : number , type = '' ) : Promise < genericASTNode [ ] > {
async nodesAtPosition (
position : number ,
type = ''
) : Promise < genericASTNode [ ] > {
let lastCompilationResult = this . compilerAbstract
let lastCompilationResult = this . compilerAbstract
if ( this . debuggerIsOn ) {
if ( this . debuggerIsOn ) {
lastCompilationResult = await this . call ( 'compilerArtefacts' , 'get' , '__last' )
lastCompilationResult = await this . call (
'compilerArtefacts' ,
'get' ,
'__last'
)
this . currentFile = await this . call ( 'fileManager' , 'file' )
this . currentFile = await this . call ( 'fileManager' , 'file' )
}
}
if ( ! lastCompilationResult ) return [ ]
if ( ! lastCompilationResult ) return [ ]
const urlFromPath = await this . call ( 'fileManager' , 'getUrlFromPath' , this . currentFile )
const urlFromPath = await this . call (
if ( lastCompilationResult && lastCompilationResult . languageversion . indexOf ( 'soljson' ) === 0 && lastCompilationResult . data && lastCompilationResult . data . sources && lastCompilationResult . data . sources [ this . currentFile ] ) {
'fileManager' ,
const nodes : genericASTNode [ ] = sourceMappingDecoder . nodesAtPosition ( type , position , lastCompilationResult . data . sources [ this . currentFile ] || lastCompilationResult . data . sources [ urlFromPath . file ] )
'getUrlFromPath' ,
this . currentFile
)
if (
lastCompilationResult &&
lastCompilationResult . languageversion . indexOf ( 'soljson' ) === 0 &&
lastCompilationResult . data &&
lastCompilationResult . data . sources &&
lastCompilationResult . data . sources [ this . currentFile ]
) {
const nodes : genericASTNode [ ] = sourceMappingDecoder . nodesAtPosition (
type ,
position ,
lastCompilationResult . data . sources [ this . currentFile ] ||
lastCompilationResult . data . sources [ urlFromPath . file ]
)
return nodes
return nodes
}
}
return [ ]
return [ ]
@ -383,7 +528,8 @@ export class CodeParser extends Plugin {
* @returns
* @returns
* /
* /
async getDeclaration ( id : number ) {
async getDeclaration ( id : number ) {
if ( this . nodeIndex . declarations && this . nodeIndex . declarations [ id ] ) return this . nodeIndex . declarations [ id ]
if ( this . nodeIndex . declarations && this . nodeIndex . declarations [ id ] )
return this . nodeIndex . declarations [ id ]
}
}
/ * *
/ * *
@ -417,7 +563,7 @@ export class CodeParser extends Plugin {
* @returns
* @returns
* /
* /
declarationOf < T extends genericASTNode > ( node : T ) {
declarationOf < T extends genericASTNode > ( node : T ) {
if ( node && ( 'referencedDeclaration' in node ) && node . referencedDeclaration ) {
if ( node && 'referencedDeclaration' in node && node . referencedDeclaration ) {
return this . nodeIndex . flatReferences [ node . referencedDeclaration ]
return this . nodeIndex . flatReferences [ node . referencedDeclaration ]
}
}
return null
return null
@ -436,7 +582,7 @@ export class CodeParser extends Plugin {
node = nodes [ nodes . length - 1 ]
node = nodes [ nodes . length - 1 ]
nodeDefinition = node
nodeDefinition = node
if ( ! isNodeDefinition ( node ) ) {
if ( ! isNodeDefinition ( node ) ) {
nodeDefinition = await this . declarationOf ( node ) || node
nodeDefinition = ( await this . declarationOf ( node ) ) || node
}
}
if ( node . nodeType === 'ImportDirective' ) {
if ( node . nodeType === 'ImportDirective' ) {
for ( const key in this . nodeIndex . flatReferences ) {
for ( const key in this . nodeIndex . flatReferences ) {
@ -457,29 +603,39 @@ export class CodeParser extends Plugin {
if ( ! nodeDefinition ) nodeDefinition = node
if ( ! nodeDefinition ) nodeDefinition = node
}
}
}
}
if ( nodeDefinition && nodeDefinition . type && nodeDefinition . type === 'Identifier' ) {
if (
nodeDefinition &&
nodeDefinition . type &&
nodeDefinition . type === 'Identifier'
) {
const nodeForIdentifier = await this . findIdentifier ( nodeDefinition )
const nodeForIdentifier = await this . findIdentifier ( nodeDefinition )
if ( nodeForIdentifier ) nodeDefinition = nodeForIdentifier
if ( nodeForIdentifier ) nodeDefinition = nodeForIdentifier
}
}
return nodeDefinition
return nodeDefinition
}
}
}
}
}
}
async getContractNodes ( contractName : string ) {
async getContractNodes ( contractName : string ) {
if ( this . nodeIndex . nodesPerFile
if (
&& this . nodeIndex . nodesPerFile [ this . currentFile ]
this . nodeIndex . nodesPerFile &&
&& this . nodeIndex . nodesPerFile [ this . currentFile ] . contracts [ contractName ]
this . nodeIndex . nodesPerFile [ this . currentFile ] &&
&& this . nodeIndex . nodesPerFile [ this . currentFile ] . contracts [ contractName ] . contractNodes ) {
this . nodeIndex . nodesPerFile [ this . currentFile ] . contracts [ contractName ] &&
return this . nodeIndex . nodesPerFile [ this . currentFile ] . contracts [ contractName ]
this . nodeIndex . nodesPerFile [ this . currentFile ] . contracts [ contractName ]
. contractNodes
) {
return this . nodeIndex . nodesPerFile [ this . currentFile ] . contracts [
contractName
]
}
}
return false
return false
}
}
async getCurrentFileNodes() {
async getCurrentFileNodes() {
if ( this . nodeIndex . nodesPerFile
if (
&& this . nodeIndex . nodesPerFile [ this . currentFile ] ) {
this . nodeIndex . nodesPerFile &&
this . nodeIndex . nodesPerFile [ this . currentFile ]
) {
return this . nodeIndex . nodesPerFile [ this . currentFile ]
return this . nodeIndex . nodesPerFile [ this . currentFile ]
}
}
return false
return false
@ -535,8 +691,6 @@ export class CodeParser extends Plugin {
return imported
return imported
}
}
/ * *
/ * *
*
*
* @param node
* @param node
@ -553,7 +707,7 @@ export class CodeParser extends Plugin {
}
}
}
}
}
}
if ( node && ( "referencedDeclaration" in node ) && node . referencedDeclaration ) {
if ( node && 'referencedDeclaration' in node && node . referencedDeclaration ) {
highlights ( node . referencedDeclaration )
highlights ( node . referencedDeclaration )
const current = this . nodeIndex . flatReferences [ node . referencedDeclaration ]
const current = this . nodeIndex . flatReferences [ node . referencedDeclaration ]
results . push ( current )
results . push ( current )
@ -586,8 +740,6 @@ export class CodeParser extends Plugin {
return this . nodeIndex . flatReferences
return this . nodeIndex . flatReferences
}
}
/ * *
/ * *
*
*
* @param node
* @param node
@ -598,7 +750,9 @@ export class CodeParser extends Plugin {
const position = await this . positionOfDefinition ( node )
const position = await this . positionOfDefinition ( node )
if ( this . compilerAbstract && this . compilerAbstract . source && position ) {
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
}
}
return ''
return ''
}
}
@ -617,8 +771,13 @@ export class CodeParser extends Plugin {
async getLineColumnOfPosition ( position : any ) {
async getLineColumnOfPosition ( position : any ) {
if ( position ) {
if ( position ) {
const fileName = this . compilerAbstract . getSourceName ( position . file )
const fileName = this . compilerAbstract . getSourceName ( position . file )
const lineBreaks = sourceMappingDecoder . getLinebreakPositions ( this . compilerAbstract . source . sources [ fileName ] . content )
const lineBreaks = sourceMappingDecoder . getLinebreakPositions (
const lineColumn = sourceMappingDecoder . convertOffsetToLineColumn ( position , lineBreaks )
this . compilerAbstract . source . sources [ fileName ] . content
)
const lineColumn = sourceMappingDecoder . convertOffsetToLineColumn (
position ,
lineBreaks
)
return lineColumn
return lineColumn
}
}
}
}
@ -629,9 +788,13 @@ export class CodeParser extends Plugin {
* @returns
* @returns
* /
* /
async getNodeDocumentation ( node : genericASTNode ) {
async getNodeDocumentation ( node : genericASTNode ) {
if ( ( "documentation" in node ) && node . documentation && ( node . documentation as any ) . text ) {
if (
let text = '' ;
'documentation' in node &&
( node . documentation as any ) . text . split ( '\n' ) . forEach ( line = > {
node . documentation &&
( node . documentation as any ) . text
) {
let text = ''
; ( node . documentation as any ) . text . split ( '\n' ) . forEach ( ( line ) = > {
text += ` ${ line . trim ( ) } \ n `
text += ` ${ line . trim ( ) } \ n `
} )
} )
return text
return text
@ -644,18 +807,17 @@ export class CodeParser extends Plugin {
* @returns
* @returns
* /
* /
async getVariableDeclaration ( node : any ) {
async getVariableDeclaration ( node : any ) {
const nodeVisibility = node . visibility && node . visibility . length ? node . visibility + ' ' : ''
const nodeVisibility =
node . visibility && node . visibility . length ? node . visibility + ' ' : ''
const nodeName = node . name && node . name . length ? node . name : ''
const nodeName = node . name && node . name . length ? node . name : ''
if ( node . typeDescriptions && node . typeDescriptions . typeString ) {
if ( node . typeDescriptions && node . typeDescriptions . typeString ) {
return ` ${ node . typeDescriptions . typeString } ${ nodeVisibility } ${ nodeName } `
return ` ${ node . typeDescriptions . typeString } ${ nodeVisibility } ${ nodeName } `
} else {
} else {
if ( node . typeName && node . typeName . name ) {
if ( node . typeName && node . typeName . name ) {
return ` ${ node . typeName . name } ${ nodeVisibility } ${ nodeName } `
return ` ${ node . typeName . name } ${ nodeVisibility } ${ nodeName } `
}
} else if ( node . typeName && node . typeName . namePath ) {
else if ( node . typeName && node . typeName . namePath ) {
return ` ${ node . typeName . namePath } ${ nodeVisibility } ${ nodeName } `
return ` ${ node . typeName . namePath } ${ nodeVisibility } ${ nodeName } `
}
} else {
else {
return ` ${ nodeName } ${ nodeName } `
return ` ${ nodeName } ${ nodeName } `
}
}
}
}
@ -667,7 +829,8 @@ export class CodeParser extends Plugin {
* @returns
* @returns
* /
* /
async getFunctionParamaters ( node : any ) {
async getFunctionParamaters ( node : any ) {
const localParam = ( node . parameters && node . parameters . parameters ) || ( node . parameters )
const localParam =
( node . parameters && node . parameters . parameters ) || node . parameters
if ( localParam ) {
if ( localParam ) {
const params = [ ]
const params = [ ]
for ( const param of localParam ) {
for ( const param of localParam ) {
@ -683,7 +846,7 @@ export class CodeParser extends Plugin {
* @returns
* @returns
* /
* /
async getFunctionReturnParameters ( node : any ) {
async getFunctionReturnParameters ( node : any ) {
const localParam = ( node . returnParameters && node . returnParameters . parameters )
const localParam = node . returnParameters && node . returnParameters . parameters
if ( localParam ) {
if ( localParam ) {
const params = [ ]
const params = [ ]
for ( const param of localParam ) {
for ( const param of localParam ) {
@ -692,7 +855,4 @@ export class CodeParser extends Plugin {
return ` ( ${ params . join ( ', ' ) } ) `
return ` ( ${ params . join ( ', ' ) } ) `
}
}
}
}
}
}