mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cleanup: notnull, add mutation annotations, optimize list copying, deduplicate
GitOrigin-RevId: 16dc54f0e3b3b666caad8377f0769a22b1e1623b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c8e750adf1
commit
ffa0186613
+10
-42
@@ -22,8 +22,8 @@ import java.util.*;
|
||||
final class CachingConstructorInjectionComponentAdapter implements ComponentAdapter {
|
||||
private static final ThreadLocal<Set<Class<?>>> ourGuard = new ThreadLocal<>();
|
||||
private final PicoContainer container;
|
||||
private final Object key;
|
||||
private final Class<?> componentImplementation;
|
||||
private final @NotNull Object key;
|
||||
private final @NotNull Class<?> componentImplementation;
|
||||
private Object myInstance;
|
||||
|
||||
CachingConstructorInjectionComponentAdapter(@NotNull PicoContainer container,
|
||||
@@ -35,12 +35,12 @@ final class CachingConstructorInjectionComponentAdapter implements ComponentAdap
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComponentKey() {
|
||||
public @NotNull Object getComponentKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getComponentImplementation() {
|
||||
public @NotNull Class<?> getComponentImplementation() {
|
||||
return componentImplementation;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ final class CachingConstructorInjectionComponentAdapter implements ComponentAdap
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComponentInstance() {
|
||||
public @NotNull Object getComponentInstance() {
|
||||
Object instance = myInstance;
|
||||
if (instance == null) {
|
||||
instance = instantiateGuarded(this, container, getComponentImplementation());
|
||||
@@ -59,9 +59,9 @@ final class CachingConstructorInjectionComponentAdapter implements ComponentAdap
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static @NotNull Object instantiateGuarded(@Nullable CachingConstructorInjectionComponentAdapter adapter,
|
||||
@NotNull PicoContainer container,
|
||||
@NotNull Class<?> componentImplementation) {
|
||||
private static @NotNull Object instantiateGuarded(@Nullable CachingConstructorInjectionComponentAdapter adapter,
|
||||
@NotNull PicoContainer container,
|
||||
@NotNull Class<?> componentImplementation) {
|
||||
Set<Class<?>> currentStack = ourGuard.get();
|
||||
if (currentStack == null) {
|
||||
currentStack = Collections.newSetFromMap(new IdentityHashMap<>(1));
|
||||
@@ -91,7 +91,7 @@ final class CachingConstructorInjectionComponentAdapter implements ComponentAdap
|
||||
return container.getComponentAdapter(expectedType);
|
||||
}
|
||||
|
||||
ComponentAdapter result = getTargetAdapter(container, expectedType, excludeAdapter.getComponentKey());
|
||||
ComponentAdapter result = container.getComponentAdapterOfType(expectedType, excludeAdapter.getComponentKey());
|
||||
return result == null ? null : expectedType.isAssignableFrom(result.getComponentImplementation()) ? result : null;
|
||||
}
|
||||
|
||||
@@ -142,8 +142,7 @@ final class CachingConstructorInjectionComponentAdapter implements ComponentAdap
|
||||
|
||||
private static @NotNull Constructor<?> getGreediestSatisfiableConstructor(@Nullable ComponentAdapter adapter,
|
||||
@NotNull DefaultPicoContainer container,
|
||||
@NotNull Class<?> componentImplementation) throws
|
||||
PicoIntrospectionException {
|
||||
@NotNull Class<?> componentImplementation) throws PicoIntrospectionException {
|
||||
Set<Constructor<?>> conflicts = new HashSet<>();
|
||||
Set<Class<?>[]> unsatisfiableDependencyTypes = new HashSet<>();
|
||||
// filter out all constructors that will definitely not match
|
||||
@@ -221,35 +220,4 @@ final class CachingConstructorInjectionComponentAdapter implements ComponentAdap
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ComponentAdapter getTargetAdapter(@NotNull DefaultPicoContainer container,
|
||||
Class<?> expectedType,
|
||||
@NotNull Object excludeKey) {
|
||||
ComponentAdapter byKey = container.getComponentAdapter(expectedType);
|
||||
if (byKey != null && !excludeKey.equals(byKey.getComponentKey())) {
|
||||
return byKey;
|
||||
}
|
||||
|
||||
List<ComponentAdapter> found = container.getComponentAdaptersOfType(expectedType);
|
||||
ComponentAdapter exclude = null;
|
||||
for (ComponentAdapter work : found) {
|
||||
if (work.getComponentKey().equals(excludeKey)) {
|
||||
exclude = work;
|
||||
}
|
||||
}
|
||||
found.remove(exclude);
|
||||
if (found.isEmpty()) {
|
||||
return container.getParent() == null ? null : container.getParent().getComponentAdapterOfType(expectedType);
|
||||
}
|
||||
else if (found.size() == 1) {
|
||||
return found.get(0);
|
||||
}
|
||||
else {
|
||||
Class<?>[] foundClasses = new Class[found.size()];
|
||||
for (int i = 0; i < foundClasses.length; i++) {
|
||||
foundClasses[i] = found.get(i).getComponentImplementation();
|
||||
}
|
||||
throw new AmbiguousComponentResolutionException(expectedType, foundClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.util.pico;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.*;
|
||||
import org.picocontainer.ComponentAdapter;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
|
||||
@@ -25,7 +23,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public final @NotNull Collection<ComponentAdapter> getComponentAdapters() {
|
||||
public final @NotNull @Unmodifiable Collection<ComponentAdapter> getComponentAdapters() {
|
||||
return componentAdapters.getImmutableSet();
|
||||
}
|
||||
|
||||
@@ -38,11 +36,6 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
public final void release() {
|
||||
componentKeyToAdapter.clear();
|
||||
componentAdapters.clear();
|
||||
}
|
||||
|
||||
private @Nullable ComponentAdapter getFromCache(@NotNull Object componentKey) {
|
||||
ComponentAdapter adapter = componentKeyToAdapter.get(componentKey);
|
||||
if (adapter != null) {
|
||||
@@ -51,20 +44,20 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
return componentKey instanceof Class ? componentKeyToAdapter.get(((Class<?>)componentKey).getName()) : null;
|
||||
}
|
||||
|
||||
public final @Nullable ComponentAdapter getComponentAdapterOfType(@NotNull Class<?> componentType) {
|
||||
final @Nullable ComponentAdapter getComponentAdapterOfType(@NotNull Class<?> componentType, @Nullable Object excludeKey) {
|
||||
// See http://jira.codehaus.org/secure/ViewIssue.jspa?key=PICO-115
|
||||
ComponentAdapter adapterByKey = getComponentAdapter(componentType);
|
||||
if (adapterByKey != null) {
|
||||
if (adapterByKey != null && (excludeKey == null || !excludeKey.equals(adapterByKey.getComponentKey()))) {
|
||||
return adapterByKey;
|
||||
}
|
||||
|
||||
List<ComponentAdapter> found = getComponentAdaptersOfType(componentType);
|
||||
List<ComponentAdapter> found = getComponentAdaptersOfType(componentType, excludeKey);
|
||||
if (found.isEmpty()) {
|
||||
return parent == null ? null : parent.getComponentAdapterOfType(componentType, excludeKey);
|
||||
}
|
||||
if (found.size() == 1) {
|
||||
return found.get(0);
|
||||
}
|
||||
if (found.isEmpty()) {
|
||||
return parent == null ? null : parent.getComponentAdapterOfType(componentType);
|
||||
}
|
||||
|
||||
Class<?>[] foundClasses = new Class[found.size()];
|
||||
for (int i = 0; i < foundClasses.length; i++) {
|
||||
@@ -73,7 +66,8 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
throw new AmbiguousComponentResolutionException(componentType, foundClasses);
|
||||
}
|
||||
|
||||
public final @NotNull List<ComponentAdapter> getComponentAdaptersOfType(@NotNull Class<?> componentType) {
|
||||
private @NotNull @Unmodifiable List<ComponentAdapter> getComponentAdaptersOfType(@NotNull Class<?> componentType,
|
||||
@Nullable Object excludeKey) {
|
||||
if (componentType == String.class) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -87,7 +81,8 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
|
||||
for (ComponentAdapter adapter : componentKeyToAdapter.values()) {
|
||||
// exclude services
|
||||
if (adapter.getComponentKey() instanceof String) {
|
||||
Object componentKey = adapter.getComponentKey();
|
||||
if (componentKey instanceof String || excludeKey != null && excludeKey.equals(componentKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -99,7 +94,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
return result;
|
||||
}
|
||||
|
||||
public final ComponentAdapter registerComponent(@NotNull ComponentAdapter componentAdapter) {
|
||||
private @NotNull ComponentAdapter registerComponent(@NotNull ComponentAdapter componentAdapter) {
|
||||
if (componentKeyToAdapter.putIfAbsent(componentAdapter.getComponentKey(), componentAdapter) != null) {
|
||||
@NotNull String message = "Key " + componentAdapter.getComponentKey() + " duplicated";
|
||||
throw new PicoException(message);
|
||||
@@ -140,7 +135,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
|
||||
@Override
|
||||
public final @Nullable Object getComponentInstanceOfType(@NotNull Class<?> componentType) {
|
||||
ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType);
|
||||
ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType, null);
|
||||
return componentAdapter == null ? null : getInstance(componentAdapter);
|
||||
}
|
||||
|
||||
@@ -165,19 +160,15 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
return registerComponent(new CachingConstructorInjectionComponentAdapter(this, componentKey, componentImplementation));
|
||||
}
|
||||
|
||||
public final DefaultPicoContainer getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* A linked hash set that's copied on write operations.
|
||||
*/
|
||||
private static final class LinkedHashSetWrapper<T> {
|
||||
private final Object lock = new Object();
|
||||
private volatile Set<T> immutableSet;
|
||||
private LinkedHashSet<T> synchronizedSet = new LinkedHashSet<>();
|
||||
private volatile @Unmodifiable Set<T> immutableSet;
|
||||
private Set<T> synchronizedSet = new LinkedHashSet<>();
|
||||
|
||||
public void add(@NotNull T element) {
|
||||
void add(@NotNull T element) {
|
||||
synchronized (lock) {
|
||||
if (!synchronizedSet.contains(element)) {
|
||||
copySyncSetIfExposedAsImmutable().add(element);
|
||||
@@ -185,7 +176,7 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedHashSet<T> copySyncSetIfExposedAsImmutable() {
|
||||
private Set<T> copySyncSetIfExposedAsImmutable() {
|
||||
if (immutableSet != null) {
|
||||
immutableSet = null;
|
||||
synchronizedSet = new LinkedHashSet<>(synchronizedSet);
|
||||
@@ -193,22 +184,13 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
return synchronizedSet;
|
||||
}
|
||||
|
||||
public void remove(@Nullable T element) {
|
||||
void remove(@Nullable T element) {
|
||||
synchronized (lock) {
|
||||
copySyncSetIfExposedAsImmutable().remove(element);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
synchronized (lock) {
|
||||
if (immutableSet != null) {
|
||||
immutableSet = null;
|
||||
}
|
||||
synchronizedSet = new LinkedHashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull Set<T> getImmutableSet() {
|
||||
@NotNull @Unmodifiable Set<T> getImmutableSet() {
|
||||
Set<T> result = immutableSet;
|
||||
if (result == null) {
|
||||
synchronized (lock) {
|
||||
@@ -232,8 +214,8 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
}
|
||||
|
||||
static final class InstanceComponentAdapter implements ComponentAdapter {
|
||||
private final Object componentKey;
|
||||
private final Object componentInstance;
|
||||
private final @NotNull Object componentKey;
|
||||
private final @NotNull Object componentInstance;
|
||||
|
||||
InstanceComponentAdapter(@NotNull Object componentKey, @NotNull Object componentInstance) {
|
||||
this.componentKey = componentKey;
|
||||
@@ -241,17 +223,17 @@ public class DefaultPicoContainer implements MutablePicoContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComponentInstance() {
|
||||
public @NotNull Object getComponentInstance() {
|
||||
return componentInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComponentKey() {
|
||||
public @NotNull Object getComponentKey() {
|
||||
return componentKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getComponentImplementation() {
|
||||
public @NotNull Class<?> getComponentImplementation() {
|
||||
return componentInstance.getClass();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
*/
|
||||
package org.picocontainer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A component adapter is responsible for providing a specific component instance. An instance of an implementation of
|
||||
* this interface is used inside a {@link PicoContainer} for every registered component or instance. Each
|
||||
@@ -24,6 +26,7 @@ public interface ComponentAdapter {
|
||||
* @return the component's key. Should either be a class type (normally an interface) or an identifier that is
|
||||
* unique (within the scope of the current PicoContainer).
|
||||
*/
|
||||
@NotNull
|
||||
Object getComponentKey();
|
||||
|
||||
/**
|
||||
@@ -32,7 +35,9 @@ public interface ComponentAdapter {
|
||||
* @return the component's implementation class. Should normally be a concrete class (ie, a class that can be
|
||||
* instantiated).
|
||||
*/
|
||||
@NotNull
|
||||
Class<?> getComponentImplementation();
|
||||
|
||||
@NotNull
|
||||
Object getComponentInstance();
|
||||
}
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ internal class ComponentManagerResolver(
|
||||
return !constructor.isAnnotationPresent(NonInjectable::class.java) && !constructor.isAnnotationPresent(Deprecated::class.java)
|
||||
}
|
||||
|
||||
override fun isInjectable(parameterType: Class<*>): Boolean = !isNotApplicableClass(parameterType)
|
||||
override fun isInjectable(parameterType: Class<*>): Boolean = isApplicableClass(parameterType)
|
||||
|
||||
override fun resolveDependency(parameterType: Class<*>, instanceClass: Class<*>, round: Int): ArgumentSupplier? {
|
||||
if (ComponentManager::class.java === parameterType) {
|
||||
|
||||
+15
-14
@@ -103,19 +103,20 @@ internal fun <T> instantiateUsingPicoContainer(aClass: Class<*>,
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isNotApplicableClass(type: Class<*>): Boolean {
|
||||
return type.isPrimitive ||
|
||||
type.isAnnotation ||
|
||||
type.isSynthetic ||
|
||||
type.isEnum ||
|
||||
type.isArray ||
|
||||
type === java.lang.String::class.java ||
|
||||
type === Class::class.java ||
|
||||
type === File::class.java ||
|
||||
type === Path::class.java ||
|
||||
java.lang.Number::class.java.isAssignableFrom(type) ||
|
||||
java.util.Collection::class.java.isAssignableFrom(type) ||
|
||||
java.util.Map::class.java.isAssignableFrom(type)
|
||||
internal fun isApplicableClass(type: Class<*>): Boolean {
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
return !type.isPrimitive &&
|
||||
!type.isAnnotation &&
|
||||
!type.isSynthetic &&
|
||||
!type.isEnum &&
|
||||
!type.isArray &&
|
||||
type !== java.lang.String::class.java &&
|
||||
type !== Class::class.java &&
|
||||
type !== File::class.java &&
|
||||
type !== Path::class.java &&
|
||||
!java.lang.Number::class.java.isAssignableFrom(type) &&
|
||||
!java.util.Collection::class.java.isAssignableFrom(type) &&
|
||||
!java.util.Map::class.java.isAssignableFrom(type)
|
||||
}
|
||||
|
||||
private fun getGreediestSatisfiableConstructor(aClass: Class<*>,
|
||||
@@ -147,7 +148,7 @@ private fun getGreediestSatisfiableConstructor(aClass: Class<*>,
|
||||
}
|
||||
|
||||
// first, perform fast check to ensure that assert about getComponentAdapterOfType is thrown only if the constructor is applicable
|
||||
if (parameterTypes.any(::isNotApplicableClass)) {
|
||||
if (!parameterTypes.all(::isApplicableClass)) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user