@@ -15,10 +15,7 @@ class Reference(PydanticModel):
1515 range : Range
1616 uri : str
1717
18-
19- def get_model_definitions_for_a_path (
20- lint_context : LSPContext , document_uri : str
21- ) -> t .List [Reference ]:
18+ def get_model_definitions_for_a_path (lint_context : LSPContext , document_uri : str ) -> t .List [Reference ]:
2219 """
2320 Get the model references for a given path.
2421
@@ -36,41 +33,38 @@ def get_model_definitions_for_a_path(
3633 # Ensure the path is a sql model
3734 if not document_uri .endswith (".sql" ):
3835 return []
39-
40- # Get the model
36+
37+ # Get the model
4138 models = lint_context .map [document_uri ]
42- if models is None :
39+ if models is None :
4340 return []
4441 if len (models ) == 0 :
4542 return []
4643 model_name = models [0 ]
4744 model = lint_context .context .get_model (model_or_snapshot = model_name , raise_if_missing = False )
48- if model is None :
45+ if model is None :
4946 return []
5047 if not isinstance (model , SqlModel ):
5148 return []
52-
49+
5350 # Find all possible references
5451 tables = list (model .query .find_all (exp .Table ))
5552 if len (tables ) == 0 :
5653 return []
57-
54+
5855 references = []
5956 for table in tables :
6057 depends_on = model .depends_on
6158
6259 # Normalize the table reference
6360 reference_name = table .this .this if table .db is None else f"{ table .db } .{ table .this .this } "
64- normalized_reference_name = normalize_model_name (
65- reference_name , default_catalog = lint_context .context .default_catalog
66- )
61+ normalized_reference_name = normalize_model_name (reference_name , default_catalog = lint_context .context .default_catalog )
6762 if normalized_reference_name not in depends_on :
6863 continue
6964
65+
7066 # Get the referenced model uri
71- referenced_model = lint_context .context .get_model (
72- model_or_snapshot = normalized_reference_name , raise_if_missing = False
73- )
67+ referenced_model = lint_context .context .get_model (model_or_snapshot = normalized_reference_name , raise_if_missing = False )
7468 if referenced_model is None :
7569 continue
7670 # Get the model uri
@@ -79,96 +73,42 @@ def get_model_definitions_for_a_path(
7973 continue
8074 # Fully qualify the path in case
8175 path = Path .resolve (Path (referenced_model_path ))
82- referenced_model_uri = f"file://{ path } "
83- read_file = open (path , "r" ).readlines ()
84-
76+ referenced_model_path = f"file://{ path } "
77+ # Get the path to the file containing the reference
78+ # file_path = document_uri.removeprefix("file://")
79+ # read_file = open(file_path, "r").readlines() # Reading the file here is not needed for range calculation
80+
8581 # Extract metadata for positioning
86- table_meta = TokenPositionDetails .from_meta (table .this .meta )
87- table_range = _range_from_token_position_details (table_meta , read_file )
88- start_pos = table_range .start
89- end_pos = table_range .end
90-
82+ this_meta = table .this .meta
83+ this_start_line_0 = this_meta ['line' ] - 1 # Convert to 0-indexed
84+ this_start_col_0 = this_meta ['col' ] - 1 # Convert to 0-indexed
85+
86+ # End position: Based on the start of 'this' token + its length
87+ end_char_0 = this_start_col_0 + len (table .this .this )
88+ end_pos = Position (line = this_start_line_0 , character = end_char_0 )
89+
90+ # Start position: Initially set to the start of 'this' token
91+ start_pos = Position (line = this_start_line_0 , character = this_start_col_0 )
92+
9193 # If there's a database qualifier, adjust the start position
92- db = table .args .get ("db" )
94+ db = table .args .get ('db' )
9395 if db is not None :
94- db_meta = TokenPositionDetails .from_meta (db .meta )
95- db_range = _range_from_token_position_details (db_meta , read_file )
96- start_pos = db_range .start
97-
96+ db_meta = db .meta
97+ db_start_line_0 = db_meta ['line' ] - 1 # Convert to 0-indexed
98+ db_start_col_0 = db_meta ['col' ] - 1 # Convert to 0-indexed
99+ start_pos = Position (line = db_start_line_0 , character = db_start_col_0 )
100+
98101 # If there's a catalog qualifier, adjust the start position further
99- catalog = table .args .get (" catalog" )
102+ catalog = table .args .get (' catalog' )
100103 if catalog is not None :
101- catalog_meta = TokenPositionDetails .from_meta (catalog .meta )
102- catalog_range = _range_from_token_position_details (catalog_meta , read_file )
103- start_pos = catalog_range .start
104+ catalog_meta = catalog .meta
105+ catalog_start_line_0 = catalog_meta ['line' ] - 1 # Convert to 0-indexed
106+ catalog_start_col_0 = catalog_meta ['col' ] - 1 # Convert to 0-indexed
107+ start_pos = Position (line = catalog_start_line_0 , character = catalog_start_col_0 )
104108
105- references .append (
106- Reference (uri = referenced_model_uri , range = Range (start = start_pos , end = end_pos ))
107- )
109+ references .append (Reference (
110+ uri = referenced_model_path ,
111+ range = Range (start = start_pos , end = end_pos )
112+ ))
108113
109114 return references
110-
111-
112- class TokenPositionDetails (PydanticModel ):
113- """
114- Details about a token's position in the source code.
115-
116- Attributes:
117- line (int): The line that the token ends on.
118- col (int): The column that the token ends on.
119- start (int): The start index of the token.
120- end (int): The ending index of the token.
121- """
122-
123- line : int
124- col : int
125- start : int
126- end : int
127-
128- @staticmethod
129- def from_meta (meta : t .Dict [str , int ]) -> "TokenPositionDetails" :
130- return TokenPositionDetails (
131- line = meta ["line" ],
132- col = meta ["col" ],
133- start = meta ["start" ],
134- end = meta ["end" ],
135- )
136-
137-
138- def _range_from_token_position_details (
139- token_position_details : TokenPositionDetails , read_file : t .List [str ]
140- ) -> Range :
141- """
142- Convert a TokenPositionDetails object to a Range object.
143-
144- :param token_position_details: Details about a token's position
145- :param read_file: List of lines from the file
146- :return: A Range object representing the token's position
147- """
148- # Convert from 1-indexed to 0-indexed for line and column
149- end_line_0 = token_position_details .line - 1
150- end_col_0 = token_position_details .col
151-
152- # Find the start line and column by counting backwards from the end position
153- start_pos = token_position_details .start
154- end_pos = token_position_details .end
155-
156- # Initialize with the end position
157- start_line_0 = end_line_0
158- start_col_0 = end_col_0 - (end_pos - start_pos + 1 )
159-
160- # If start_col_0 is negative, we need to go back to previous lines
161- while start_col_0 < 0 and start_line_0 > 0 :
162- start_line_0 -= 1
163- start_col_0 += len (read_file [start_line_0 ])
164- # Account for newline character
165- if start_col_0 >= 0 :
166- break
167- start_col_0 += 1 # For the newline character
168-
169- # Ensure we don't have negative values
170- start_col_0 = max (0 , start_col_0 )
171- return Range (
172- start = Position (line = start_line_0 , character = start_col_0 ),
173- end = Position (line = end_line_0 , character = end_col_0 ),
174- )
0 commit comments