3 votes

Pourquoi le débogueur d'Intellij atteint deux fois le point d'arrêt pour ce code Scala

Pour le code scala suivant, lorsque je place un point de débogage au niveau de l'instruction if et que j'active "Log : Message d'atteinte du point d'arrêt"

object App1 {
  def main(args: Array[String]): Unit = {
    iftest()
  }
  def iftest(): Unit = {
    val setA: Set[String] = Set("a", "b", "c");
    var setB: Set[String] = Set("d", "e", "f")
    if(setA.size > setB.size){ //here break point at line 8
      println("bigger")
    }
  }
}

J'ai obtenu la sortie suivante dans la console. La question est de savoir pourquoi ce point d'arrêt est atteint deux fois.

Breakpoint reached at com.eguller.App1$.iftest(App1.scala:8)
Breakpoint reached at com.eguller.App1$.iftest(App1.scala:8)

Mais pour suivre un code Java similaire, le point d'arrêt n'est atteint qu'une seule fois.

        Set<String> set1 = new HashSet<>();
        set1.add("1");
        set1.add("2");

        Set<String> set2 = new HashSet<>();
        set2.add("a");
        set2.add("b");

        if(set1.size() > set2.size()){ //here break point at line 8
            System.out.println("size different");
        }

J'ai obtenu le résultat suivant

Breakpoint reached at com.eguller.JApp.main(JApp.java:8)

S'agit-il d'un bogue dans le débogueur Intellij ou d'une caractéristique du langage de programmation Scala ?

IntelliJ IDEA 2021.3 Java - 11 Scala - 2.12.15

2voto

niktrop Points 411

Il s'agit d'une particularité de la génération du bytecode scalac. Pour une raison quelconque, il génère une position supplémentaire pour le débogueur juste avant l'instruction return et le place sur cette ligne. Vous pouvez invoquer l'action "Show bytecode" dans l'IDE et voir qu'il y a 2 LINENUMBER 8 entrées :

// access flags 0x1
public iftest()V
 L0
  LINENUMBER 6 L0
  GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
  INVOKEVIRTUAL scala/Predef$.Set ()Lscala/collection/immutable/Set$;
  GETSTATIC scala/runtime/ScalaRunTime$.MODULE$ : Lscala/runtime/ScalaRunTime$;
  ICONST_3
  ANEWARRAY java/lang/String
  DUP
  ICONST_0
  LDC "a"
  AASTORE
  DUP
  ICONST_1
  LDC "b"
  AASTORE
  DUP
  ICONST_2
  LDC "c"
  AASTORE
  CHECKCAST [Ljava/lang/Object;
  INVOKEVIRTUAL scala/runtime/ScalaRunTime$.wrapRefArray ([Ljava/lang/Object;)Lscala/collection/immutable/ArraySeq;
  INVOKEVIRTUAL scala/collection/immutable/Set$.apply (Lscala/collection/immutable/Seq;)Ljava/lang/Object;
  CHECKCAST scala/collection/immutable/Set
  ASTORE 1
 L1
  LINENUMBER 7 L1
  GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
  INVOKEVIRTUAL scala/Predef$.Set ()Lscala/collection/immutable/Set$;
  GETSTATIC scala/runtime/ScalaRunTime$.MODULE$ : Lscala/runtime/ScalaRunTime$;
  ICONST_3
  ANEWARRAY java/lang/String
  DUP
  ICONST_0
  LDC "d"
  AASTORE
  DUP
  ICONST_1
  LDC "e"
  AASTORE
  DUP
  ICONST_2
  LDC "f"
  AASTORE
  CHECKCAST [Ljava/lang/Object;
  INVOKEVIRTUAL scala/runtime/ScalaRunTime$.wrapRefArray ([Ljava/lang/Object;)Lscala/collection/immutable/ArraySeq;
  INVOKEVIRTUAL scala/collection/immutable/Set$.apply (Lscala/collection/immutable/Seq;)Ljava/lang/Object;
  CHECKCAST scala/collection/immutable/Set
  ASTORE 2
 L2
  LINENUMBER 8 L2
  ALOAD 1
  INVOKEINTERFACE scala/collection/immutable/Set.size ()I (itf)
  ALOAD 2
  INVOKEINTERFACE scala/collection/immutable/Set.size ()I (itf)
  IF_ICMPLE L3
 L4
  LINENUMBER 9 L4
  GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
  LDC "bigger"
  INVOKEVIRTUAL scala/Predef$.println (Ljava/lang/Object;)V
  GOTO L3
 L3
  LINENUMBER 8 L3
 FRAME APPEND [scala/collection/immutable/Set scala/collection/immutable/Set]
  RETURN
 L5
  LOCALVARIABLE setA Lscala/collection/immutable/Set; L1 L3 1
  LOCALVARIABLE setB Lscala/collection/immutable/Set; L2 L3 2
  LOCALVARIABLE this LApp1$; L0 L5 0
  MAXSTACK = 6
  MAXLOCALS = 3

Le compilateur Scala 3 ne l'ajoute pas et les points d'arrêt fonctionnent comme prévu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X