/* * Copyright 2010-2015 JetBrains s.r.o. * * 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 org.jetbrains.kotlin.test; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.editor.Editor; import org.jetbrains.annotations.NotNull; import java.util.List; public class TagsTestDataUtil { public static String insertInfoTags(List<LineMarkerInfo> lineMarkers, boolean withDescription, String text) { List<LineMarkerTagPoint> lineMarkerPoints = Lists.newArrayList(); for (LineMarkerInfo markerInfo : lineMarkers) { lineMarkerPoints.add(new LineMarkerTagPoint(markerInfo.startOffset, true, markerInfo, withDescription)); lineMarkerPoints.add(new LineMarkerTagPoint(markerInfo.endOffset, false, markerInfo, withDescription)); } return insertTagsInText(lineMarkerPoints, text); } public static String insertInfoTags(List<HighlightInfo> highlights, String text) { List<HighlightTagPoint> highlightPoints = Lists.newArrayList(); for (HighlightInfo highlight : highlights) { highlightPoints.add(new HighlightTagPoint(highlight.startOffset, true, highlight)); highlightPoints.add(new HighlightTagPoint(highlight.endOffset, false, highlight)); } return insertTagsInText(highlightPoints, text); } public static String generateTextWithCaretAndSelection(@NotNull Editor editor) { List<TagInfo> points = Lists.newArrayList(); points.add(new TagInfo<String>(editor.getCaretModel().getOffset(), true, "caret")); if (editor.getSelectionModel().hasSelection()) { points.add(new TagInfo<String>(editor.getSelectionModel().getSelectionStart(), true, "selection")); points.add(new TagInfo<String>(editor.getSelectionModel().getSelectionEnd(), false, "selection")); } return insertTagsInText(points, editor.getDocument().getText()); } public static String insertTagsInText(List<? extends TagInfo> tags, String text) { StringBuilder builder = new StringBuilder(text); List<? extends TagInfo> sortedTagPoints = Ordering.natural().reverse().sortedCopy(tags); // Insert tags into text starting from the end for preventing invalidating previous tags offsets for (TagInfo point : sortedTagPoints) { String tagText; if (point.isStart) { String attributesString = point.getAttributesString(); if (attributesString.isEmpty()) { tagText = String.format("<%s>", point.getName()); } else { tagText = String.format("<%s %s>", point.getName(), attributesString); } } else { tagText = String.format("</%s>", point.getName()); } builder.insert(point.offset, tagText); } return builder.toString(); } public static class TagInfo<Data> implements Comparable<TagInfo<?>> { protected final int offset; protected final boolean isStart; protected final Data data; public TagInfo(int offset, boolean start, Data data) { this.offset = offset; isStart = start; this.data = data; } @Override public int compareTo(@NotNull TagInfo<?> other) { if (offset != other.offset) { return ((Integer) offset).compareTo(other.offset); } if (isStart != other.isStart) { // All "starts" should go after "ends" for same offset return isStart ? -1 : 1; } String thisTag = this.getName(); String otherTag = other.getName(); // Invert order for end tags return thisTag.compareTo(otherTag) * (isStart ? -1 : 1); } @NotNull public String getName() { return data.toString(); } @NotNull public String getAttributesString() { return ""; } } private static class HighlightTagPoint extends TagInfo<HighlightInfo> { private final HighlightInfo highlightInfo; private HighlightTagPoint(int offset, boolean start, HighlightInfo info) { super(offset, start, info); highlightInfo = info; } @NotNull @Override public String getName() { return highlightInfo.getSeverity().equals(HighlightSeverity.INFORMATION) ? "info" : highlightInfo.getSeverity().toString().toLowerCase(); } @NotNull @Override public String getAttributesString() { if (isStart) { if (highlightInfo.getDescription() != null) { return String.format("textAttributesKey=\"%s\" descr=%s", highlightInfo.forcedTextAttributesKey, highlightInfo.getDescription()); } else { return String.format("textAttributesKey=\"%s\"", highlightInfo.forcedTextAttributesKey); } } else { return ""; } } } private static class LineMarkerTagPoint extends TagInfo<LineMarkerInfo> { private final boolean withDescription; public LineMarkerTagPoint(int offset, boolean start, LineMarkerInfo info, boolean withDescription) { super(offset, start, info); this.withDescription = withDescription; } @NotNull @Override public String getName() { return "lineMarker"; } @NotNull @Override public String getAttributesString() { return withDescription ? String.format("descr=\"%s\"", data.getLineMarkerTooltip()) : "descr=\"*\""; } } }