5

In an earlier question Here I asked in general about the symbol table for an Apex class.

Using the Tooling API wrapper from Here I am able to get part way there. But am unGodly confused.

If I go to the developer console, query editor, check the "Use Tooling API" box and run this query:

Select Id, Name, symbolTable FROM ApexClass Where Name Like '%NewCaseListController%'

I get back an ID, Name and [object Object] for the symbol table, meaning there is a symbol table object there.

But if I try the same query in Apex code in the execute anonymous window I get the error:

System.CalloutException: Web service callout failed: Unable to parse callout response. Apex type not found for element location

If I do this in Apex I can get a result back, and according to the code for the class the result should be of type ToolingAPIWSDL.QueryResult. The QueryResult should contain a member consisting of a list of sObject_x records sObject_x[], unless I am mis-reading what that means.

ToolingAPIWSDL.QueryResult result = tooley.query('select Id, Name from ApexClass WHERE Name Like \'NewCaseListController\'');

I can take the result and apparently put the sObject_x object in it like this:

List<ToolingAPIWSDL.sObject_x> objList = new List<ToolingAPIWSDL.sObject_x>();
for(Integer i = 0; i<result.records.size(); i++){
    objList.add(result.records[i]);
}

At least that does not throw an error and I can write: System.debug('objList: ' + objList[0]);

And get a result, but how do I access the symbol table? Or more to the point, how can I get a list of methods and variables? I am assuming the symbolTable is the only way?

1 Answer 1

6

You can't use Tooling API SOQL queries directly in Apex. Currently they would need to be passed out the the SOAP or REST API's.

The challenge with the SOAP version of the Tooling API will be creating an Apex class to represent both the ApexClass and they SymbolTable as returned in the SOAP response.

I got part way there with the SOAP API:

ToolingAPIWSDL.SforceService toolingService = new ToolingAPIWSDL.SforceService();
toolingService.SessionHeader = new ToolingAPIWSDL.SessionHeader_element();
toolingService.SessionHeader.SessionId = UserInfo.getSessionId();
toolingService.endpoint_x = URL.getSalesforceBaseUrl().toExternalForm() + '/services/Soap/T/33.0';

ToolingAPIWSDL.QueryResult result = toolingService.query('select Id, Name from ApexClass WHERE Id = \'01p28000005irLNAAY\'');
for(ToolingAPIWSDL.sObject_x acx : result.records) {
    System.debug(acx);
}

The problem is that when you add the SymbolTable to the SOQL query you get the error:

System.CalloutException: Web service callout failed: Unable to parse callout response. Apex type not found for element location line: 4627,

This is around the representation of SymbolTable in ToolingAPIWSDL and the methods>location element that comes back in the response. Or more specifically, the Method class doesn't have the required elements. You will need to expand that out to make more progress down this path.

Something like:

public class Method {
    public ToolingAPIWSDL.Position location;
    public String[] modifiers;
    public String name;
    public ToolingAPIWSDL.Position[] references;
    public String type_x;
    private String[] location_type_info = new String[]{'location','urn:tooling.soap.sforce.com','Position','1','1','false'};
    private String[] modifiers_type_info = new String[]{'modifiers','urn:tooling.soap.sforce.com','string','0','-1','false'};
    private String[] name_type_info = new String[]{'name','urn:tooling.soap.sforce.com','string','1','1','false'};
    private String[] references_type_info = new String[]{'references','urn:tooling.soap.sforce.com','Position','0','-1','false'};
    private String[] type_x_type_info = new String[]{'type','urn:tooling.soap.sforce.com','string','1','1','false'};
    public String visibility;
    private String[] visibility_type_info = new String[]{'visibility','urn:tooling.soap.sforce.com','SymbolVisibility','1','1','false'};
    public ToolingAPIWSDL.Parameter[] parameters;
    private String[] parameters_type_info = new String[]{'parameters','urn:tooling.soap.sforce.com','Parameter','0','-1','false'};
    public String returnType;
    private String[] returnType_type_info = new String[]{'returnType','urn:tooling.soap.sforce.com','string','1','1','false'};
    private String[] apex_schema_type_info = new String[]{'urn:tooling.soap.sforce.com','true','false'};
    private String[] field_order_type_info = new String[]{'location','modifiers','name','references','type_x','visibility','parameters','returnType'};
}

This now brings back the sObject_x record that contains the Symbol table.


An alternative is to use the REST version of the Tooling API.

In Workbench - REST Explorer:

/services/data/v36.0/tooling/query/?q=Select+Id,Name,SymbolTable+From+ApexClass+where+Id='01p40000000IQrsAAG'

You would then need to parse the SymbolTable out of the REST Response. Something like Json2Apex would be useful here.

enter image description here

1
  • 2
    I ended up using the REST API version, Workbench makes it really easy to see the structure of the returned data, from there it looks pretty simple, thanks.
    – ScottH7a9
    Apr 8, 2016 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .