def MakeSignature( s ): def GetTSDocs( docs_list ): return '\n'.join( item[ 'text' ] for item in docs_list ) label = _DisplayPartsToString( s[ 'prefixDisplayParts' ] ) parameters = [] sep = _DisplayPartsToString( s[ 'separatorDisplayParts' ] ) for index, p in enumerate( s[ 'parameters' ] ): param = _DisplayPartsToString( p[ 'displayParts' ] ) start = len( label ) end = start + len( param ) label += param if index < len( s[ 'parameters' ] ) - 1: label += sep parameters.append( { 'documentation': GetTSDocs( p.get( 'documentation', [] ) ), 'label': [ utils.CodepointOffsetToByteOffset( label, start ), utils.CodepointOffsetToByteOffset( label, end ) ] } ) label += _DisplayPartsToString( s[ 'suffixDisplayParts' ] ) return { 'documentation': GetTSDocs( s.get( 'documentation', [] ) ), 'label': label, 'parameters': parameters }
def _TsDiagnosticToYcmdDiagnostic(self, request_data, ts_diagnostic): filepath = request_data['filepath'] ts_fixes = self._SendRequest( 'getCodeFixes', { 'file': filepath, 'startLine': ts_diagnostic['startLocation']['line'], 'startOffset': ts_diagnostic['startLocation']['offset'], 'endLine': ts_diagnostic['endLocation']['line'], 'endOffset': ts_diagnostic['endLocation']['offset'], 'errorCodes': [ts_diagnostic['code']] }) location = responses.Location(request_data['line_num'], request_data['column_num'], filepath) fixits = [] for fix in ts_fixes: description = fix['description'] # TSServer returns these fixits for every error in JavaScript files. # Ignore them since they are not useful. if description in [ 'Ignore this error message', 'Disable checking for this file' ]: continue fixit = responses.FixIt( location, _BuildFixItForChanges(request_data, fix['changes']), description) fixits.append(fixit) contents = GetFileLines(request_data, filepath) ts_start_location = ts_diagnostic['startLocation'] ts_start_line = ts_start_location['line'] start_offset = utils.CodepointOffsetToByteOffset( contents[ts_start_line - 1], ts_start_location['offset']) ts_end_location = ts_diagnostic['endLocation'] ts_end_line = ts_end_location['line'] end_offset = utils.CodepointOffsetToByteOffset( contents[ts_end_line - 1], ts_end_location['offset']) location_start = responses.Location(ts_start_line, start_offset, filepath) location_end = responses.Location(ts_end_line, end_offset, filepath) location_extent = responses.Range(location_start, location_end) return responses.Diagnostic([location_extent], location_start, location_extent, ts_diagnostic['message'], 'ERROR', fixits=fixits)
def CodepointOffsetToByteOffset_test(): # Tuples of ( ( unicode_line_value, codepoint_offset ), expected_result ). tests = [ # Simple ascii strings. (('test', 1), 1), (('test', 4), 4), (('test', 5), 5), # Unicode char at beginning. (('†est', 1), 1), (('†est', 2), 4), (('†est', 4), 6), (('†est', 5), 7), # Unicode char at end. (('tes†', 1), 1), (('tes†', 2), 2), (('tes†', 4), 4), (('tes†', 5), 7), # Unicode char in middle. (('tes†ing', 1), 1), (('tes†ing', 2), 2), (('tes†ing', 4), 4), (('tes†ing', 5), 7), (('tes†ing', 7), 9), (('tes†ing', 8), 10), # Converts bytes to Unicode. ((utils.ToBytes('†est'), 2), 4) ] for test in tests: yield lambda: eq_(utils.CodepointOffsetToByteOffset(*test[0]), test[1])
def test_CodepointOffsetToByteOffset(self): # Tuples of ( ( unicode_line_value, codepoint_offset ), expected_result ). test_cases = [ # Simple ascii strings. (('test', 1), 1), (('test', 4), 4), (('test', 5), 5), # Unicode char at beginning. (('†est', 1), 1), (('†est', 2), 4), (('†est', 4), 6), (('†est', 5), 7), # Unicode char at end. (('tes†', 1), 1), (('tes†', 2), 2), (('tes†', 4), 4), (('tes†', 5), 7), # Unicode char in middle. (('tes†ing', 1), 1), (('tes†ing', 2), 2), (('tes†ing', 4), 4), (('tes†ing', 5), 7), (('tes†ing', 7), 9), (('tes†ing', 8), 10), # Converts bytes to Unicode. ((utils.ToBytes('†est'), 2), 4) ] for test, expected in test_cases: with self.subTest(test=test, expected=expected): assert_that(utils.CodepointOffsetToByteOffset(*test), equal_to(expected))
def _BuildLocation(file_contents, filename, line, ch): # tern returns codepoint offsets, but we need byte offsets, so we must # convert return responses.Location(line=line + 1, column=utils.CodepointOffsetToByteOffset( file_contents[line], ch + 1), filename=os.path.realpath(filename))
def _CallHierarchy(self, request_data, args): self._Reload(request_data) response = self._SendRequest( f'provideCallHierarchy{ args[ 0 ] }Calls', { 'file': request_data['filepath'], 'line': request_data['line_num'], 'offset': request_data['column_codepoint'] }) goto_response = [] for hierarchy_item in response: description = hierarchy_item.get('from', hierarchy_item.get('to')) filepath = description['file'] start_position = hierarchy_item['fromSpans'][0]['start'] goto_line = start_position['line'] try: line_value = GetFileLines(request_data, filepath)[goto_line - 1] except IndexError: continue goto_column = utils.CodepointOffsetToByteOffset( line_value, start_position['offset']) goto_response.append( responses.BuildGoToResponse(filepath, goto_line, goto_column, description['name'])) if goto_response: return goto_response raise RuntimeError(f'No { args[ 0 ].lower() } calls found.')
def _BuildLocation( file_contents, filename, line, offset ): return responses.Location( line = line, # tsserver returns codepoint offsets, but we need byte offsets, so we must # convert column = utils.CodepointOffsetToByteOffset( file_contents[ line - 1 ], offset ), filename = filename )
def _BuildLocation(split_lines, filename, line_num, column_num): if (line_num <= 0 or column_num <= 0 or line_num - 1 >= len(split_lines)): return responses.Location(line_num, 0, filename) line_value = split_lines[line_num - 1] return responses.Location( line_num, utils.CodepointOffsetToByteOffset(line_value, column_num), filename)
def _TsDiagnosticToYcmdDiagnostic( self, request_data, ts_diagnostic ): filepath = request_data[ 'filepath' ] ts_fixes = self._SendRequest( 'getCodeFixes', { 'file': filepath, 'startLine': ts_diagnostic[ 'startLocation' ][ 'line' ], 'startOffset': ts_diagnostic[ 'startLocation' ][ 'offset' ], 'endLine': ts_diagnostic[ 'endLocation' ][ 'line' ], 'endOffset': ts_diagnostic[ 'endLocation' ][ 'offset' ], 'errorCodes': [ ts_diagnostic[ 'code' ] ] } ) location = responses.Location( request_data[ 'line_num' ], request_data[ 'column_num' ], filepath ) fixits = [ responses.FixIt( location, _BuildFixItForChanges( request_data, fix[ 'changes' ] ), fix[ 'description' ] ) for fix in ts_fixes ] contents = GetFileLines( request_data, filepath ) ts_start_location = ts_diagnostic[ 'startLocation' ] ts_start_line = ts_start_location[ 'line' ] start_offset = utils.CodepointOffsetToByteOffset( contents[ ts_start_line - 1 ], ts_start_location[ 'offset' ] ) ts_end_location = ts_diagnostic[ 'endLocation' ] ts_end_line = ts_end_location[ 'line' ] end_offset = utils.CodepointOffsetToByteOffset( contents[ ts_end_line - 1 ], ts_end_location[ 'offset' ] ) location_start = responses.Location( ts_start_line, start_offset, filepath ) location_end = responses.Location( ts_end_line, end_offset, filepath ) location_extent = responses.Range( location_start, location_end ) return responses.Diagnostic( [ location_extent ], location_start, location_extent, ts_diagnostic[ 'message' ], 'ERROR', fixits = fixits )
def TsDiagnosticToYcmdDiagnostic(filepath, line_value, ts_diagnostic): ts_start_location = ts_diagnostic['startLocation'] ts_end_location = ts_diagnostic['endLocation'] start_offset = utils.CodepointOffsetToByteOffset( line_value, ts_start_location['offset']) end_offset = utils.CodepointOffsetToByteOffset(line_value, ts_end_location['offset']) location = responses.Location(ts_start_location['line'], start_offset, filepath) location_end = responses.Location(ts_end_location['line'], end_offset, filepath) location_extent = responses.Range(location, location_end) return responses.Diagnostic([location_extent], location, location_extent, ts_diagnostic['message'], 'ERROR')
def TsDiagnosticToYcmdDiagnostic(request_data, ts_diagnostic): filepath = request_data['filepath'] contents = request_data['lines'] ts_start_location = ts_diagnostic['startLocation'] ts_start_line = ts_start_location['line'] start_offset = utils.CodepointOffsetToByteOffset( contents[ts_start_line - 1], ts_start_location['offset']) ts_end_location = ts_diagnostic['endLocation'] ts_end_line = ts_end_location['line'] end_offset = utils.CodepointOffsetToByteOffset(contents[ts_end_line - 1], ts_end_location['offset']) location_start = responses.Location(ts_start_line, start_offset, filepath) location_end = responses.Location(ts_end_line, end_offset, filepath) location_extent = responses.Range(location_start, location_end) return responses.Diagnostic([location_extent], location_start, location_extent, ts_diagnostic['message'], 'ERROR')
def MakeSignature(s): label = _DisplayPartsToString(s['prefixDisplayParts']) parameters = [] sep = _DisplayPartsToString(s['separatorDisplayParts']) for index, p in enumerate(s['parameters']): param = _DisplayPartsToString(p['displayParts']) start = len(label) end = start + len(param) label += param if index < len(s['parameters']) - 1: label += sep parameters.append({ 'label': [ utils.CodepointOffsetToByteOffset(label, start), utils.CodepointOffsetToByteOffset(label, end) ] }) label += _DisplayPartsToString(s['suffixDisplayParts']) return {'label': label, 'parameters': parameters}
def CodepointOffsetToByteOffset_test(test, expected): assert_that(utils.CodepointOffsetToByteOffset(*test), equal_to(expected))