]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5867 SONAR-5819 Index symbol highlighting and exploit it in api/sources/lines
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Mon, 1 Dec 2014 13:51:47 +0000 (14:51 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Mon, 1 Dec 2014 13:56:11 +0000 (14:56 +0100)
12 files changed:
server/sonar-server/src/main/java/org/sonar/server/source/DecorationDataHolder.java
server/sonar-server/src/main/java/org/sonar/server/source/HtmlSourceDecorator.java
server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineDoc.java
server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java
server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java
server/sonar-server/src/test/java/org/sonar/server/source/HtmlSourceDecoratorTest.java
server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java
server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json
server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source_with_params_from_and_to.json

index e533f99ac00432d545e1ec2bb207593a5fc9fc03..8b368e5ccf97a11f5ea28ca7408ecccab674a0ee 100644 (file)
@@ -54,6 +54,19 @@ class DecorationDataHolder {
     }
   }
 
+  void loadLineSymbolReferences(String symbolsReferences) {
+    String[] symbols = symbolsReferences.split(ENTITY_SEPARATOR);
+    for (String symbol : symbols) {
+      String[] symbolFields = symbol.split(FIELD_SEPARATOR);
+      int startOffset = Integer.parseInt(symbolFields[0]);
+      int endOffset = Integer.parseInt(symbolFields[1]);
+      int symbolLength = endOffset - startOffset;
+      int symbolId = Integer.parseInt(symbolFields[2]);
+      loadSymbolOccurrences(symbolId, symbolLength, new String[] { Integer.toString(startOffset) });
+    }
+  }
+
+
   void loadSyntaxHighlightingData(String syntaxHighlightingRules) {
     String[] rules = syntaxHighlightingRules.split(ENTITY_SEPARATOR);
     for (String rule : rules) {
index c5756ca1fad34245fcfb4cd5562e7c9293622a0c..01ee890f8a18a055d63cb68ca670a348802eabb7 100644 (file)
@@ -37,6 +37,8 @@ import java.util.List;
 
 public class HtmlSourceDecorator implements ServerComponent {
 
+  private static final String SINGLE_LINE_SYMBOLS = "single_line_symbols";
+
   private final MyBatis mybatis;
 
   private final SnapshotSourceDao snapshotSourceDao;
@@ -76,7 +78,7 @@ public class HtmlSourceDecorator implements ServerComponent {
   }
 
   @CheckForNull
-  public String getDecoratedSourceAsHtml(@Nullable String sourceLine, @Nullable String highlighting) {
+  public String getDecoratedSourceAsHtml(@Nullable String sourceLine, @Nullable String highlighting, @Nullable String symbols) {
     Collection<SnapshotDataDto> snapshotDataEntries = Lists.newArrayList();
     if (highlighting != null) {
       SnapshotDataDto highlightingDto = new SnapshotDataDto();
@@ -84,6 +86,12 @@ public class HtmlSourceDecorator implements ServerComponent {
       highlightingDto.setDataType(SnapshotDataTypes.SYNTAX_HIGHLIGHTING);
       snapshotDataEntries.add(highlightingDto);
     }
+    if (symbols != null) {
+      SnapshotDataDto symbolsDto = new SnapshotDataDto();
+      symbolsDto.setData(symbols);
+      symbolsDto.setDataType(SINGLE_LINE_SYMBOLS);
+      snapshotDataEntries.add(symbolsDto);
+    }
     List<String> decoratedSource = decorate(sourceLine, snapshotDataEntries, 1, 1);
     if (decoratedSource == null) {
       return null;
@@ -121,6 +129,8 @@ public class HtmlSourceDecorator implements ServerComponent {
         dataHolder.loadSyntaxHighlightingData(entry.getData());
       } else if (SnapshotDataTypes.SYMBOL_HIGHLIGHTING.equals(entry.getDataType())) {
         dataHolder.loadSymbolReferences(entry.getData());
+      } else if (SINGLE_LINE_SYMBOLS.equals(entry.getDataType())) {
+        dataHolder.loadLineSymbolReferences(entry.getData());
       }
     }
   }
index 5fd358dfda4e75052e9ce478221ec5fa44d4258d..e845c1926fc3191f202d588b5ebb6ec534903b04 100644 (file)
@@ -86,8 +86,9 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_SCM_DATE, scmDate);
   }
 
+  @CheckForNull
   public String highlighting() {
-    return getField(SourceLineIndexDefinition.FIELD_HIGHLIGHTING);
+    return getNullableField(SourceLineIndexDefinition.FIELD_HIGHLIGHTING);
   }
 
   public void setHighlighting(String s) {
@@ -114,7 +115,7 @@ public class SourceLineDoc extends BaseDoc {
     return String.format("%s_%d", fileUuid(), line());
   }
 
-  @Nullable
+  @CheckForNull
   public Integer utLineHits() {
     Number lineHits = (Number)getNullableField(SourceLineIndexDefinition.FIELD_UT_LINE_HITS);
     return lineHits == null ? null : lineHits.intValue();
@@ -124,7 +125,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_UT_LINE_HITS, lineHits);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer utConditions() {
     Number conditions = (Number)getNullableField(SourceLineIndexDefinition.FIELD_UT_CONDITIONS);
     return conditions == null ? null : conditions.intValue();
@@ -134,7 +135,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_UT_CONDITIONS, conditions);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer utCoveredConditions() {
     Number coveredConditions = (Number)getNullableField(SourceLineIndexDefinition.FIELD_UT_COVERED_CONDITIONS);
     return coveredConditions == null ? null : coveredConditions.intValue();
@@ -144,7 +145,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_UT_COVERED_CONDITIONS, coveredConditions);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer itLineHits() {
     Number lineHits = (Number)getNullableField(SourceLineIndexDefinition.FIELD_IT_LINE_HITS);
     return lineHits == null ? null : lineHits.intValue();
@@ -154,7 +155,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_IT_LINE_HITS, lineHits);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer itConditions() {
     Number conditions = (Number)getNullableField(SourceLineIndexDefinition.FIELD_IT_CONDITIONS);
     return conditions == null ? null : conditions.intValue();
@@ -164,7 +165,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_IT_CONDITIONS, conditions);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer itCoveredConditions() {
     Number coveredConditions = (Number)getNullableField(SourceLineIndexDefinition.FIELD_IT_COVERED_CONDITIONS);
     return coveredConditions == null ? null : coveredConditions.intValue();
@@ -174,7 +175,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_IT_COVERED_CONDITIONS, coveredConditions);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer overallLineHits() {
     Number lineHits = (Number)getNullableField(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS);
     return lineHits == null ? null : lineHits.intValue();
@@ -184,7 +185,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, lineHits);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer overallConditions() {
     Number conditions = (Number)getNullableField(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS);
     return conditions == null ? null : conditions.intValue();
@@ -194,7 +195,7 @@ public class SourceLineDoc extends BaseDoc {
     setField(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, conditions);
   }
 
-  @Nullable
+  @CheckForNull
   public Integer overallCoveredConditions() {
     Number coveredConditions = (Number)getNullableField(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS);
     return coveredConditions == null ? null : coveredConditions.intValue();
@@ -203,4 +204,14 @@ public class SourceLineDoc extends BaseDoc {
   public void setOverallCoveredConditions(@Nullable Integer coveredConditions) {
     setField(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, coveredConditions);
   }
+
+  @CheckForNull
+  public String symbols() {
+    return getNullableField(SourceLineIndexDefinition.FIELD_SYMBOLS);
+  }
+
+  public void setSymbols(@Nullable String s) {
+    setField(SourceLineIndexDefinition.FIELD_SYMBOLS, s);
+  }
+
 }
index 6db9156df57671921a48befdaa32d0e50082cf35..ce10ac551bc5a16dbd48e7ff89bcd09dda15aef7 100644 (file)
@@ -45,6 +45,7 @@ public class SourceLineIndexDefinition implements IndexDefinition {
   public static final String FIELD_OVERALL_LINE_HITS = "overallLineHits";
   public static final String FIELD_OVERALL_CONDITIONS = "overallConditions";
   public static final String FIELD_OVERALL_COVERED_CONDITIONS = "overallCoveredConditions";
+  public static final String FIELD_SYMBOLS = "symbols";
 
   public static final String INDEX = "sourcelines";
 
@@ -88,6 +89,7 @@ public class SourceLineIndexDefinition implements IndexDefinition {
     sourceLineMapping.createShortField(FIELD_OVERALL_LINE_HITS);
     sourceLineMapping.createShortField(FIELD_OVERALL_CONDITIONS);
     sourceLineMapping.createShortField(FIELD_OVERALL_COVERED_CONDITIONS);
+    sourceLineMapping.stringFieldBuilder(FIELD_SYMBOLS).build();
     sourceLineMapping.createDateTimeField(BaseNormalizer.UPDATED_AT_FIELD);
   }
 }
index a3875fc69c5844ecb2a06b7169174c86a7d3869a..f2cd6030096da75d80e4417b68e116ea77e67bdc 100644 (file)
@@ -145,6 +145,7 @@ public class SourceLineResultSetIterator extends ResultSetIterator<SourceLineRes
           doc.setOverallConditions(parseIntegerFromRecord(csvRecord, 10));
           doc.setOverallCoveredConditions(parseIntegerFromRecord(csvRecord, 11));
           doc.setHighlighting(csvRecord.get(12));
+          doc.setSymbols(csvRecord.get(13));
           doc.setSource(csvRecord.get(csvRecord.size() - 1));
 
           result.addLine(doc);
index 577b2cc1af5f4813edc6b11a73979d8edf48f96a..1b7e12ed408b5d4abc31b700f1bf57bf0f7576ce 100644 (file)
@@ -101,7 +101,7 @@ public class LinesAction implements RequestHandler {
     for (SourceLineDoc line: lines) {
       json.beginObject()
         .prop("line", line.line())
-        .prop("code", htmlSourceDecorator.getDecoratedSourceAsHtml(line.source(), line.highlighting()))
+        .prop("code", htmlSourceDecorator.getDecoratedSourceAsHtml(line.source(), line.highlighting(), line.symbols()))
         .prop("scmAuthor", line.scmAuthor())
         .prop("scmRevision", line.scmRevision());
       Date scmDate = line.scmDate();
index bfd1c47983de49a76d9cc7cc2bcaae6e75fbc4c9..34e101105ebd3086c8d8c15e3d136a2e3d5a9b2b 100644 (file)
@@ -68,7 +68,7 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void highlight_syntax_with_html_from_component() throws Exception {
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:Dispatcher", null, null);
+    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:Dispatcher", (Integer) null, (Integer) null);
 
     assertThat(decoratedSource).containsExactly(
       "<span class=\"cppd\">/*</span>",
@@ -103,7 +103,7 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void mark_symbols_with_html_from_component() throws Exception {
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:VelocityManager", null, null);
+    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:VelocityManager", (Integer) null, (Integer) null);
 
     assertThat(decoratedSource).containsExactly(
       "/*",
@@ -136,7 +136,7 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void decorate_source_with_multiple_decoration_strategies_from_component() throws Exception {
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:DebuggingInterceptor", null, null);
+    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:DebuggingInterceptor", (Integer) null, (Integer) null);
 
     assertThat(decoratedSource).containsExactly(
       "<span class=\"cppd\">/*</span>",
@@ -173,7 +173,7 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
     HtmlSourceDecorator sourceDecorator = new HtmlSourceDecorator(mock(MyBatis.class), snapshotSourceDao, snapshotDataDao);
 
-    sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:DebuggingInterceptor", null, null);
+    sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:DebuggingInterceptor", (Integer) null, (Integer) null);
 
     verify(snapshotDataDao, times(1)).selectSnapshotDataByComponentKey(eq("org.apache.struts:struts:DebuggingInterceptor"), eq(Lists.newArrayList("highlight_syntax", "symbol")),
       any(SqlSession.class));
@@ -185,24 +185,25 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
   public void should_decorate_single_line() {
     String sourceLine = "package org.polop;";
     String highlighting = "0,7,k";
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, highlighting)).isEqualTo("<span class=\"k\">package</span> org.polop;");
+    String symbols = "8,17,42";
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, highlighting, symbols)).isEqualTo("<span class=\"k\">package</span> <span class=\"sym-42 sym\">org.polop</span>;");
   }
 
   @Test
   public void should_ignore_missing_highlighting() {
     String sourceLine = "    if (toto < 42) {";
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, null)).isEqualTo("    if (toto &lt; 42) {");
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, "")).isEqualTo("    if (toto &lt; 42) {");
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, (String) null, (String) null)).isEqualTo("    if (toto &lt; 42) {");
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, "", (String) null)).isEqualTo("    if (toto &lt; 42) {");
   }
 
   @Test
   public void should_ignore_null_source() {
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml(null, null)).isNull();
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(null, (String) null, (String) null)).isNull();
   }
 
   @Test
   public void should_ignore_empty_source() {
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml("", null)).isEqualTo("");
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml("", (String) null, (String) null)).isEqualTo("");
   }
 }
 
