/* * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.goide.runconfig.testing.coverage; import com.intellij.openapi.util.Factory; import com.intellij.rt.coverage.data.CoverageData; import com.intellij.rt.coverage.data.ProjectData; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import java.util.Map; public class GoCoverageProjectData extends ProjectData { @NotNull private final Map<String, FileData> myFilesData = ContainerUtil.newHashMap(); public void processFiles(@NotNull Processor<FileData> processor) { for (FileData fileData : myFilesData.values()) { if (!processor.process(fileData)) { return; } } } public void processFile(@NotNull String filePath, @NotNull Processor<RangeData> processor) { FileData fileData = myFilesData.get(filePath); if (fileData != null) { for (RangeData rangeData : fileData.myRangesData.values()) { if (!processor.process(rangeData)) { return; } } } } public void addData(String filePath, int startLine, int startColumn, int endLine, int endColumn, int statements, int hits) { FileData fileData = ContainerUtil.getOrCreate(myFilesData, filePath, new Factory<FileData>() { @Override public FileData create() { return new FileData(filePath); } }); fileData.add(startLine, startColumn, endLine, endColumn, statements, hits); } @Override public void merge(CoverageData data) { super.merge(data); if (data instanceof GoCoverageProjectData) { for (Map.Entry<String, FileData> entry : ((GoCoverageProjectData)data).myFilesData.entrySet()) { String filePath = entry.getKey(); FileData fileData = myFilesData.get(filePath); FileData fileDataToMerge = entry.getValue(); if (fileData != null) { for (Map.Entry<String, RangeData> dataEntry : fileDataToMerge.myRangesData.entrySet()) { RangeData existingRangeData = fileData.myRangesData.get(dataEntry.getKey()); if (existingRangeData != null) { fileData.myRangesData.put(dataEntry.getKey(), new RangeData(existingRangeData.startLine, existingRangeData.startColumn, existingRangeData.endLine, existingRangeData.endColumn, existingRangeData.statements, existingRangeData.hits + dataEntry.getValue().hits)); } else { fileData.myRangesData.put(dataEntry.getKey(), dataEntry.getValue()); } } } else { myFilesData.put(filePath, fileDataToMerge); } } } } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof GoCoverageProjectData)) return false; GoCoverageProjectData data = (GoCoverageProjectData)o; return myFilesData.equals(data.myFilesData); } @Override public int hashCode() { return myFilesData.hashCode(); } public static class FileData { @NotNull public final String myFilePath; @NotNull public final Map<String, RangeData> myRangesData = ContainerUtil.newHashMap(); public FileData(@NotNull String filePath) { myFilePath = filePath; } public void add(int startLine, int startColumn, int endLine, int endColumn, int statements, int hits) { myRangesData.put(rangeKey(startLine, startColumn, endLine, endColumn), new RangeData(startLine, startColumn, endLine, endColumn, statements, hits)); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof FileData)) return false; FileData fileData = (FileData)o; if (!myFilePath.equals(fileData.myFilePath)) return false; return myRangesData.equals(fileData.myRangesData); } @Override public int hashCode() { int result = myFilePath.hashCode(); result = 31 * result + myRangesData.hashCode(); return result; } } public static class RangeData { public final int startLine; public final int startColumn; public final int endLine; public final int endColumn; public final int hits; public final int statements; public RangeData(int startLine, int startColumn, int endLine, int endColumn, int statements, int hits) { this.startLine = startLine; this.startColumn = startColumn; this.endLine = endLine; this.endColumn = endColumn; this.hits = hits; this.statements = statements; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof RangeData)) return false; RangeData data = (RangeData)o; if (startLine != data.startLine) return false; if (startColumn != data.startColumn) return false; if (endLine != data.endLine) return false; if (endColumn != data.endColumn) return false; if (hits != data.hits) return false; return statements == data.statements; } @Override public int hashCode() { int result = startLine; result = 31 * result + startColumn; result = 31 * result + endLine; result = 31 * result + endColumn; result = 31 * result + hits; result = 31 * result + statements; return result; } @Override public String toString() { return rangeKey(startLine, startColumn, endLine, endColumn) + "; hits: " + hits + "; statements: " + statements; } } private static String rangeKey(int startLine, int startColumn, int endLine, int endColumn) { return startLine + ":" + startColumn + "-" + endLine + ":" + endColumn; } }