Skip to content

Commit f28bf04

Browse files
committed
Fixing some issues with as-you-type checks
1 parent 7cd010c commit f28bf04

File tree

4 files changed

+68
-32
lines changed

4 files changed

+68
-32
lines changed

hdlcc/builders/base_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ def _buildAndParse(self, source, flags=None):
276276
# content, so we dump the buffer content to a temporary file
277277
# and tell the compiler to compile it instead
278278
if source.hasBufferContent():
279-
build_path = source.dumpBufferContentToFile()
279+
build_path = source.getDumpPath()
280280
self._logger.debug("Source has buffered content, using %s",
281281
build_path)
282282
else:

hdlcc/hdlcc_base.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,8 @@ def getMessagesWithText(self, path, content):
483483
self._setupEnvIfNeeded()
484484

485485
source, remarks = self.getSourceByPath(path)
486-
source.setBufferContent(content)
487-
messages = self.getMessagesBySource(source)
488-
source.clearBufferContent()
486+
with source.havingBufferContent(content):
487+
messages = self.getMessagesBySource(source)
489488

490489
# Some messages may not include the filename field when checking a
491490
# file by content. In this case, we'll assume the empty filenames

hdlcc/parsers/base_parser.py

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
"Base source file parser"
1818

1919
import abc
20+
import os
2021
import os.path as p
2122
import logging
2223
import re
2324
import time
25+
from contextlib import contextmanager
2426

2527
from hdlcc.utils import getFileType, removeDuplicates
2628

@@ -49,10 +51,7 @@ def __init__(self, filename, library='work', flags=None):
4951
self._content = None
5052
self._mtime = 0
5153
self.filetype = getFileType(self.filename)
52-
53-
self._buffer_time = None
54-
self._buffer_content = None
55-
54+
self._prev = None
5655
self.abspath = p.abspath(filename)
5756

5857
def getState(self):
@@ -83,8 +82,7 @@ def recoverFromState(cls, state):
8382
obj.flags = state['flags']
8483
obj._cache = state['_cache']
8584
obj._content = None
86-
obj._buffer_time = None
87-
obj._buffer_content = None
85+
obj._prev = None
8886
obj._mtime = state['_mtime']
8987
obj.filetype = state['filetype']
9088
# pylint: enable=protected-access
@@ -123,53 +121,89 @@ def _changed(self):
123121
Checks if the file changed based on the modification time
124122
provided by p.getmtime
125123
"""
126-
return self.getmtime() > self._mtime
124+
if self.getmtime() > self._mtime:
125+
_logger.debug("File '%s' has changed", self.filename)
126+
return True
127+
return False
127128

128129
def _clearCachesIfChanged(self):
129130
"""
130131
Clears all the caches if the file has changed to force updating
131132
every parsed info
132133
"""
133134
if self._changed():
134-
self._content = None
135+
# Since the content was set by the caller, we can't really clear
136+
# this unless we're handling with a proper file
137+
if not self.hasBufferContent(): # pragma: no cover
138+
self._content = None
135139
self._cache = {}
136140

137141
def getmtime(self):
138142
"""
139143
Gets file modification time as defined in p.getmtime
140144
"""
141-
if self._buffer_time is not None:
142-
return self._buffer_time
145+
if self.hasBufferContent():
146+
return 0
143147
if not p.exists(self.filename):
144148
return None
145149
return p.getmtime(self.filename)
146150

147-
def setBufferContent(self, content):
148-
self._buffer_content = content
149-
self._buffer_time = time.time()
151+
@contextmanager
152+
def havingBufferContent(self, content):
153+
"""
154+
Context manager for handling a source file with a custom content
155+
that is different from the file it points to. This is intended to
156+
allow as-you-type checking
157+
"""
158+
self._setBufferContent(content)
159+
yield
160+
self._clearBufferContent()
161+
162+
def getDumpPath(self):
163+
"""
164+
Returns the dump path in use while inside the havingBufferContent
165+
context
166+
"""
167+
return p.join(p.dirname(self.filename), '.dump_' +
168+
p.basename(self.filename))
150169

151170
def hasBufferContent(self):
152-
return self._buffer_content is not None
171+
"""
172+
Returns true whenever the source is inside the havingBufferContent
173+
context
174+
"""
175+
return self._prev is not None
153176

154-
def dumpBufferContentToFile(self):
155-
buffer_dump_path = p.join(p.dirname(self.filename), '.dump_' +
156-
p.basename(self.filename))
157-
open(buffer_dump_path, 'w').write(self._buffer_content)
177+
def _setBufferContent(self, content):
178+
"""
179+
Setup portion of the havingBufferContent context
180+
"""
181+
_logger.debug("Setting source content")
182+
self._prev = (self._mtime, self._content)
183+
self._content = content
184+
self._mtime = time.time()
185+
186+
buffer_dump_path = self.getDumpPath()
187+
_logger.debug("Dumping buffer content to '%s'", buffer_dump_path)
188+
open(buffer_dump_path, 'w').write(self._content)
158189
return buffer_dump_path
159190

160-
def clearBufferContent(self):
161-
self._buffer_time = None
162-
self._buffer_content = None
191+
def _clearBufferContent(self):
192+
"""
193+
Tear down portion of the havingBufferContent context
194+
"""
195+
_logger.debug("Clearing buffer content")
196+
buffer_dump_path = self.getDumpPath()
197+
if p.exists(buffer_dump_path):
198+
os.remove(buffer_dump_path)
199+
200+
self._mtime, self._content = self._prev
201+
self._prev = None
163202

164203
def getSourceContent(self):
165204
"""
166205
Cached version of the _getSourceContent method
167206
"""
168-
if self._buffer_content is not None:
169-
if self._changed():
170-
self._cache = {}
171-
return self._buffer_content
172-
173207
self._clearCachesIfChanged()
174208

175209
if self._content is None:
@@ -185,8 +219,9 @@ def getRawSourceContent(self):
185219
"""
186220
self._clearCachesIfChanged()
187221

188-
if self._buffer_content is not None:
189-
return self._buffer_content
222+
if self.hasBufferContent():
223+
return self._content
224+
190225
if 'raw_content' not in self._cache or self._changed():
191226
self._cache['raw_content'] = \
192227
open(self.filename, mode='rb').read().decode(errors='ignore')

hdlcc/tests/test_hdlcc_base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ def test005b():
606606
_logger.debug("Records received:")
607607
for record in records:
608608
_logger.debug("- %s", record)
609+
else:
610+
_logger.warning("No records found")
609611

610612
# Check that all records point to the original filename and
611613
# remove them from the records so it's easier to compare

0 commit comments

Comments
 (0)