index 01950d94669ed783994b884eb10edf2f691b232f..6e828d3ea1c9b7efd4936035dd540a8968036f2a 100644 (file)
@@ -89,7 +89,7 @@ public class SourceServiceTest {
 
     service.getLinesAsHtml(COMPONENT_KEY);
 
-    verify(sourceDecorator).getDecoratedSourceAsHtml(COMPONENT_KEY, null, null);
+    verify(sourceDecorator).getDecoratedSourceAsHtml(COMPONENT_KEY, (Integer) null, (Integer) null);
   }
 
   @Test
index 9460d5cf3486f6d57d3e46f9a438f0537f4016d9..e86cc45328df59f1075d5fb39bdf7e19ee245cad 100644 (file)
@@ -56,10 +56,10 @@ public class SourceLineResultSetIteratorTest {
   public void should_generate_source_line_documents() throws Exception {
     db.prepareDbUnit(getClass(), "shared.xml");
     PreparedStatement stmt = connection.prepareStatement("UPDATE file_sources SET data = ? WHERE id=1");
-    stmt.setString(1, "aef12a,alice,2014-04-25T12:34:56+0100,1,0,0,2,0,0,3,0,0,polop,class Foo {\r\n" +
-      "abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,  // Empty\r\n" +
-      "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,}\r\n" +
-      "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,\r\n");
+    stmt.setString(1, "aef12a,alice,2014-04-25T12:34:56+0100,1,0,0,2,0,0,3,0,0,polop,palap,class Foo {\r\n" +
+      "abe465,bob,2014-07-25T12:34:56+0100,,,,,,,,,,,,  // Empty\r\n" +
+      "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,}\r\n" +
+      "afb789,carol,2014-03-23T12:34:56+0100,,,,,,,,,,,,\r\n");
     stmt.executeUpdate();
 
     SourceLineResultSetIterator iterator = SourceLineResultSetIterator.create(dbClient, connection, 0L);
@@ -75,6 +75,7 @@ public class SourceLineResultSetIteratorTest {
     // TODO Sanitize usage of fscking dates
     // assertThat(firstLine.scmDate()).isEqualTo(DateUtils.parseDateTime("2014-04-25T12:34:56+0100"));
     assertThat(firstLine.highlighting()).isEqualTo("polop");
+    assertThat(firstLine.symbols()).isEqualTo("palap");
     assertThat(firstLine.source()).isEqualTo("class Foo {");
     assertThat(firstLine.utLineHits()).isEqualTo(1);
     assertThat(firstLine.utConditions()).isEqualTo(0);
index 8653e52f83764b764d5fd303a7537b2f7eb34c6d..94639b2088461ed93d316a652d80de89635179f7 100644 (file)
@@ -72,10 +72,10 @@ public class LinesActionTest {
         mock(HashAction.class)
       )
     );
-    when(htmlSourceDecorator.getDecoratedSourceAsHtml(anyString(), anyString())).thenAnswer(new Answer<String>() {
+    when(htmlSourceDecorator.getDecoratedSourceAsHtml(anyString(), anyString(), anyString())).thenAnswer(new Answer<String>() {
       @Override
       public String answer(InvocationOnMock invocation) throws Throwable {
-        return "<span class=\"" + invocation.getArguments()[1] + "\">" +
+        return "<span class=\"" + invocation.getArguments()[1] + " sym-" + invocation.getArguments()[2] + "\">" +
           StringEscapeUtils.escapeHtml((String) invocation.getArguments()[0]) +
             "</span>";
       }
@@ -96,6 +96,7 @@ public class LinesActionTest {
       .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop")
       .put(SourceLineIndexDefinition.FIELD_SOURCE, "class Polop {")
       .put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "h1")
+      .put(SourceLineIndexDefinition.FIELD_SYMBOLS, "palap")
       .put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, 3)
       .put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, 2)
       .put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, 1)
@@ -110,6 +111,7 @@ public class LinesActionTest {
       .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop")
       .put(SourceLineIndexDefinition.FIELD_SOURCE, "  // Empty")
       .put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "h2")
+      .put(SourceLineIndexDefinition.FIELD_SYMBOLS, "pulup")
       .put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, 3)
       .put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, 2)
       .put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, 1)
