Skip to content

Commit

Permalink
Refactor library support
Browse files Browse the repository at this point in the history
  • Loading branch information
Soarex16 committed May 26, 2023
1 parent 8330e86 commit 5e020f1
Show file tree
Hide file tree
Showing 32 changed files with 141 additions and 482 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package org.jetbrains.kotlin.idea.debugger.sequence.lib.collections

import com.intellij.debugger.streams.lib.ExpressionBasedLibrarySupport
import com.intellij.debugger.streams.lib.LibrarySupport
import com.intellij.debugger.streams.lib.LibrarySupportProvider
import com.intellij.debugger.streams.trace.TraceExpressionBuilder
Expand All @@ -16,7 +17,7 @@ import org.jetbrains.kotlin.idea.debugger.sequence.trace.impl.KotlinTraceExpress

class KotlinCollectionSupportProvider : LibrarySupportProvider {
private val builder: StreamChainBuilder = KotlinCollectionChainBuilder()
private val support: LibrarySupport by lazy { KotlinCollectionLibrarySupport() }
private val support: ExpressionBasedLibrarySupport by lazy { KotlinCollectionLibrarySupport() }
private val dsl by lazy { DslImpl(KotlinStatementFactory(KotlinCollectionsPeekCallFactory())) }

override fun getLanguageId(): String = KotlinLanguage.INSTANCE.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package org.jetbrains.kotlin.idea.debugger.sequence.lib.sequence

import com.intellij.debugger.streams.lib.ExpressionBasedLibrarySupport
import com.intellij.debugger.streams.lib.LibrarySupport
import com.intellij.debugger.streams.lib.LibrarySupportProvider
import com.intellij.debugger.streams.trace.TraceExpressionBuilder
Expand All @@ -25,7 +26,7 @@ class KotlinSequenceSupportProvider : LibrarySupportProvider {
KotlinChainTransformerImpl(SequenceTypeExtractor()),
SequenceCallCheckerWithNameHeuristics(SequenceCallChecker())
)
private val support: LibrarySupport by lazy { KotlinSequencesSupport() }
private val support: ExpressionBasedLibrarySupport by lazy { KotlinSequencesSupport() }
private val dsl: DslImpl by lazy { DslImpl(KotlinStatementFactory(KotlinCollectionsPeekCallFactory())) }

override fun getChainBuilder(): StreamChainBuilder = builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.intellij.debugger.streams.psi.impl.DebuggerPositionResolverImpl;
import com.intellij.debugger.streams.trace.*;
import com.intellij.debugger.streams.trace.breakpoint.*;
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.BreakpointTracingSupport;
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.BreakpointBasedLibrarySupport;
import com.intellij.debugger.streams.trace.impl.TraceResultInterpreterImpl;
import com.intellij.debugger.streams.ui.ChooserOption;
import com.intellij.debugger.streams.ui.impl.ElementChooserImpl;
Expand Down Expand Up @@ -151,7 +151,8 @@ private void notifyUI(@NotNull @Nls String message) {

@NotNull
private static StreamTracer getStreamTracer(@NotNull XDebugSession session, @NotNull Project project, @NotNull LibrarySupportProvider provider) {
final TraceResultInterpreter resultInterpreter = new TraceResultInterpreterImpl(provider.getLibrarySupport().getInterpreterFactory());
final var librarySupport = provider.getLibrarySupport();
final TraceResultInterpreter resultInterpreter = new TraceResultInterpreterImpl(librarySupport.getInterpreterFactory());

String tracingEngine = Registry.get(TRACING_ENGINE_REGISTRY_KEY).getSelectedOption();
if (tracingEngine == null) {
Expand All @@ -169,16 +170,17 @@ private static StreamTracer getStreamTracer(@NotNull XDebugSession session, @Not
if (currentFile == null) {
throw new DebuggerLocationNotFoundException("Cannot find current file PSI representation");
}
final BreakpointTracingSupport breakpointTracingSupport = provider.getBreakpointTracingSupport();
if (breakpointTracingSupport == null) {
LOG.warn(String.format("Breakpoint based tracing not supported for language %s. Falling back to evaluate expression tracer", provider.getLanguageId()));
final TraceExpressionBuilder expressionBuilder = provider.getExpressionBuilder(project);
yield new EvaluateExpressionTracer(session, expressionBuilder, resultInterpreter);

if (librarySupport instanceof BreakpointBasedLibrarySupport breakpointTracingSupport) {
final BreakpointResolver breakpointResolver = breakpointTracingSupport
.getBreakpointResolverFactory()
.getBreakpointResolver(currentFile);
yield new MethodBreakpointTracer(session, breakpointTracingSupport, breakpointResolver, resultInterpreter);
}
final BreakpointResolver breakpointResolver = breakpointTracingSupport
.getBreakpointResolverFactory()
.getBreakpointResolver(currentFile);
yield new MethodBreakpointTracer(session, breakpointTracingSupport, breakpointResolver, resultInterpreter);

LOG.warn(String.format("Breakpoint based tracing not supported for language %s. Falling back to evaluate expression tracer", provider.getLanguageId()));
final TraceExpressionBuilder expressionBuilder = provider.getExpressionBuilder(project);
yield new EvaluateExpressionTracer(session, expressionBuilder, resultInterpreter);
}
case EVALUATE_EXPRESSION_TRACER -> {
final TraceExpressionBuilder expressionBuilder = provider.getExpressionBuilder(project);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.streams.lib

import com.intellij.debugger.streams.trace.dsl.Dsl

interface ExpressionBasedLibrarySupport: LibrarySupport {
fun createHandlerFactory(dsl: Dsl): HandlerFactory
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// Copyright 2000-2017 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.streams.lib

import com.intellij.debugger.streams.trace.dsl.Dsl

/**
* @author Vitaliy.Bibaev
*/
interface LibrarySupport {
fun createHandlerFactory(dsl: Dsl): HandlerFactory
val interpreterFactory: InterpreterFactory
val resolverFactory: ResolverFactory
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
package com.intellij.debugger.streams.lib;

import com.intellij.debugger.streams.trace.TraceExpressionBuilder;
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.BreakpointTracingSupport;
import com.intellij.debugger.streams.wrapper.StreamChainBuilder;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

Expand All @@ -34,9 +32,4 @@ static List<LibrarySupportProvider> getList() {

@NotNull
LibrarySupport getLibrarySupport();

@Nullable
default BreakpointTracingSupport getBreakpointTracingSupport() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import com.intellij.debugger.streams.resolve.ValuesOrderResolver
import com.intellij.debugger.streams.trace.CallTraceInterpreter
import com.intellij.debugger.streams.trace.IntermediateCallHandler
import com.intellij.debugger.streams.trace.TerminatorCallHandler
import com.intellij.debugger.streams.trace.breakpoint.ValueManager
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.RuntimeIntermediateCallHandler
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.RuntimeTerminalCallHandler
import com.intellij.debugger.streams.trace.dsl.Dsl
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
import com.intellij.debugger.streams.wrapper.TerminatorStreamCall
import com.intellij.openapi.util.NlsSafe
import com.sun.jdi.ObjectReference

/**
* @author Vitaliy.Bibaev
Expand All @@ -24,8 +28,12 @@ interface Operation {

interface IntermediateOperation : Operation {
fun getTraceHandler(callOrder: Int, call: IntermediateStreamCall, dsl: Dsl): IntermediateCallHandler

fun getRuntimeTraceHandler(number: Int, call: IntermediateStreamCall, valueManager: ValueManager, time: ObjectReference): RuntimeIntermediateCallHandler? = null
}

interface TerminalOperation : Operation {
fun getTraceHandler(call: TerminatorStreamCall, resultExpression: String, dsl: Dsl): TerminatorCallHandler

fun getRuntimeTraceHandler(number: Int, call: TerminatorStreamCall, valueManager: ValueManager, time: ObjectReference): RuntimeTerminalCallHandler? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ import com.intellij.debugger.streams.resolve.ValuesOrderResolver
import com.intellij.debugger.streams.trace.CallTraceInterpreter
import com.intellij.debugger.streams.trace.IntermediateCallHandler
import com.intellij.debugger.streams.trace.TerminatorCallHandler
import com.intellij.debugger.streams.trace.breakpoint.ValueManager
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.*
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.impl.handlers.NopCallHandler
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.impl.handlers.PeekCallHandler
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.impl.handlers.PeekTerminalCallHandler
import com.intellij.debugger.streams.trace.dsl.Dsl
import com.intellij.debugger.streams.trace.impl.handler.unified.PeekTraceHandler
import com.intellij.debugger.streams.trace.impl.handler.unified.TerminatorTraceHandler
import com.intellij.debugger.streams.trace.impl.interpret.SimplePeekCallTraceInterpreter
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
import com.intellij.debugger.streams.wrapper.TerminatorStreamCall
import com.sun.jdi.ObjectReference

class DefaultLibrarySupport : LibrarySupport {
class DefaultLibrarySupport : UniversalLibrarySupport {
override fun createHandlerFactory(dsl: Dsl): HandlerFactory = object : HandlerFactory {
override fun getForIntermediate(number: Int, call: IntermediateStreamCall): IntermediateCallHandler {
return PeekTraceHandler(number, call.name, call.typeBefore, call.typeAfter, dsl)
Expand All @@ -25,6 +31,23 @@ class DefaultLibrarySupport : LibrarySupport {
}
}

override fun createRuntimeHandlerFactory(valueManager: ValueManager): RuntimeHandlerFactory = object : RuntimeHandlerFactory {
override fun getForSource(): RuntimeSourceCallHandler {
return NopCallHandler()
}

override fun getForIntermediate(number: Int, call: IntermediateStreamCall, time: ObjectReference): RuntimeIntermediateCallHandler {
return PeekCallHandler(valueManager, number, call.typeBefore, call.typeAfter, time)
}

override fun getForTermination(number: Int, call: TerminatorStreamCall, time: ObjectReference): RuntimeTerminalCallHandler {
return PeekTerminalCallHandler(valueManager, number, time, call.typeBefore, call.resultType)
}
}

override val breakpointResolverFactory: BreakpointResolverFactory
get() = TODO("Not yet implemented")

override val interpreterFactory: InterpreterFactory = object : InterpreterFactory {
override fun getInterpreter(callName: String): CallTraceInterpreter {
return SimplePeekCallTraceInterpreter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import com.intellij.debugger.streams.resolve.ValuesOrderResolver
import com.intellij.debugger.streams.trace.CallTraceInterpreter
import com.intellij.debugger.streams.trace.IntermediateCallHandler
import com.intellij.debugger.streams.trace.TerminatorCallHandler
import com.intellij.debugger.streams.trace.breakpoint.JavaBreakpointResolver
import com.intellij.debugger.streams.trace.breakpoint.ValueManager
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.*
import com.intellij.debugger.streams.trace.dsl.Dsl
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
import com.intellij.debugger.streams.wrapper.TerminatorStreamCall
import com.sun.jdi.ObjectReference

/**
* @author Vitaliy.Bibaev
*/
abstract class LibrarySupportBase(private val compatibleLibrary: LibrarySupport = LibrarySupportBase.EMPTY) : LibrarySupport {
abstract class LibrarySupportBase(private val compatibleLibrary: UniversalLibrarySupport = LibrarySupportBase.EMPTY) : UniversalLibrarySupport {
companion object {
val EMPTY: LibrarySupport = DefaultLibrarySupport()
val EMPTY: UniversalLibrarySupport = DefaultLibrarySupport()
}

private val mySupportedIntermediateOperations: MutableMap<String, IntermediateOperation> = mutableMapOf()
Expand All @@ -38,6 +42,60 @@ abstract class LibrarySupportBase(private val compatibleLibrary: LibrarySupport
}
}

override fun createRuntimeHandlerFactory(valueManager: ValueManager): RuntimeHandlerFactory {
// TODO: factory
// Terminal operations:
// void forEach(Consumer<? super T> action)
// void forEachOrdered(Consumer<? super T> action)

// Object[] toArray()
// <A> A[] toArray(IntFunction<A[]> generator)
// T reduce(T identity, BinaryOperator<T> accumulator)
// <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
// <R> R collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
// <R,A> R collect(Collector<? super T,A,R> collector)
// long count()
// default List<T> toList()

// boolean anyMatch(Predicate<? super T> predicate)
// boolean allMatch(Predicate<? super T> predicate)
// boolean noneMatch(Predicate<? super T> predicate)

// Optional<T> reduce(BinaryOperator<T> accumulator)
// Optional<T> miсn(Comparator<? super T> comparator)
// Optional<T> max(Comparator<? super T> comparator)
// Optional<T> findFirst()
// Optional<T> findAny()
//private fun getTerminationOperationFormatter(valueManager: ValueManager, evaluationContext: EvaluationContextImpl, streamCall: StreamCall): TerminationOperationTraceFormatter = when(streamCall.name) {
// "findAny", "findFirst", "min", "max", "reduce" -> OptionalTraceFormatter(valueManager, evaluationContext)
// "forEach", "forEachOrdered" -> ForEachTraceFormatter(valueManager, evaluationContext)
// "anyMatch", "allMatch", "noneMatch" -> TODO("Not implemented")
// else -> ToCollectionTraceFormatter(valueManager, evaluationContext)
//}
return object : RuntimeHandlerFactory {
val compatibleRuntimeHandlerFactory = compatibleLibrary.createRuntimeHandlerFactory(valueManager)
override fun getForSource(): RuntimeSourceCallHandler {
return compatibleRuntimeHandlerFactory.getForSource()
}

override fun getForIntermediate(number: Int, call: IntermediateStreamCall, time: ObjectReference): RuntimeIntermediateCallHandler {
val operation = mySupportedIntermediateOperations[call.name]
return operation?.getRuntimeTraceHandler(number, call, valueManager, time)
?: compatibleRuntimeHandlerFactory.getForIntermediate(number, call, time)
}

override fun getForTermination(number: Int, call: TerminatorStreamCall, time: ObjectReference): RuntimeTerminalCallHandler {
val terminalOperation = mySupportedTerminalOperations[call.name]
return terminalOperation?.getRuntimeTraceHandler(number, call, valueManager, time)
?: compatibleRuntimeHandlerFactory.getForTermination(number, call, time)
}
}
}

override val breakpointResolverFactory: BreakpointResolverFactory = BreakpointResolverFactory {
JavaBreakpointResolver(it)
}

final override val interpreterFactory: InterpreterFactory = object : InterpreterFactory {
override fun getInterpreter(callName: String): CallTraceInterpreter {
val operation = findOperationByName(callName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ import com.intellij.debugger.streams.psi.impl.JavaChainTransformerImpl
import com.intellij.debugger.streams.psi.impl.JavaStreamChainBuilder
import com.intellij.debugger.streams.psi.impl.PackageChainDetector
import com.intellij.debugger.streams.trace.TraceExpressionBuilder
import com.intellij.debugger.streams.trace.breakpoint.JavaBreakpointResolver
import com.intellij.debugger.streams.trace.breakpoint.ValueManager
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.BreakpointResolverFactory
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.BreakpointTracingSupport
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.RuntimeHandlerFactory
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.impl.DefaultRuntimeHandlerFactory
import com.intellij.debugger.streams.trace.breakpoint.new_arch.lib.UniversalLibrarySupport
import com.intellij.debugger.streams.trace.dsl.Dsl
import com.intellij.debugger.streams.trace.dsl.impl.DslImpl
import com.intellij.debugger.streams.trace.dsl.impl.java.JavaStatementFactory
Expand All @@ -27,7 +22,7 @@ internal class StandardLibrarySupportProvider : LibrarySupportProvider {
private companion object {
val builder: StreamChainBuilder = JavaStreamChainBuilder(JavaChainTransformerImpl(),
PackageChainDetector.forJavaStreams("java.util.stream"))
val support: LibrarySupport = StandardLibrarySupport()
val support: UniversalLibrarySupport = StandardLibrarySupport()
val dsl: Dsl = DslImpl(JavaStatementFactory())
}

Expand All @@ -39,14 +34,4 @@ internal class StandardLibrarySupportProvider : LibrarySupportProvider {
override fun getChainBuilder(): StreamChainBuilder = builder

override fun getLibrarySupport(): LibrarySupport = support

override fun getBreakpointTracingSupport(): BreakpointTracingSupport = object : BreakpointTracingSupport {
override fun createRuntimeHandlerFactory(valueManager: ValueManager): RuntimeHandlerFactory {
return DefaultRuntimeHandlerFactory(valueManager)
}

override val breakpointResolverFactory: BreakpointResolverFactory = BreakpointResolverFactory {
JavaBreakpointResolver(it)
}
}
}

This file was deleted.

Loading

0 comments on commit 5e020f1

Please sign in to comment.