def execute(self): data = self.params.get("data", None) # example of data: # # public with sharing class AUTOTEST { # String someString; # public String myPublicString { get; set; } # public AUTOTEST(String foo , Boolean bar) { # ApexPages.StandardController c; # c.cancel(); # String s = 'foo'; # s. if data == None: raise MMException('Please provide data') typedef = parsehelp.get_type_definition(data) return util.generate_success_response(list(typedef), "array")
def execute(self): data = self.params.get("data", None) word = self.params.get("word", None) file_name = self.params.get("file_name", None) # example of data: # # public with sharing class AUTOTEST { # String someString; # public String myPublicString { get; set; } # public AUTOTEST(String foo , Boolean bar) { # ApexPages.StandardController c; # c.cancel(); # String s = 'foo'; # s. if data == None: raise MMException('Please provide data') if file_name == None: raise MMException('Please provide file_name') apex_completions = util.parse_json_from_file(os.path.join(config.base_path, config.support_dir, "sforce", "metadata", "apex.json")) typedef = parsehelp.get_type_definition(data) debug('autocomplete type definition: ') debug(typedef) if '<' not in typedef[2] and '[' not in typedef[2]: if '.' in typedef[2] and '<' not in typedef[2]: type_parts = typedef[2].split('.') typedef_class = type_parts[0] #e.g. ApexPages typedef_class_lower = typedef_class.lower() typedef_class_extra = type_parts[1] #e.g. StandardController typedef_class_extra_lower = typedef_class_extra.lower() else: typedef_class = typedef[2] #e.g. ApexPages typedef_class_lower = typedef_class.lower() typedef_class_extra = typedef[4].replace('.','') #e.g. StandardController typedef_class_extra_lower = typedef_class_extra.lower() if '<' in typedef_class: typedef_class_lower = re.sub('\<.*?\>', '', typedef_class_lower) typedef_class_lower = re.sub('\<', '', typedef_class_lower) typedef_class_lower = re.sub('\>', '', typedef_class_lower) typedef_class = re.sub('\<.*?\>', '', typedef_class) typedef_class = re.sub('\<', '', typedef_class) typedef_class = re.sub('\>', '', typedef_class) if '[' in typedef_class: typedef_class_lower = re.sub('\[.*?\]', '', typedef_class_lower) typedef_class = re.sub('\[.*?\]', '', typedef_class) else: if '<' in typedef[2]: typedef_class = typedef[2].split('<')[0] elif '[' in typedef[2]: typedef_class = typedef[2].split('[')[0] typedef_class_lower = typedef_class.lower() typedef_class_extra = '' typedef_class_extra_lower = '' debug('autocomplete type: ') debug(typedef_class) #String debug('autocomplete type extra: ') debug(typedef_class_extra) #String if word != None and word == 'Page' and os.path.isdir(os.path.join(config.project.location,"src","pages")): for (dirpath, dirnames, filenames) in os.walk(os.path.join(config.project.location,"src","pages")): for f in filenames: if '-meta.xml' in f: continue base_page_name = f.replace(".page", "") completions.append({ 'type' : "Visualforce Page", 'name' : base_page_name }) return util.generate_success_response(completions, 'array') if len(typedef[4]) > 1 and '.' in typedef[4]: #deeply nested, need to look for properties #TODO return util.generate_success_response([], 'array') # # Is typedef_class a STANDARD Apex class? # apex_class_key = typedef_class if apex_class_key == 'DateTime': apex_class_key = 'Datetime' if apex_class_key in apex_completions["publicDeclarations"] and typedef_class_extra_lower == '': apex_class_key = word if apex_class_key == 'DateTime': apex_class_key = 'Datetime' comp_def = apex_completions["publicDeclarations"].get(apex_class_key) for i in comp_def: completions.append(i) return util.generate_success_response(sorted(completions), 'array') elif apex_completions["publicDeclarations"].get(apex_class_key) != None: top_level = apex_completions["publicDeclarations"].get(typedef_class) sub_def = top_level.get(word) if sub_def == None: sub_def = top_level.get(typedef_class_extra) completions = get_symbol_table_completions(sub_def) return util.generate_success_response(sorted(completions), 'array') elif apex_class_key in apex_completions["publicDeclarations"]["System"]: if typedef_class == 'DateTime': typedef_class = 'Datetime' if word == typedef_class: #static comp_def = apex_completions["publicDeclarations"]["System"].get(apex_class_key) else: #instance comp_def = apex_completions["publicDeclarations"]["System"].get(typedef_class) completions = get_symbol_table_completions(comp_def) return util.generate_success_response(sorted(completions), 'array') # # Is typedef_class a CUSTOM Apex class? # # HANDLE CUSTOM APEX CLASS STATIC METHODS # e.g. ===> MyCustomClass.doSomethingCool elif word != None and os.path.isfile(os.path.join(config.project.location,"src","classes",word+".cls")): try: completions = get_apex_completions(word) return util.generate_success_response(sorted(completions), 'array') except: return util.generate_success_response([], 'array') if typedef_class_lower == None: return util.generate_success_response([], 'array') # HANDLE CUSTOM APEX INSTANCE METHOD ## # MyClass foo = new MyClass() # e.g. ===> foo.?? # TODO: do we still need this given the existence of symbol tables, i don't think so? # clazz = parsehelp.extract_class(data) # inheritance = parsehelp.extract_inheritance(data, clazz) # if inheritance != None: # if os.path.isfile(os.path.join(config.project.location,"src","classes",inheritance+".cls")): #=> apex classes # completions = util.get_apex_completions(inheritance, typedef_class) # return sorted(completions) # get symbol table for the seed file symbol_table = get_symbol_table(file_name) if symbol_table != None and "innerClasses" in symbol_table and type(symbol_table["innerClasses"] is list and len(symbol_table["innerClasses"]) > 0): for ic in symbol_table["innerClasses"]: if ic["name"].lower() == typedef_class_lower: completions = get_completions_for_inner_class(ic) return util.generate_success_response(sorted(completions), 'array') if os.path.isfile(os.path.join(config.project.location,"src","classes",typedef_class+".cls")): #=> apex classes completions = get_apex_completions(typedef_class, typedef_class_extra) return util.generate_success_response(sorted(completions), 'array') #TODO: finish return util.generate_success_response([], 'array') if typedef_class.endswith('__r'): typedef_class = typedef_class.replace('__r', '__c') if os.path.isfile(os.path.join(config.project.location,"src","objects",typedef_class+".object")): #=> object fields from src directory (more info on field metadata, so is primary) object_dom = parse(os.path.join(config.project.location,"src","objects",typedef_class+".object")) for node in object_dom.getElementsByTagName('fields'): field_name = '' field_type = '' for child in node.childNodes: if child.nodeName != 'fullName' and child.nodeName != 'type': continue if child.nodeName == 'fullName': field_name = child.firstChild.nodeValue elif child.nodeName == 'type': field_type = child.firstChild.nodeValue completions.append((field_name+" \t"+field_type, field_name)) return sorted(completions) elif os.path.isfile(os.path.join(config.project.location,"config",".org_metadata")) and settings.get('mm_use_org_metadata_for_completions', False): #=> parse org metadata, looking for object fields jsonData = util.parse_json_from_file(os.path.join(config.project.location,"config",".org_metadata")) for metadata_type in jsonData: if 'xmlName' in metadata_type and metadata_type['xmlName'] == 'CustomObject': for object_type in metadata_type['children']: if 'text' in object_type and object_type['text'].lower() == typedef_class_lower: for attr in object_type['children']: if 'text' in attr and attr['text'] == 'fields': for field in attr['children']: completions.append((field['text'], field['text'])) if len(completions) == 0 and '__c' in typedef_class_lower: try: #need to index custom objects here, because it couldnt be found if len(ThreadTracker.get_pending_mm_panel_threads(sublime.active_window())) == 0: params = { 'metadata_types' : ['CustomObject'] } mm.call('refresh_metadata_index', False, params=params) except: debug('Failed to index custom object metadata') else: completions.append(('Id', 'Id')) return (sorted(completions), completion_flags) else: return []