diff options
Diffstat (limited to 'plugins')
4 files changed, 190 insertions, 2 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index 9cb185a943e..3b626b8ed9f 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -34,6 +34,7 @@ import org.sonar.xoo.global.GlobalSensor; import org.sonar.xoo.lang.CpdTokenizerSensor; import org.sonar.xoo.lang.LineMeasureSensor; import org.sonar.xoo.lang.MeasureSensor; +import org.sonar.xoo.lang.SignificantCodeSensor; import org.sonar.xoo.lang.SymbolReferencesSensor; import org.sonar.xoo.lang.SyntaxHighlightingSensor; import org.sonar.xoo.lang.XooCpdMapping; @@ -173,7 +174,9 @@ public class XooPlugin implements Plugin { context.addExtension(GlobalSensor.class); } if (context.getSonarQubeVersion().isGreaterThanOrEqual(Version.create(7, 2))) { - context.addExtension(OneExternalIssuePerLineSensor.class); + context.addExtensions( + OneExternalIssuePerLineSensor.class, + SignificantCodeSensor.class); } } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SignificantCodeSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SignificantCodeSensor.java new file mode 100644 index 00000000000..108d232cb5a --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SignificantCodeSensor.java @@ -0,0 +1,94 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.xoo.lang; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.code.NewSignificantCode; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.xoo.Xoo; + +public class SignificantCodeSensor implements Sensor { + private static final Logger LOG = Loggers.get(SignificantCodeSensor.class); + private static final String FILE_EXTENSION = ".significantCode"; + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor + .name("Xoo Significant Code Ranges Sensor") + .onlyOnLanguages(Xoo.KEY); + } + + @Override + public void execute(SensorContext context) { + for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) { + processSignificantCodeFile(file, context); + } + } + + private void processSignificantCodeFile(InputFile inputFile, SensorContext context) { + Path ioFile = inputFile.path(); + Path significantCodeFile = ioFile.resolveSibling(ioFile.getFileName() + FILE_EXTENSION).toAbsolutePath(); + if (Files.exists(significantCodeFile) && Files.isRegularFile(significantCodeFile)) { + LOG.debug("Processing " + significantCodeFile.toString()); + try { + List<String> lines = Files.readAllLines(significantCodeFile, context.fileSystem().encoding()); + NewSignificantCode significantCode = context.newSignificantCode() + .onFile(inputFile); + for (String line : lines) { + if (StringUtils.isBlank(line) || line.startsWith("#")) { + continue; + } + processLine(line, inputFile, significantCode); + } + significantCode.save(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } + + private void processLine(String fileLine, InputFile inputFile, NewSignificantCode significantCode) { + String[] textPointer = fileLine.split(","); + if (textPointer.length != 3) { + throw new IllegalStateException("Invalid format in error file"); + } + + try { + int line = Integer.parseInt(textPointer[0]); + int startLineOffset = Integer.parseInt(textPointer[1]); + int endLineOffset = Integer.parseInt(textPointer[2]); + + significantCode.addRange(inputFile.newRange(line, startLineOffset, line, endLineOffset)); + + } catch (NumberFormatException e) { + throw new IllegalStateException("Invalid format in error file", e); + } + } + +} diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java index 9be43f0b4f3..dacd5b3f575 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java @@ -62,6 +62,6 @@ public class XooPluginTest { SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.2"), SonarQubeSide.SCANNER); Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); - assertThat(context.getExtensions()).hasSize(53).contains(OneExternalIssuePerLineSensor.class); + assertThat(context.getExtensions()).hasSize(54).contains(OneExternalIssuePerLineSensor.class); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java new file mode 100644 index 00000000000..115c1c030a2 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java @@ -0,0 +1,91 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.xoo.lang; + +import java.io.File; +import java.io.IOException; +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.fs.internal.DefaultTextPointer; +import org.sonar.api.batch.fs.internal.DefaultTextRange; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; +import org.sonar.api.batch.sensor.internal.SensorContextTester; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SignificantCodeSensorTest { + private SignificantCodeSensor sensor; + private SensorContextTester context; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private File baseDir; + + private InputFile inputFile; + + @Before + public void prepare() throws IOException { + baseDir = temp.newFolder(); + sensor = new SignificantCodeSensor(); + context = SensorContextTester.create(baseDir); + inputFile = new TestInputFileBuilder("foo", baseDir, new File(baseDir, "src/foo.xoo")) + .setLanguage("xoo") + .setContents("some lines\nof code\nyet another line") + .build(); + } + + @Test + public void testDescriptor() { + sensor.describe(new DefaultSensorDescriptor()); + } + + @Test + public void testNoExceptionIfNoFileWithOffsets() { + context.fileSystem().add(inputFile); + sensor.execute(context); + } + + @Test + public void testExecution() throws IOException { + File significantCode = new File(baseDir, "src/foo.xoo.significantCode"); + FileUtils.write(significantCode, "1,1,4\n2,2,5"); + context.fileSystem().add(inputFile); + + sensor.execute(context); + + assertThat(context.significantCodeTextRange("foo:src/foo.xoo", 1)).isEqualTo(range(1, 1, 4)); + assertThat(context.significantCodeTextRange("foo:src/foo.xoo", 2)).isEqualTo(range(2, 2, 5)); + } + + private static TextRange range(int line, int startOffset, int endOffset) { + return new DefaultTextRange(new DefaultTextPointer(line, startOffset), new DefaultTextPointer(line, endOffset)); + } +} |