Skip to content

Commit 4963be8

Browse files
committed
feat: added a property LineIsPython that stores if each line of code is a python line or not
1 parent c4c0164 commit 4963be8

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

cls/TestCoverage/Data/CodeUnit.cls

+61
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@ Property MethodEndMap As array Of %Integer;
3838
/// For routines, map of labels to associated line numbers
3939
Property LineToMethodMap As array Of %Dictionary.CacheIdentifier [ Private ];
4040

41+
/// For each line, whether or not it belongs to a python method, only populated for .cls CodeUnits
42+
Property LineIsPython As array Of %Boolean;
43+
4144
/// Set to true if this class/routine is generated
4245
Property Generated As %Boolean [ InitialExpression = 0 ];
4346

47+
///
4448
/// Methods, branches, etc. within this unit of code.
4549
Relationship SubUnits As TestCoverage.Data.CodeSubUnit [ Cardinality = children, Inverse = Parent ];
4650

@@ -129,6 +133,7 @@ ClassMethod GetCurrentByName(pInternalName As %String, pSourceNamespace As %Stri
129133

130134
If (tType = "CLS") {
131135
Set pCodeUnit.Generated = ($$$comClassKeyGet(tName,$$$cCLASSgeneratedby) '= "")
136+
132137
}
133138

134139

@@ -170,6 +175,9 @@ ClassMethod GetCurrentByName(pInternalName As %String, pSourceNamespace As %Stri
170175
Do pCodeUnit.Lines.Insert(tLine)
171176

172177
If (tType = "CLS") {
178+
// initialize each line to not python (we'll update this later)
179+
Do pCodeUnit.LineIsPython.SetAt(0, tLineNumber)
180+
173181
// Extract line offset of methods in classes
174182
Set tStart = $Piece(tLine," ")
175183
If (tStart = "ClassMethod") || (tStart = "Method") {
@@ -236,6 +244,54 @@ ClassMethod GetCurrentByName(pInternalName As %String, pSourceNamespace As %Stri
236244
Quit tSC
237245
}
238246

247+
/// Fill in the LineIsPython property of .cls files
248+
Method UpdatePythonLines(pName As %String, ByRef pPyCodeUnit) As %Status
249+
{
250+
251+
Set tSC = $$$OK
252+
Set tOriginalNamespace = $Namespace
253+
Set tInitTLevel = $TLevel
254+
255+
Try {
256+
TSTART
257+
258+
If (##class(TestCoverage.Manager).HasPython(pName)) {
259+
260+
Set tFromHash = pPyCodeUnit.Hash
261+
Set tToHash = ..Hash
262+
set sql = "SELECT map.ToLine FROM TestCoverage_Data.CodeUnitMap map " _
263+
"JOIN TestCoverage_Data.CodeUnit fromCodeUnit " _
264+
"ON fromCodeUnit.Hash = map.FromHash " _
265+
"WHERE map.FromHash = ? " _
266+
"AND map.ToHash = ? "
267+
set resultSet = ##class(%SQL.Statement).%ExecDirect(, sql, tFromHash, tToHash)
268+
If (resultSet.%SQLCODE < 0) {
269+
Throw ##class(%Exception.SQL).CreateFromSQLCODE(resultSet.%SQLCODE, resultSet.%Message)
270+
}
271+
while resultSet.%Next(.tSC) {
272+
$$$ThrowOnError(tSC)
273+
Set hToLine = resultSet.%GetData(1)
274+
set ^IRIS.TempCG($i(^IRIS.TempCG)) = hToLine
275+
do ..LineIsPython.SetAt(1, hToLine)
276+
}
277+
If (resultSet.%SQLCODE < 0) {
278+
Throw ##class(%Exception.SQL).CreateFromSQLCODE(resultSet.%SQLCODE, resultSet.%Message)
279+
}
280+
}
281+
Set tSC = ..%Save()
282+
$$$ThrowOnError(tSC)
283+
284+
TCOMMIT
285+
} Catch e {
286+
Set pCodeUnit = $$$NULLOREF
287+
Set tSC = e.AsStatus()
288+
}
289+
While ($TLevel > tInitTLevel) {
290+
TROLLBACK 1
291+
}
292+
Quit tSC
293+
}
294+
239295
/// Get the executable lines of code in python over to the .cls CodeUnit
240296
Method UpdatePyExecutableLines(pName As %String, ByRef pPyCodeUnit) As %Status
241297
{
@@ -636,6 +692,11 @@ Storage Default
636692
<Value>Generated</Value>
637693
</Value>
638694
</Data>
695+
<Data name="LineIsPython">
696+
<Attribute>LineIsPython</Attribute>
697+
<Structure>subnode</Structure>
698+
<Subscript>"LineIsPython"</Subscript>
699+
</Data>
639700
<Data name="LineToMethodMap">
640701
<Attribute>LineToMethodMap</Attribute>
641702
<Structure>subnode</Structure>

cls/TestCoverage/Utils.cls

+4
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ ClassMethod Snapshot(pIntRoutines As %List, pPyRoutines As %List, Output pReleva
120120
// update the executable lines for the .cls file's python
121121
$$$ThrowOnError(tCodeUnit.UpdatePyExecutableLines(tName, .tPyCodeUnit))
122122

123+
// update the pythonicity of the lines for the .cls file
124+
$$$ThrowOnError(tCodeUnit.UpdatePythonLines(tName, .tPyCodeUnit))
125+
123126
// update the relevant python routines
124127
If ($BitCount(tPyCodeUnit.ExecutableLines, 1)) {
125128
set pPyRelevantRoutines = pPyRelevantRoutines _ $ListBuild(tName)
@@ -144,6 +147,7 @@ ClassMethod Snapshot(pIntRoutines As %List, pPyRoutines As %List, Output pReleva
144147
$$$ThrowOnError(##class(TestCoverage.Data.CodeUnit).GetCurrentByName(tPyRoutine_".CLS",,.tCodeUnit))
145148
$$$ThrowOnError(##class(TestCoverage.Data.CodeUnit).GetCurrentByName(tPyRoutine_".PY",,.tPyCodeUnit))
146149
$$$ThrowOnError(tCodeUnit.UpdatePyExecutableLines(tPyRoutine, .tPyCodeUnit))
150+
$$$ThrowOnError(tCodeUnit.UpdatePythonLines(tPyRoutine, .tPyCodeUnit))
147151

148152
If ($BitCount(tPyCodeUnit.ExecutableLines, 1)) {
149153
set pPyRelevantRoutines = pPyRelevantRoutines _ $ListBuild(tPyRoutine)

internal/testing/unit_tests/UnitTest/TestCoverage/Unit/CodeUnit.cls

+7
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ Method TestCodeUnitCreation()
4242
Set tSC = tClsCodeUnit.UpdatePyExecutableLines($classname(),.tPyCodeUnit)
4343
Do $$$AssertStatusOK(tSC,"Found updated executable line data for "_tClsName)
4444

45+
Set tSC = tClsCodeUnit.UpdatePythonLines($classname(),.tPyCodeUnit)
46+
Do $$$AssertStatusOK(tSC,"Found updated pythonicity line data for "_tClsName)
47+
4548
Set tConstantReturnValueLine = tClsCodeUnit.MethodMap.GetAt("SampleConstantReturnValue")
4649
Set tCodeGeneratorLine = tClsCodeUnit.MethodMap.GetAt("SampleCodeGenerator")
4750
Set tNormalMethodLine = tClsCodeUnit.MethodMap.GetAt("SampleNormalMethod")
@@ -51,6 +54,10 @@ Method TestCodeUnitCreation()
5154
Do $$$AssertNotEquals(tCodeGeneratorLine,"")
5255
Do $$$AssertNotEquals(tNormalMethodLine,"")
5356
Do $$$AssertNotEquals(tPythonMethodLine,"")
57+
58+
// test if LineIsPython is working properly
59+
Do $$$AssertEquals(tClsCodeUnit.LineIsPython.GetAt(tPythonMethodLine+2), 1)
60+
Do $$$AssertEquals(tClsCodeUnit.LineIsPython.GetAt(tNormalMethodLine+2), 0)
5461

5562
// tTestLines(line number) = $ListBuild(description, executable (default 1), mapped (default 1), mapped from hash (if relevant), mapped from line (if relevant))
5663
Set tTestLines(tConstantReturnValueLine+2) = $ListBuild("SampleConstantReturnValue+1",0,0)

0 commit comments

Comments
 (0)