mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1536,10 +1536,8 @@ Function un.onInit
|
||||
Call un.UninstallFeedback
|
||||
|
||||
; Uninstallation was run from installation dir?
|
||||
IfFileExists "$INSTDIR\IdeaWin32.dll" 0 end_of_uninstall
|
||||
IfFileExists "$INSTDIR\IdeaWin64.dll" 0 end_of_uninstall
|
||||
IfFileExists "$INSTDIR\${PRODUCT_EXE_FILE_64}" 0 end_of_uninstall
|
||||
IfFileExists "$INSTDIR\${PRODUCT_EXE_FILE}" 0 end_of_uninstall
|
||||
|
||||
get_reg_key:
|
||||
SetRegView 32
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.engine;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
@@ -253,7 +253,7 @@ public class JVMNameUtil {
|
||||
|
||||
@NotNull
|
||||
public static JVMName getJVMQualifiedName(@NotNull PsiClass psiClass) {
|
||||
final String name = getNonAnonymousClassName(psiClass);
|
||||
final String name = getClassVMName(psiClass);
|
||||
if (name != null) {
|
||||
return getJVMRawText(name);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -41,7 +42,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class MethodCandidateInfo extends CandidateInfo{
|
||||
public static final RecursionGuard ourOverloadGuard = RecursionManager.createGuard("overload.guard");
|
||||
public static final ThreadLocal<Map<PsiElement, CurrentCandidateProperties>> CURRENT_CANDIDATE = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Map<PsiElement, CurrentCandidateProperties>> CURRENT_CANDIDATE = ThreadLocal.withInitial(HashMap::new);
|
||||
@ApplicabilityLevelConstant private volatile int myApplicabilityLevel;
|
||||
@ApplicabilityLevelConstant private volatile int myPertinentApplicabilityLevel;
|
||||
private final PsiElement myArgumentList;
|
||||
|
||||
@@ -14,6 +14,21 @@
|
||||
<style>
|
||||
.activityChart {
|
||||
width: 100%;
|
||||
/*
|
||||
our data has extraordinary high values (extremes) and it makes item chart not readable (extremes are visible and others column bars are too low),
|
||||
as solution, amCharts supports breaks (https://www.amcharts.com/demos/column-chart-with-axis-break/),
|
||||
but it contradicts to our goal - to show that these items are extremes,
|
||||
so, as solution, we increase chart height to give more space to render bars.
|
||||
|
||||
It is ok, as now we use UI Library (ElementUI) and can use Tabs, Collapse and any other component to group charts.
|
||||
Also, as we use Vue.js and Vue Router, it is one-line to provide dedicated view (/#/components and so on)
|
||||
*/
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.timeLineChart {
|
||||
width: 100%;
|
||||
/* in any case time line chart will adjust height according to items */
|
||||
height: 380px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,26 +15,33 @@ export abstract class BaseChartComponent<T extends ChartManager> extends Vue {
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.chartManager = this.createChartManager()
|
||||
this.renderDataIfAvailable()
|
||||
}
|
||||
|
||||
protected abstract createChartManager(): T
|
||||
|
||||
@Watch("measurementData")
|
||||
// @ts-ignore
|
||||
private measurementDataChanged(): void {
|
||||
this.renderDataIfAvailable()
|
||||
}
|
||||
|
||||
/** @final */
|
||||
protected renderDataIfAvailable(): void {
|
||||
const data = this.measurementData
|
||||
if (data != null) {
|
||||
const chartManager = this.chartManager
|
||||
if (chartManager != null) {
|
||||
chartManager.render(data)
|
||||
}
|
||||
if (data == null) {
|
||||
// yes, do not re-render as empty - null value not expected to be set in valid cases
|
||||
return
|
||||
}
|
||||
|
||||
let chartManager = this.chartManager
|
||||
if (chartManager == null) {
|
||||
chartManager = this.createChartManager()
|
||||
this.chartManager = chartManager
|
||||
}
|
||||
chartManager.render(data)
|
||||
}
|
||||
|
||||
beforeDestroy() {
|
||||
const chartManager = this.chartManager
|
||||
if (chartManager != null) {
|
||||
this.chartManager = null
|
||||
chartManager.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import {DataManager} from "@/state/DataManager"
|
||||
|
||||
export interface ChartManager {
|
||||
render(data: DataManager): void
|
||||
|
||||
dispose(): void
|
||||
}
|
||||
|
||||
function configureCommonChartSettings(chart: am4charts.XYChart) {
|
||||
@@ -15,7 +17,6 @@ function configureCommonChartSettings(chart: am4charts.XYChart) {
|
||||
const cursor = new am4charts.XYCursor()
|
||||
cursor.lineY.disabled = true
|
||||
cursor.lineX.disabled = true
|
||||
// todo y axis for ItemChart doesn't work as expected (not scaled according to current data) because of 2 series for axis (and so, no chart data is set)
|
||||
cursor.behavior = "zoomXY"
|
||||
chart.cursor = cursor
|
||||
}
|
||||
@@ -30,30 +31,10 @@ export abstract class XYChartManager implements ChartManager {
|
||||
// this.addDisposeHandler(childHot)
|
||||
}
|
||||
|
||||
/** @override */
|
||||
dispose(): void {
|
||||
this.chart.dispose()
|
||||
}
|
||||
|
||||
// module.hot must be passed here explicitly, because module in this context related only to this module
|
||||
// private addDisposeHandler(hot: __WebpackModuleApi.Hot | null | undefined) {
|
||||
// if (hot == null) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// hot.dispose(_data => {
|
||||
// const chart = this.chart
|
||||
// if (chart == null) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// (this as any).chart = null
|
||||
// chart.dispose()
|
||||
// // const exportingMenu = chart.exporting.menu
|
||||
// // if (exportingMenu != null) {
|
||||
// // exportingMenu.dispose()
|
||||
// // }
|
||||
// })
|
||||
// }
|
||||
|
||||
abstract render(data: DataManager): void
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Prop, Watch} from "vue-property-decorator"
|
||||
import {ComponentChartManager, ItemChartManager, ServiceChartManager, TopHitProviderChart} from "./ItemChartManager"
|
||||
import {ComponentChartManager, ItemChartManager} from "./ItemChartManager"
|
||||
import {ItemChartType} from "@/charts/ItemChartDescriptor"
|
||||
import {BaseChartComponent} from "@/charts/BaseChartComponent"
|
||||
|
||||
@@ -34,10 +34,13 @@
|
||||
return new ComponentChartManager(chartContainer)
|
||||
}
|
||||
else if (type === "services") {
|
||||
return new ServiceChartManager(chartContainer)
|
||||
return new ItemChartManager(chartContainer, ["appServices", "projectServices", "moduleServices"])
|
||||
}
|
||||
else if (type === "extensions") {
|
||||
return new ItemChartManager(chartContainer, ["appExtensions", "projectExtensions", "moduleExtensions"])
|
||||
}
|
||||
else if (type === "topHitProviders") {
|
||||
return new TopHitProviderChart(chartContainer)
|
||||
return new ItemChartManager(chartContainer, ["appOptionsTopHitProviders", "projectOptionsTopHitProviders"])
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unknown chart type: ${type}`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
export type ItemChartType = "components" | "services" | "topHitProviders"
|
||||
export type ItemChartType = "components" | "services" | "extensions" | "topHitProviders"
|
||||
|
||||
export interface ItemChartDescriptor {
|
||||
readonly label: string
|
||||
@@ -8,9 +8,10 @@ export interface ItemChartDescriptor {
|
||||
}
|
||||
|
||||
// not as part of ItemChartManager.ts to reduce scope of changes on change
|
||||
// (makes sure that hot reloading to not reload all modules where `chartDescriptors` is used - especially `router`)
|
||||
// (make sure that hot reloading will not reload all modules where `chartDescriptors` is used - especially `router`)
|
||||
export const chartDescriptors: Array<ItemChartDescriptor> = [
|
||||
{label: "Components", name: "components"},
|
||||
{label: "Services", name: "services"},
|
||||
{label: "Extensions", name: "extensions"},
|
||||
{label: "Options Top Hit Providers", name: "topHitProviders"},
|
||||
]
|
||||
|
||||
@@ -5,13 +5,18 @@ import {XYChartManager} from "@/charts/ChartManager"
|
||||
import {DataManager} from "@/state/DataManager"
|
||||
import {Item} from "@/state/data"
|
||||
|
||||
export type ComponentProviderSourceNames = "appComponents" | "projectComponents"
|
||||
export type ServiceProviderSourceNames = "appServices" | "projectServices"
|
||||
export type ComponentProviderSourceNames = "appComponents" | "projectComponents" | "moduleComponents"
|
||||
export type ServiceProviderSourceNames = "appServices" | "projectServices" | "moduleServices"
|
||||
export type ExtensionProviderSourceNames = "appExtensions" | "projectExtensions" | "moduleExtensions"
|
||||
export type TopHitProviderSourceNames = "appOptionsTopHitProviders" | "projectOptionsTopHitProviders"
|
||||
|
||||
export abstract class ItemChartManager extends XYChartManager {
|
||||
export class ItemChartManager extends XYChartManager {
|
||||
// isUseYForName - if true, names are more readable, but not possible to see all components because layout from top to bottom (so, opposite from left to right some data can be out of current screen)
|
||||
protected constructor(container: HTMLElement, private readonly sourceNames: Array<ComponentProviderSourceNames> | Array<TopHitProviderSourceNames> | Array<ServiceProviderSourceNames>) {
|
||||
constructor(container: HTMLElement,
|
||||
private readonly sourceNames: Array<ComponentProviderSourceNames>
|
||||
| Array<TopHitProviderSourceNames>
|
||||
| Array<ServiceProviderSourceNames>
|
||||
| Array<ExtensionProviderSourceNames>) {
|
||||
super(container, module.hot)
|
||||
|
||||
this.configureNameAxis()
|
||||
@@ -50,14 +55,21 @@ export abstract class ItemChartManager extends XYChartManager {
|
||||
private configureDurationAxis(): void {
|
||||
const durationAxis = this.chart.yAxes.push(new am4charts.DurationAxis())
|
||||
durationAxis.title.text = "Duration"
|
||||
durationAxis.baseUnit = "millisecond"
|
||||
// base unit the values are in (https://www.amcharts.com/docs/v4/reference/durationformatter/)
|
||||
durationAxis.durationFormatter.baseUnit = "millisecond"
|
||||
durationAxis.durationFormatter.durationFormat = "S"
|
||||
// do not set strictMinMax because otherwise zooming will not work
|
||||
// (axis will not reflect currently selected items, but always the whole set and so, will be not convenient to see items with small values)
|
||||
// durationAxis.strictMinMax = true
|
||||
|
||||
// cursor tooltip is distracting
|
||||
durationAxis.cursorTooltipEnabled = false
|
||||
|
||||
// https://www.amcharts.com/docs/v4/concepts/axes/positioning-axis-elements/#Setting_the_density_of_the_the_grid_labels
|
||||
// default value 40 makes distribution not good
|
||||
// but for other charts default value suits better...
|
||||
// decided to not do anything - if you don't like that extremes makes chart not readable - fix these extremes or select desired area (cursor is supported)
|
||||
}
|
||||
|
||||
protected configureSeries(): void {
|
||||
@@ -69,7 +81,7 @@ export abstract class ItemChartManager extends XYChartManager {
|
||||
}
|
||||
|
||||
// https://www.amcharts.com/docs/v4/concepts/series/#Note_about_Series_data_and_Category_axis
|
||||
render(data: DataManager) {
|
||||
render(data: DataManager): void {
|
||||
const concatenatedData: Array<ClassItem> = []
|
||||
let colorIndex = 0
|
||||
const legendData: Array<LegendItem> = []
|
||||
@@ -83,17 +95,21 @@ export abstract class ItemChartManager extends XYChartManager {
|
||||
stroke: color,
|
||||
}
|
||||
|
||||
// generate color before - even if no data for this type of items, still color should be the same regardless of current data set
|
||||
// so, if currently no data for project, but there is data for modules, color for modules should use index 3 and not 2
|
||||
const items = data.data[sourceName]
|
||||
if (items == null || items.length === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
const legendItem: LegendItem = {
|
||||
name: (sourceName.startsWith("app") ? "Application" : "Project") + "-level",
|
||||
name: this.sourceNameToLegendName(sourceName, items.length),
|
||||
fill: color,
|
||||
sourceName,
|
||||
}
|
||||
legendData.push(legendItem)
|
||||
applicableSources.add(sourceName)
|
||||
|
||||
// generate color before - even if no data for this type of items, still color should be the same regardless of current data set
|
||||
// so, if currently no data for project, but there is data for modules, color for modules should use index 3 and not 2
|
||||
const items = data.data[sourceName] || []
|
||||
for (const item of items) {
|
||||
concatenatedData.push({
|
||||
...item,
|
||||
@@ -123,7 +139,21 @@ export abstract class ItemChartManager extends XYChartManager {
|
||||
this.chart.data = concatenatedData
|
||||
}
|
||||
|
||||
protected computeRangeMarkers(data: DataManager, items: Array<ClassItem>) {
|
||||
private sourceNameToLegendName(sourceName: string, itemCount: number): string {
|
||||
let prefix
|
||||
if (sourceName.startsWith("app")) {
|
||||
prefix = "Application"
|
||||
}
|
||||
else if (sourceName.startsWith("project")) {
|
||||
prefix = "Project"
|
||||
}
|
||||
else if (sourceName.startsWith("module")) {
|
||||
prefix = "Module"
|
||||
}
|
||||
return `${prefix}-level (${itemCount})`
|
||||
}
|
||||
|
||||
protected computeRangeMarkers(data: DataManager, items: Array<ClassItem>): void {
|
||||
const nameAxis = this.nameAxis
|
||||
nameAxis.axisRanges.clear()
|
||||
for (const guideLineDescriptor of data.computeGuides(items)) {
|
||||
@@ -131,7 +161,7 @@ export abstract class ItemChartManager extends XYChartManager {
|
||||
}
|
||||
}
|
||||
|
||||
private createRangeMarker(axis: am4charts.CategoryAxis, item: ClassItem, label: string) {
|
||||
private createRangeMarker(axis: am4charts.CategoryAxis, item: ClassItem, label: string): void {
|
||||
const range = axis.axisRanges.create()
|
||||
range.category = item.shortName
|
||||
range.label.inside = true
|
||||
@@ -160,7 +190,7 @@ function getShortName(item: Item): string {
|
||||
|
||||
export class ComponentChartManager extends ItemChartManager {
|
||||
constructor(container: HTMLElement) {
|
||||
super(container, ["appComponents", "projectComponents"])
|
||||
super(container, ["appComponents", "projectComponents", "moduleComponents"])
|
||||
}
|
||||
|
||||
// doesn't make sense for components - cannot be outside of ready, and app initialized is clear
|
||||
@@ -169,18 +199,6 @@ export class ComponentChartManager extends ItemChartManager {
|
||||
}
|
||||
}
|
||||
|
||||
export class ServiceChartManager extends ItemChartManager {
|
||||
constructor(container: HTMLElement) {
|
||||
super(container, ["appServices", "projectServices"])
|
||||
}
|
||||
}
|
||||
|
||||
export class TopHitProviderChart extends ItemChartManager {
|
||||
constructor(container: HTMLElement) {
|
||||
super(container, ["appOptionsTopHitProviders", "projectOptionsTopHitProviders"])
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendItem {
|
||||
readonly name: string
|
||||
readonly sourceName: string
|
||||
|
||||
@@ -16,9 +16,15 @@ export interface InputData {
|
||||
|
||||
appComponents?: Array<Item>
|
||||
projectComponents?: Array<Item>
|
||||
moduleComponents?: Array<Item>
|
||||
|
||||
appServices?: Array<Item>
|
||||
projectServices?: Array<Item>
|
||||
moduleServices?: Array<Item>
|
||||
|
||||
appExtensions?: Array<Item>
|
||||
projectExtensions?: Array<Item>
|
||||
moduleExtensions?: Array<Item>
|
||||
|
||||
preloadActivities?: Array<Item>
|
||||
appOptionsTopHitProviders?: Array<Item>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||
<template>
|
||||
<div class="activityChart" ref="chartContainer"></div>
|
||||
<div class="timeLineChart" ref="chartContainer"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
@@ -11,8 +11,8 @@ import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
// A way to remove stalled/unused component data.
|
||||
internal val STALLED_STORAGE_EP = ExtensionPointName<StalledStorageBean>("com.intellij.stalledStorage")
|
||||
// A way to remove obsolete component data.
|
||||
internal val OBSOLETE_STORAGE_EP = ExtensionPointName<ObsoleteStorageBean>("com.intellij.obsoleteStorage")
|
||||
|
||||
abstract class ComponentStoreWithExtraComponents : ComponentStoreImpl() {
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -81,14 +81,14 @@ abstract class ComponentStoreWithExtraComponents : ComponentStoreImpl() {
|
||||
override fun commitComponents(isForce: Boolean, session: SaveSessionProducerManager, errors: MutableList<Throwable>) {
|
||||
// ensure that this task will not interrupt regular saving
|
||||
LOG.runAndLogException {
|
||||
commitStalledComponents(session, false)
|
||||
commitObsoleteComponents(session, false)
|
||||
}
|
||||
|
||||
super.commitComponents(isForce, session, errors)
|
||||
}
|
||||
|
||||
internal open fun commitStalledComponents(session: SaveSessionProducerManager, isProjectLevel: Boolean) {
|
||||
for (bean in STALLED_STORAGE_EP.extensionList) {
|
||||
internal open fun commitObsoleteComponents(session: SaveSessionProducerManager, isProjectLevel: Boolean) {
|
||||
for (bean in OBSOLETE_STORAGE_EP.extensionList) {
|
||||
if (bean.isProjectLevel != isProjectLevel) {
|
||||
continue
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import com.intellij.util.xmlb.annotations.XCollection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
final class StalledStorageBean {
|
||||
final class ObsoleteStorageBean {
|
||||
@Attribute
|
||||
public String file;
|
||||
|
||||
@@ -353,9 +353,9 @@ private open class ProjectStoreImpl(project: Project, private val pathMacroManag
|
||||
|
||||
final override fun createSaveSessionProducerManager() = ProjectSaveSessionProducerManager(project)
|
||||
|
||||
final override fun commitStalledComponents(session: SaveSessionProducerManager, isProjectLevel: Boolean) {
|
||||
final override fun commitObsoleteComponents(session: SaveSessionProducerManager, isProjectLevel: Boolean) {
|
||||
if (isDirectoryBased) {
|
||||
super.commitStalledComponents(session, true)
|
||||
super.commitObsoleteComponents(session, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,10 +299,10 @@ internal class ApplicationStoreTest {
|
||||
|
||||
@Test
|
||||
fun `remove stalled data`() = runBlocking<Unit> {
|
||||
val stalledStorageBean = StalledStorageBean()
|
||||
stalledStorageBean.file = "i_do_not_want_to_be_deleted_but.xml"
|
||||
stalledStorageBean.components.addAll(listOf("loser1", "loser2", "lucky"))
|
||||
PlatformTestUtil.maskExtensions(STALLED_STORAGE_EP, listOf(stalledStorageBean), disposableRule.disposable)
|
||||
val obsoleteStorageBean = ObsoleteStorageBean()
|
||||
obsoleteStorageBean.file = "i_do_not_want_to_be_deleted_but.xml"
|
||||
obsoleteStorageBean.components.addAll(listOf("loser1", "loser2", "lucky"))
|
||||
PlatformTestUtil.maskExtensions(OBSOLETE_STORAGE_EP, listOf(obsoleteStorageBean), disposableRule.disposable)
|
||||
|
||||
@State(name = "loser1", storages = [(Storage(value = "i_do_not_want_to_be_deleted_but.xml"))])
|
||||
class AOther : A()
|
||||
@@ -325,8 +325,8 @@ internal class ApplicationStoreTest {
|
||||
|
||||
componentStore.save()
|
||||
|
||||
// all must be saved regardless of stalledStorageBean because we have such components
|
||||
assertThat(testAppConfig.resolve(stalledStorageBean.file)).isEqualTo("""
|
||||
// all must be saved regardless of obsoleteStorageBean because we have such components
|
||||
assertThat(testAppConfig.resolve(obsoleteStorageBean.file)).isEqualTo("""
|
||||
<application>
|
||||
<component name="loser1" foo="old" />
|
||||
<component name="loser2" foo="old?" />
|
||||
@@ -338,7 +338,7 @@ internal class ApplicationStoreTest {
|
||||
|
||||
// first looser is deleted since state equals to default (no committed component data)
|
||||
componentStore.save()
|
||||
assertThat(testAppConfig.resolve(stalledStorageBean.file)).isEqualTo("""
|
||||
assertThat(testAppConfig.resolve(obsoleteStorageBean.file)).isEqualTo("""
|
||||
<application>
|
||||
<component name="loser2" foo="old?" />
|
||||
<component name="lucky" bar="foo" />
|
||||
@@ -349,7 +349,7 @@ internal class ApplicationStoreTest {
|
||||
|
||||
// second looser is deleted since state equals to default (no committed component data)
|
||||
componentStore.save()
|
||||
assertThat(testAppConfig.resolve(stalledStorageBean.file)).isEqualTo("""
|
||||
assertThat(testAppConfig.resolve(obsoleteStorageBean.file)).isEqualTo("""
|
||||
<application>
|
||||
<component name="lucky" bar="foo" />
|
||||
</application>
|
||||
@@ -358,12 +358,12 @@ internal class ApplicationStoreTest {
|
||||
|
||||
@Test
|
||||
fun `remove stalled data - keep file if another unknown component`() = runBlocking<Unit> {
|
||||
val stalledStorageBean = StalledStorageBean()
|
||||
stalledStorageBean.file = "i_will_be_not_deleted.xml"
|
||||
stalledStorageBean.components.addAll(listOf("Loser"))
|
||||
PlatformTestUtil.maskExtensions(STALLED_STORAGE_EP, listOf(stalledStorageBean), disposableRule.disposable)
|
||||
val obsoleteStorageBean = ObsoleteStorageBean()
|
||||
obsoleteStorageBean.file = "i_will_be_not_deleted.xml"
|
||||
obsoleteStorageBean.components.addAll(listOf("Loser"))
|
||||
PlatformTestUtil.maskExtensions(OBSOLETE_STORAGE_EP, listOf(obsoleteStorageBean), disposableRule.disposable)
|
||||
|
||||
testAppConfig.resolve(stalledStorageBean.file).write("""
|
||||
testAppConfig.resolve(obsoleteStorageBean.file).write("""
|
||||
<application>
|
||||
<component name="Unknown" data="some data" />
|
||||
<component name="Loser" foo="old?" />
|
||||
@@ -372,7 +372,7 @@ internal class ApplicationStoreTest {
|
||||
|
||||
componentStore.save()
|
||||
|
||||
assertThat(testAppConfig.resolve(stalledStorageBean.file)).isEqualTo("""
|
||||
assertThat(testAppConfig.resolve(obsoleteStorageBean.file)).isEqualTo("""
|
||||
<application>
|
||||
<component name="Unknown" data="some data" />
|
||||
</application>
|
||||
|
||||
@@ -182,16 +182,16 @@ internal class ProjectStoreTest {
|
||||
""".trimIndent())
|
||||
it.path
|
||||
}) { project ->
|
||||
val stalledStorageBean = StalledStorageBean()
|
||||
val obsoleteStorageBean = ObsoleteStorageBean()
|
||||
val storageFileName = "foo.xml"
|
||||
stalledStorageBean.file = storageFileName
|
||||
stalledStorageBean.components.addAll(listOf("AppLevelLoser"))
|
||||
obsoleteStorageBean.file = storageFileName
|
||||
obsoleteStorageBean.components.addAll(listOf("AppLevelLoser"))
|
||||
|
||||
val projectStalledStorageBean = StalledStorageBean()
|
||||
val projectStalledStorageBean = ObsoleteStorageBean()
|
||||
projectStalledStorageBean.file = storageFileName
|
||||
projectStalledStorageBean.isProjectLevel = true
|
||||
projectStalledStorageBean.components.addAll(listOf("ProjectLevelLoser"))
|
||||
PlatformTestUtil.maskExtensions(STALLED_STORAGE_EP, listOf(stalledStorageBean, projectStalledStorageBean), project)
|
||||
PlatformTestUtil.maskExtensions(OBSOLETE_STORAGE_EP, listOf(obsoleteStorageBean, projectStalledStorageBean), project)
|
||||
|
||||
val componentStore = project.stateStore
|
||||
|
||||
@@ -204,7 +204,7 @@ internal class ProjectStoreTest {
|
||||
|
||||
componentStore.save()
|
||||
|
||||
assertThat(Paths.get(project.stateStore.storageManager.expandMacros(PROJECT_CONFIG_DIR)).resolve(stalledStorageBean.file)).isEqualTo("""
|
||||
assertThat(Paths.get(project.stateStore.storageManager.expandMacros(PROJECT_CONFIG_DIR)).resolve(obsoleteStorageBean.file)).isEqualTo("""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AppLevelLoser" foo="old?" />
|
||||
|
||||
+3
-3
@@ -44,6 +44,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.util.pico.DefaultPicoContainer.getMeasureTokenLevel;
|
||||
|
||||
public abstract class ComponentManagerImpl extends UserDataHolderBase implements ComponentManagerEx, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.components.ComponentManager");
|
||||
|
||||
@@ -481,9 +483,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
|
||||
return instance;
|
||||
}
|
||||
|
||||
// if it will be module component, then get rid of such component instead of measurement
|
||||
boolean appComponent = ComponentManagerImpl.this instanceof Application;
|
||||
StartUpMeasurer.MeasureToken measureToken = StartUpMeasurer.start(appComponent ? Activities.APP_COMPONENT : Activities.PROJECT_COMPONENT);
|
||||
StartUpMeasurer.MeasureToken measureToken = StartUpMeasurer.start(Activities.COMPONENT, getMeasureTokenLevel(picoContainer));
|
||||
instance = super.getComponentInstance(picoContainer);
|
||||
|
||||
if (myInitializing) {
|
||||
|
||||
+9
-1
@@ -10,6 +10,8 @@ import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ArrayFactory;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.StartUpMeasurer;
|
||||
import com.intellij.util.StartUpMeasurer.Activities;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.OpenTHashSet;
|
||||
import org.jdom.Element;
|
||||
@@ -25,6 +27,8 @@ import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.intellij.util.pico.DefaultPicoContainer.getMeasureTokenLevel;
|
||||
|
||||
/**
|
||||
* @author AKireyev
|
||||
*/
|
||||
@@ -272,6 +276,8 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T> {
|
||||
}
|
||||
assertNotReadOnlyMode();
|
||||
|
||||
StartUpMeasurer.MeasureToken measureToken = StartUpMeasurer.start(Activities.EXTENSION, getMeasureTokenLevel(myPicoContainer));
|
||||
|
||||
int totalSize = myAdapters.size();
|
||||
Class<T> extensionClass = getExtensionClass();
|
||||
T[] result = ArrayUtil.newArray(extensionClass, totalSize);
|
||||
@@ -281,7 +287,6 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T> {
|
||||
|
||||
// check before to avoid any "restore" work if already cancelled
|
||||
CHECK_CANCELED.run();
|
||||
|
||||
processingAdaptersNow = true;
|
||||
try {
|
||||
List<ExtensionComponentAdapter> adapters = myAdapters;
|
||||
@@ -332,6 +337,9 @@ public abstract class ExtensionPointImpl<T> implements ExtensionPoint<T> {
|
||||
if (extensionIndex != result.length) {
|
||||
result = Arrays.copyOf(result, extensionIndex);
|
||||
}
|
||||
|
||||
// don't count ProcessCanceledException as valid action to measure (later special category can be introduced if needed)
|
||||
measureToken.endWithThreshold(extensionClass);
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.intellij.util.pico;
|
||||
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.StartUpMeasurer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FList;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -403,4 +404,18 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
public String toString() {
|
||||
return "DefaultPicoContainer" + (getParent() == null ? " (root)" : " (parent="+getParent()+")");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StartUpMeasurer.Level getMeasureTokenLevel(@NotNull PicoContainer picoContainer) {
|
||||
PicoContainer parent = picoContainer.getParent();
|
||||
if (parent == null) {
|
||||
return StartUpMeasurer.Level.APPLICATION;
|
||||
}
|
||||
else if (parent.getParent() == null) {
|
||||
return StartUpMeasurer.Level.PROJECT;
|
||||
}
|
||||
else {
|
||||
return StartUpMeasurer.Level.MODULE;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -38,6 +38,7 @@ import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.ExceptionUtilRt;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.PathKt;
|
||||
@@ -268,7 +269,7 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
|
||||
@SystemIndependent
|
||||
protected String path(@NotNull String relativePath) {
|
||||
return file(relativePath).getPath();
|
||||
return PathUtil.toSystemIndependentName(file(relativePath).getPath());
|
||||
}
|
||||
|
||||
protected File file(@NotNull String relativePath) {
|
||||
|
||||
@@ -86,12 +86,16 @@ class StartUpPerformanceReporter : StartupActivity, DumbAware {
|
||||
private fun logStats(end: Long, activationNumber: Int) {
|
||||
val items = mutableListOf<Item>()
|
||||
val activities = THashMap<String, MutableList<Item>>()
|
||||
|
||||
StartUpMeasurer.processAndClear(Consumer { item ->
|
||||
if (item.name.first() == '_') {
|
||||
activities.getOrPut(item.name) { mutableListOf() }.add(item)
|
||||
fun addActivity(name: String) {
|
||||
activities.getOrPut(name) { mutableListOf() }.add(item)
|
||||
}
|
||||
else {
|
||||
items.add(item)
|
||||
|
||||
when {
|
||||
item.name.first() == '_' -> addActivity(item.name)
|
||||
item.level != null -> addActivity("${item.level!!.jsonFieldNamePrefix}${item.name.capitalize()}")
|
||||
else -> items.add(item)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -161,9 +165,10 @@ class StartUpPerformanceReporter : StartupActivity, DumbAware {
|
||||
}
|
||||
|
||||
private fun activityNameToJsonFieldName(name: String): String {
|
||||
val firstIndex = if (name.startsWith('_')) 1 else 0
|
||||
return when {
|
||||
name.last() == 'y' -> name.substring(1, name.length - 1) + "ies"
|
||||
else -> name.substring(1) + 's'
|
||||
name.last() == 'y' -> name.substring(firstIndex, name.length - 1) + "ies"
|
||||
else -> name.substring(firstIndex) + 's'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -41,6 +41,8 @@ import java.util.List;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.intellij.util.pico.DefaultPicoContainer.getMeasureTokenLevel;
|
||||
|
||||
public final class ServiceManagerImpl implements Disposable {
|
||||
private static final Logger LOG = Logger.getInstance(ServiceManagerImpl.class);
|
||||
|
||||
@@ -231,9 +233,7 @@ public final class ServiceManagerImpl implements Disposable {
|
||||
|
||||
@NotNull
|
||||
private Object createAndInitialize(@NotNull PicoContainer container) {
|
||||
// if it will be module service, then get rid of such component instead of measurement
|
||||
boolean appComponent = myComponentManager instanceof Application;
|
||||
StartUpMeasurer.MeasureToken measureToken = StartUpMeasurer.start(appComponent ? Activities.APP_SERVICE : Activities.PROJECT_SERVICE);
|
||||
StartUpMeasurer.MeasureToken measureToken = StartUpMeasurer.start(Activities.SERVICE, getMeasureTokenLevel(container));
|
||||
Object instance = getDelegate().getComponentInstance(container);
|
||||
if (instance instanceof Disposable) {
|
||||
Disposer.register(myComponentManager, (Disposable)instance);
|
||||
|
||||
@@ -348,6 +348,6 @@
|
||||
|
||||
<extensionPoint qualifiedName="com.intellij.search.traverseUiHelper" interface="com.intellij.ide.ui.search.TraverseUIHelper"/>
|
||||
|
||||
<extensionPoint name="stalledStorage" beanClass="com.intellij.configurationStore.StalledStorageBean"/>
|
||||
<extensionPoint name="obsoleteStorage" beanClass="com.intellij.configurationStore.ObsoleteStorageBean"/>
|
||||
</extensionPoints>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -600,28 +600,28 @@
|
||||
|
||||
<rawEditorTypedHandler implementationClass="com.intellij.openapi.editor.impl.EditorFactoryImpl$MyRawTypedHandler"/>
|
||||
|
||||
<stalledStorage file="statistics.toolbar.clicks.xml">
|
||||
<obsoleteStorage file="statistics.toolbar.clicks.xml">
|
||||
<components>
|
||||
<component>ToolbarClicksCollector</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
<stalledStorage file="statistics.main_menu.xml">
|
||||
</obsoleteStorage>
|
||||
<obsoleteStorage file="statistics.main_menu.xml">
|
||||
<components>
|
||||
<component>MainMenuCollector</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
<stalledStorage file="statistics.shortcuts.xml">
|
||||
</obsoleteStorage>
|
||||
<obsoleteStorage file="statistics.shortcuts.xml">
|
||||
<components>
|
||||
<component>ShortcutsCollector</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
<stalledStorage file="statistics.application.usages.xml">
|
||||
</obsoleteStorage>
|
||||
<obsoleteStorage file="statistics.application.usages.xml">
|
||||
<components>
|
||||
<component>StatisticsApplicationUsages</component>
|
||||
<component>UsageTrigger</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
<stalledStorage file="usage.statistics.xml">
|
||||
</obsoleteStorage>
|
||||
<obsoleteStorage file="usage.statistics.xml">
|
||||
<components>
|
||||
<component>StatisticsApplicationUsages</component>
|
||||
<component>UsageTrigger</component>
|
||||
@@ -634,18 +634,18 @@
|
||||
<component>ActionsCollector</component>
|
||||
<component>FUSApplicationUsageTrigger</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
</obsoleteStorage>
|
||||
|
||||
<stalledStorage file="usage.statistics.xml" isProjectLevel="true">
|
||||
<obsoleteStorage file="usage.statistics.xml" isProjectLevel="true">
|
||||
<components>
|
||||
<component>FUSProjectUsageTrigger</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
<stalledStorage file="workspace.xml" isProjectLevel="true">
|
||||
</obsoleteStorage>
|
||||
<obsoleteStorage file="workspace.xml" isProjectLevel="true">
|
||||
<components>
|
||||
<component>FUSProjectUsageTrigger</component>
|
||||
</components>
|
||||
</stalledStorage>
|
||||
</obsoleteStorage>
|
||||
|
||||
<postStartupActivity implementation="com.intellij.ide.StartUpPerformanceReporter" order="last"/>
|
||||
</extensions>
|
||||
|
||||
+39
-11
@@ -42,13 +42,27 @@ public final class StartUpMeasurer {
|
||||
public static final String LOAD_MODULES = "module loading";
|
||||
}
|
||||
|
||||
// ExtensionAreas not available for ExtensionPointImpl
|
||||
public enum Level {
|
||||
APPLICATION("app"), PROJECT("project"), MODULE("module");
|
||||
|
||||
private final String jsonFieldNamePrefix;
|
||||
|
||||
Level(@NotNull String jsonFieldNamePrefix) {
|
||||
this.jsonFieldNamePrefix = jsonFieldNamePrefix;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getJsonFieldNamePrefix() {
|
||||
return jsonFieldNamePrefix;
|
||||
}
|
||||
}
|
||||
|
||||
// non-sequential and repeated items
|
||||
public static final class Activities {
|
||||
public static final String APP_COMPONENT = "_appComponent";
|
||||
public static final String PROJECT_COMPONENT = "_projectComponent";
|
||||
|
||||
public static final String APP_SERVICE = "_appService";
|
||||
public static final String PROJECT_SERVICE = "_projectService";
|
||||
public static final String COMPONENT = "component";
|
||||
public static final String SERVICE = "service";
|
||||
public static final String EXTENSION = "extension";
|
||||
|
||||
public static final String PRELOAD_ACTIVITY = "_preloadActivity";
|
||||
|
||||
@@ -66,12 +80,17 @@ public final class StartUpMeasurer {
|
||||
|
||||
@NotNull
|
||||
public static MeasureToken start(@NotNull String name, @Nullable String description) {
|
||||
return new Item(name, description);
|
||||
return new Item(name, description, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MeasureToken start(@NotNull String name) {
|
||||
return new Item(name, null);
|
||||
return new Item(name, null, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MeasureToken start(@NotNull String name, @NotNull Level level) {
|
||||
return new Item(name, null, level);
|
||||
}
|
||||
|
||||
public static void processAndClear(@NotNull Consumer<Item> consumer) {
|
||||
@@ -95,15 +114,19 @@ public final class StartUpMeasurer {
|
||||
// null doesn't mean root - not obligated to set parent, only as hint
|
||||
private final Item parent;
|
||||
|
||||
private Item(@Nullable String name, @Nullable String description) {
|
||||
this(name, description, System.nanoTime(), null);
|
||||
@Nullable
|
||||
private final Level myLevel;
|
||||
|
||||
private Item(@Nullable String name, @Nullable String description, @Nullable Level level) {
|
||||
this(name, description, System.nanoTime(), null, level);
|
||||
}
|
||||
|
||||
private Item(@Nullable String name, @Nullable String description, long start, @Nullable Item parent) {
|
||||
private Item(@Nullable String name, @Nullable String description, long start, @Nullable Item parent, @Nullable Level level) {
|
||||
this.name = name;
|
||||
this.description = StringUtil.nullize(description);
|
||||
this.start = start;
|
||||
this.parent = parent;
|
||||
myLevel = level;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -111,12 +134,17 @@ public final class StartUpMeasurer {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Level getLevel() {
|
||||
return myLevel;
|
||||
}
|
||||
|
||||
// and how do we can sort correctly, when parent item equals to child (start and end) and also there is another child with start equals to end?
|
||||
// so, parent added to API but as it was not enough, decided to measure time in nanoseconds instead of ms to mitigate such situations
|
||||
@Override
|
||||
@NotNull
|
||||
public Item startChild(@NotNull String name) {
|
||||
return new Item(name, null, System.nanoTime(), this);
|
||||
return new Item(name, null, System.nanoTime(), this, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -208,6 +208,13 @@ public class PluginXmlDomInspection extends BasicDomElementsInspection<IdeaPlugi
|
||||
|
||||
if (!hasRealPluginId(ideaPlugin)) return;
|
||||
|
||||
String id = ideaPlugin.getId().getStringValue();
|
||||
if (id != null &&
|
||||
(StringUtil.startsWith(id, "com.android.") ||
|
||||
id.equals("org.jetbrains.android"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
XmlTag xmlTag = ideaPlugin.getXmlTag();
|
||||
if (xmlTag == null) return;
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<idea-plugin>
|
||||
<id>com.android.something</id>
|
||||
<version>1</version>
|
||||
<vendor>JB is not required due to ID</vendor>
|
||||
</idea-plugin>
|
||||
+4
@@ -397,6 +397,10 @@ class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase {
|
||||
testHighlightingInIdeaProject("pluginWithJetBrainsAndMeAsVendor.xml")
|
||||
}
|
||||
|
||||
void testPluginXmlInIdeaProjectWithAndroidId() {
|
||||
testHighlightingInIdeaProject("pluginWithAndroidIdVendor.xml")
|
||||
}
|
||||
|
||||
void testSpecifyJetBrainsAsVendorQuickFix() {
|
||||
PsiUtil.markAsIdeaProject(project, true)
|
||||
try {
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.idea.devkit.inspections.missingApi
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.idea.devkit.kotlin.inspections.missingApi
|
||||
|
||||
import com.intellij.testFramework.TestDataPath
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.project.PluginProjectWithIdeaJdkDescriptor
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.project.PluginProjectWithIdeaLibraryDescriptor
|
||||
import org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project.PluginProjectWithIdeaJdkDescriptor
|
||||
import org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project.PluginProjectWithIdeaLibraryDescriptor
|
||||
|
||||
@TestDataPath("\$CONTENT_ROOT/testData/inspections/missingApi")
|
||||
abstract class JavaMissingRecentApiInspectionTestBase : MissingRecentApiInspectionTestBase() {
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.idea.devkit.kotlin.inspections.missingApi
|
||||
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.MissingRecentApiInspectionTestBase
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.project.PluginProjectWithIdeaJdkDescriptor
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.project.PluginProjectWithIdeaLibraryDescriptor
|
||||
import org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project.PluginProjectWithIdeaJdkDescriptor
|
||||
import org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project.PluginProjectWithIdeaLibraryDescriptor
|
||||
|
||||
abstract class KotlinMissingRecentApiInspectionTestBase : MissingRecentApiInspectionTestBase() {
|
||||
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.idea.devkit.inspections.missingApi
|
||||
package org.jetbrains.idea.devkit.kotlin.inspections.missingApi
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil
|
||||
import com.intellij.openapi.roots.JavaModuleExternalPaths
|
||||
@@ -9,8 +9,10 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.TestDataPath
|
||||
import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
|
||||
import org.jetbrains.idea.devkit.inspections.PluginModuleTestCase
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.project.PluginProjectWithIdeaJdkDescriptor
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.project.PluginProjectWithIdeaLibraryDescriptor
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.MissingRecentApiInspection
|
||||
import org.jetbrains.idea.devkit.inspections.missingApi.MissingRecentApiVisitor
|
||||
import org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project.PluginProjectWithIdeaJdkDescriptor
|
||||
import org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project.PluginProjectWithIdeaLibraryDescriptor
|
||||
|
||||
/**
|
||||
* Base class for tests of [MissingRecentApiInspection] on Java and Kotlin sources.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.idea.devkit.inspections.missingApi.project
|
||||
package org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project
|
||||
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.idea.devkit.inspections.missingApi.project
|
||||
package org.jetbrains.idea.devkit.kotlin.inspections.missingApi.project
|
||||
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
Reference in New Issue
Block a user