public static bool IsExternalFunctionCall(TranslatorContext context, FunctionCall node) { if (node.Expression is MemberAccess memberAccess) { if (memberAccess.Expression is Identifier identifier) { if (identifier.Name == "this") { return(true); } if (identifier.Name == "super") { return(true); } if (!context.HasASTNodeId(identifier.ReferencedDeclaration)) { return(true); } var contract = context.GetASTNodeById(identifier.ReferencedDeclaration) as ContractDefinition; if (contract == null) { return(true); } } else if (memberAccess.Expression is MemberAccess structSelect) { //a.b.c.foo(...) //TODO: do we want to check that the contract the struct variable is declared // is not in the "context"? Why this isn't done for IndexAccess? return(true); } else if (memberAccess.Expression.ToString().Equals("msg.sender")) { // calls can be of the form "msg.sender.call()" or "msg.sender.send()" or "msg.sender.transfer()" return(true); } else if (memberAccess.Expression is FunctionCall) { // TODO: example? return(true); } else if (memberAccess.Expression is IndexAccess) { //a[i].foo(..) return(true); } else if (memberAccess.Expression is TupleExpression) { return(true); } } return(false); }