@@ -124,6 +126,7 @@ public class LinesActionTest {
       .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop")
       .put(SourceLineIndexDefinition.FIELD_SOURCE, "}")
       .put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "h3")
+      .put(SourceLineIndexDefinition.FIELD_SYMBOLS, "pylyp")
       .put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, 3)
       .put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, 2)
       .put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, 1)
@@ -166,6 +169,7 @@ public class LinesActionTest {
     fieldMap.put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop");
     fieldMap.put(SourceLineIndexDefinition.FIELD_SOURCE, "}");
     fieldMap.put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "");
+    fieldMap.put(SourceLineIndexDefinition.FIELD_SYMBOLS, "");
     fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_LINE_HITS, null);
     fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_CONDITIONS, null);
     fieldMap.put(SourceLineIndexDefinition.FIELD_OVERALL_COVERED_CONDITIONS, null);
index ec78a1f83f536ad2ba15839dcb1bf9fc5b1e3044..1ab70956af5c91b36ea162b33b11affcbe7a25cd 100644 (file)
@@ -1,7 +1,7 @@
 {
   "sources": [
     {
-      "code": "<span class=\"h1\">class Polop {</span>",
+      "code": "<span class=\"h1 sym-palap\">class Polop {</span>",
       "line": 1,
       "scmAuthor": "polop",
       "scmRevision": "cafebabe",
@@ -10,7 +10,7 @@
       "coveredConditions": 1
     },
     {
-      "code": "<span class=\"h2\">  // Empty</span>",
+      "code": "<span class=\"h2 sym-pulup\">  // Empty</span>",
       "line": 2,
       "scmAuthor": "polop",
       "scmRevision": "cafebabe",
@@ -19,7 +19,7 @@
       "coveredConditions": 1
     },
     {
-      "code": "<span class=\"h3\">}</span>",
+      "code": "<span class=\"h3 sym-pylyp\">}</span>",
       "line": 3,
       "scmAuthor": "polop",
       "scmRevision": "cafebabe",
index 73dcf29d17a4e12c0bf4fb32778d433abd5fc9c2..8845334e1d954ea8cc1ac3e805af8c9e4894e279 100644 (file)
@@ -1,7 +1,7 @@
 {
   "sources": [
     {
-      "code": "<span class=\"\">}</span>",
+      "code": "<span class=\" sym-\">}</span>",
       "line": 3,
       "scmAuthor": "polop",
       "scmRevision": "cafebabe"