Repository: joernio/joern
Pull request #2833 (2023-06-08 08:01:18)

dotgenerator: display Identifier in ControlStructure
Structures like `int a; if(a) { foo(); }` are actually something like `int a; if(a!=null) { foo(); }`. Hence `a` is the condition in the CFG and should be displayed even if it's just an Identifier. This PR fixes that.

See: https://discord.com/channels/832209896089976854/832214243230744626/1115821653956513884

Also: some minor clean-ups.


Patch:
diff --git a/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/queryengine/SourcesToStartingPoints.scala b/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/queryengine/SourcesToStartingPoints.scala
index aa88ddbe0..e2e855abd 100644
--- a/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/queryengine/SourcesToStartingPoints.scala
+++ b/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/queryengine/SourcesToStartingPoints.scala
@@ -9,7 +9,6 @@ import io.shiftleft.semanticcpg.language._
 import io.shiftleft.semanticcpg.language.operatorextension.allAssignmentTypes
 import io.shiftleft.semanticcpg.utils.MemberAccess.isFieldAccess
 import org.slf4j.LoggerFactory
-import overflowdb.traversal.Traversal
 
 import java.util.concurrent.{ForkJoinPool, ForkJoinTask, RecursiveTask, RejectedExecutionException}
 import scala.util.{Failure, Success, Try}
@@ -157,10 +156,11 @@ class SourceToStartingPoints(src: StoredNode) extends RecursiveTask[List[CfgNode
     val identifiers      = m.ast.isIdentifier.sortBy(x => (x.lineNumber, x.columnNumber)).l
     val identifierUsages = identifiers.nameExact(name).takeWhile(notLeftHandOfAssignment).l
     val fieldIdentifiers = m.ast.isFieldIdentifier.sortBy(x => (x.lineNumber, x.columnNumber)).l
+    val thisRefs         = Seq("this", "self") ++ m.typeDecl.name.headOption.toList
     val fieldAccessUsages = fieldIdentifiers.isFieldIdentifier
       .canonicalNameExact(name)
       .inFieldAccess
-      .where(_.argument(1).codeExact("this", "self", m.typeDecl.name.head))
+      .where(_.argument(1).codeExact(thisRefs: _*))
       .takeWhile(notLeftHandOfAssignment)
       .l
     (identifierUsages ++ fieldAccessUsages).headOption.toList
diff --git a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/TypeHelper.scala b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/TypeHelper.scala
index aeb814043..012ca8e33 100644
--- a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/TypeHelper.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/TypeHelper.scala
@@ -14,6 +14,7 @@ trait TypeHelper { this: AstCreator =>
 
   private val ArrayReplacements = Map(
     "any[]"     -> s"${Defines.Any}[]",
+    "unknown[]" -> s"${Defines.Unknown}[]",
     "number[]"  -> s"${Defines.Number}[]",
     "string[]"  -> s"${Defines.String}[]",
     "boolean[]" -> s"${Defines.Boolean}[]"
@@ -21,10 +22,12 @@ trait TypeHelper { this: AstCreator =>
 
   private val TypeReplacements = Map(
     " any"     -> s" ${Defines.Any}",
+    " unknown" -> s" ${Defines.Unknown}",
     " number"  -> s" ${Defines.Number}",
     " null"    -> s" ${Defines.Null}",
     " string"  -> s" ${Defines.String}",
     " boolean" -> s" ${Defines.Boolean}",
+    " bigint"  -> s" ${Defines.BigInt}",
     "{}"       -> Defines.Object,
     "typeof "  -> ""
   )
@@ -60,6 +63,10 @@ trait TypeHelper { this: AstCreator =>
     case TSObjectKeyword     => Defines.Object
     case TSStringKeyword     => Defines.String
     case TSSymbolKeyword     => Defines.Symbol
+    case TSUnknownKeyword    => Defines.Unknown
+    case TSVoidKeyword       => Defines.Void
+    case TSUndefinedKeyword  => Defines.Undefined
+    case TSNeverKeyword      => Defines.Never
     case TSIntrinsicKeyword  => code(tsType.json)
     case TSTypeReference     => code(tsType.json)
     case TSArrayType         => code(tsType.json)
diff --git a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/parser/BabelAst.scala b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/parser/BabelAst.scala
index 16c5c368b..bda979c24 100644
--- a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/parser/BabelAst.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/parser/BabelAst.scala
@@ -234,6 +234,7 @@ object BabelAst {
   object TSTypeAliasDeclaration          extends BabelNode
   object TSTypeAnnotation                extends FlowType
   object TSTypeAssertion                 extends BabelNode
+  object TSTypeExpression                extends TSType
   object TSTypeLiteral                   extends TSType
   object TSTypeOperator                  extends TSType
   object TSTypeParameter                 extends TSType
diff --git a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/Defines.scala b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/Defines.scala
index 441fc7de1..512c265e9 100644
--- a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/Defines.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/Defines.scala
@@ -12,8 +12,14 @@ object Defines {
   val Symbol: String            = "__ecma.Symbol"
   val Console: String           = "__whatwg.console"
   val Object: String            = "object"
+  val BigInt: String            = "bigint"
+  val Unknown: String           = "unknown"
+  val Void: String              = "void"
+  val Never: String             = "never"
+  val Undefined: String         = "undefined"
   val NodeModulesFolder: String = "node_modules"
   val GlobalNamespace: String   = NamespaceTraversal.globalNamespaceName
 
-  val JsTypes: List[String] = List(Any, Number, String, Boolean, Null, Math, Symbol, Console, Object)
+  val JsTypes: List[String] =
+    List(Any, Number, String, Boolean, Null, Math, Symbol, Console, Object, BigInt, Unknown, Never, Void, Undefined)
 }
diff --git a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/GlobalBuiltins.scala b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/GlobalBuiltins.scala
index 8b3c31910..1fe6bafa4 100644
--- a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/GlobalBuiltins.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/passes/GlobalBuiltins.scala
@@ -9,6 +9,7 @@ object GlobalBuiltins {
     "AsyncFunction",
     "AsyncGenerator",
     "AsyncGeneratorFunction",
+    "AsyncIterator",
     "Atomics",
     "BigInt",
     "BigInt64Array",
@@ -26,12 +27,23 @@ object GlobalBuiltins {
     "Generator",
     "GeneratorFunction",
     "HTMLImageElement",
+    "Iterator",
     "Infinity",
     "Int16Array",
     "Int32Array",
     "Int8Array",
     "InternalError",
     "Intl",
+    "Intl.Collator",
+    "Intl.DateTimeFormat",
+    "Intl.DisplayNames",
+    "Intl.DurationFormat",
+    "Intl.ListFormat",
+    "Intl.Locale",
+    "Intl.NumberFormat",
+    "Intl.PluralRules",
+    "Intl.RelativeTimeFormat",
+    "Intl.Segmenter",
     "JSON",
     "JSON.parse",
     "JSON.stringify",
@@ -113,12 +125,8 @@ object GlobalBuiltins {
     "WeakRef",
     "WeakSet",
     "decodeURI",
-    "decodeURI",
-    "decodeURIComponent",
     "decodeURIComponent",
     "encodeURI",
-    "encodeURI",
-    "encodeURIComponent",
     "encodeURIComponent",
     "escape",
     "eval",
@@ -126,17 +134,961 @@ object GlobalBuiltins {
     "fetch",
     "globalThis",
     "isFinite",
-    "isFinite",
-    "isNaN",
     "isNaN",
     "localStorage.setItem",
     "parseFloat",
-    "parseFloat",
-    "parseInt",
     "parseInt",
     "undefined",
     "unescape",
-    "uneval"
+    "uneval",
+    "AbortController",
+    "AbortSignal",
+    "AbsoluteOrientationSensor",
+    "AbstractRange",
+    "Accelerometer",
+    "AesCbcParams",
+    "AesCtrParams",
+    "AesGcmParams",
+    "AesKeyGenParams",
+    "AmbientLightSensor",
+    "AnalyserNode",
+    "ANGLE_instanced_arrays",
+    "Animation",
+    "AnimationEffect",
+    "AnimationEvent",
+    "AnimationPlaybackEvent",
+    "AnimationTimeline",
+    "Attr",
+    "AudioBuffer",
+    "AudioBufferSourceNode",
+    "AudioContext",
+    "AudioData",
+    "AudioDecoder",
+    "AudioDestinationNode",
+    "AudioEncoder",
+    "AudioListener",
+    "AudioNode",
+    "AudioParam",
+    "AudioParamDescriptor",
+    "AudioParamMap",
+    "AudioProcessingEvent",
+    "AudioScheduledSourceNode",
+    "AudioSinkInfo",
+    "AudioTrack",
+    "AudioTrackList",
+    "AudioWorklet",
+    "AudioWorkletGlobalScope",
+    "AudioWorkletNode",
+    "AudioWorkletProcessor",
+    "AuthenticatorAssertionResponse",
+    "AuthenticatorAttestationResponse",
+    "AuthenticatorResponse",
+    "BackgroundFetchEvent",
+    "BackgroundFetchManager",
+    "BackgroundFetchRecord",
+    "BackgroundFetchRegistration",
+    "BackgroundFetchUpdateUIEvent",
+    "BarcodeDetector",
+    "BarProp",
+    "BaseAudioContext",
+    "BatteryManager",
+    "BeforeInstallPromptEvent",
+    "BeforeUnloadEvent",
+    "BiquadFilterNode",
+    "Blob",
+    "BlobEvent",
+    "Bluetooth",
+    "BluetoothCharacteristicProperties",
+    "BluetoothDevice",
+    "BluetoothRemoteGATTCharacteristic",
+    "BluetoothRemoteGATTDescriptor",
+    "BluetoothRemoteGATTServer",
+    "BluetoothRemoteGATTService",
+    "BluetoothUUID",
+    "BroadcastChannel",
+    "ByteLengthQueuingStrategy",
+    "Cache",
+    "CacheStorage",
+    "CanMakePaymentEvent",
+    "CanvasCaptureMediaStreamTrack",
+    "CanvasGradient",
+    "CanvasPattern",
+    "CanvasRenderingContext2D",
+    "CaptureController",
+    "CaretPosition",
+    "CDATASection",
+    "ChannelMergerNode",
+    "ChannelSplitterNode",
+    "CharacterData",
+    "Client",
+    "Clients",
+    "Clipboard",
+    "ClipboardEvent",
+    "ClipboardItem",
+    "CloseEvent",
+    "Comment",
+    "CompositionEvent",
+    "CompressionStream",
+    "console",
+    "ConstantSourceNode",
+    "ContactAddress",
+    "ContactsManager",
+    "ContentIndex",
+    "ContentIndexEvent",
+    "ContentVisibilityAutoStateChangeEvent",
+    "ConvolverNode",
+    "CookieChangeEvent",
+    "CookieStore",
+    "CookieStoreManager",
+    "CountQueuingStrategy",
+    "Credential",
+    "CredentialsContainer",
+    "Crypto",
+    "CryptoKey",
+    "CryptoKeyPair",
+    "CSPViolationReportBody",
+    "CSS",
+    "CSSAnimation",
+    "CSSConditionRule",
+    "CSSContainerRule",
+    "CSSCounterStyleRule",
+    "CSSFontFaceRule",
+    "CSSFontFeatureValuesRule",
+    "CSSFontPaletteValuesRule",
+    "CSSGroupingRule",
+    "CSSImageValue",
+    "CSSImportRule",
+    "CSSKeyframeRule",
+    "CSSKeyframesRule",
+    "CSSKeywordValue",
+    "CSSLayerBlockRule",
+    "CSSLayerStatementRule",
+    "CSSMathInvert",
+    "CSSMathMax",
+    "CSSMathMin",
+    "CSSMathNegate",
+    "CSSMathProduct",
+    "CSSMathSum",
+    "CSSMathValue",
+    "CSSMatrixComponent",
+    "CSSMediaRule",
+    "CSSNamespaceRule",
+    "CSSNumericArray",
+    "CSSNumericValue",
+    "CSSPageRule",
+    "CSSPerspective",
+    "CSSPositionValue",
+    "CSSPrimitiveValue",
+    "CSSPropertyRule",
+    "CSSPseudoElement",
+    "CSSRotate",
+    "CSSRule",
+    "CSSRuleList",
+    "CSSScale",
+    "CSSSkew",
+    "CSSSkewX",
+    "CSSSkewY",
+    "CSSStyleDeclaration",
+    "CSSStyleRule",
+    "CSSStyleSheet",
+    "CSSStyleValue",
+    "CSSSupportsRule",
+    "CSSTransformComponent",
+    "CSSTransformValue",
+    "CSSTransition",
+    "CSSTranslate",
+    "CSSUnitValue",
+    "CSSUnparsedValue",
+    "CSSValue",
+    "CSSValueList",
+    "CSSVariableReferenceValue",
+    "CustomElementRegistry",
+    "CustomEvent",
+    "CustomStateSet",
+    "DataTransfer",
+    "DataTransferItem",
+    "DataTransferItemList",
+    "DecompressionStream",
+    "DedicatedWorkerGlobalScope",
+    "DelayNode",
+    "DeprecationReportBody",
+    "DeviceMotionEvent",
+    "DeviceMotionEventAcceleration",
+    "DeviceMotionEventRotationRate",
+    "DeviceOrientationEvent",
+    "DirectoryEntrySync",
+    "DirectoryReaderSync",
+    "Document",
+    "DocumentFragment",
+    "DocumentTimeline",
+    "DocumentType",
+    "DOMError",
+    "DOMException",
+    "DOMHighResTimeStamp",
+    "DOMImplementation",
+    "DOMMatrix (WebKitCSSMatrix)",
+    "DOMMatrixReadOnly",
+    "DOMParser",
+    "DOMPoint",
+    "DOMPointReadOnly",
+    "DOMQuad",
+    "DOMRect",
+    "DOMRectReadOnly",
+    "DOMStringList",
+    "DOMStringMap",
+    "DOMTokenList",
+    "DragEvent",
+    "DynamicsCompressorNode",
+    "EcdhKeyDeriveParams",
+    "EcdsaParams",
+    "EcKeyGenParams",
+    "EcKeyImportParams",
+    "Element",
+    "ElementInternals",
+    "EncodedAudioChunk",
+    "EncodedVideoChunk",
+    "ErrorEvent",
+    "Event",
+    "EventCounts",
+    "EventSource",
+    "EventTarget",
+    "ExtendableCookieChangeEvent",
+    "ExtendableEvent",
+    "ExtendableMessageEvent",
+    "EyeDropper",
+    "FeaturePolicy",
+    "FederatedCredential",
+    "FetchEvent",
+    "File",
+    "FileEntrySync",
+    "FileList",
+    "FileReader",
+    "FileReaderSync",
+    "FileSystem",
+    "FileSystemDirectoryEntry",
+    "FileSystemDirectoryHandle",
+    "FileSystemDirectoryReader",
+    "FileSystemEntry",
+    "FileSystemFileEntry",
+    "FileSystemFileHandle",
+    "FileSystemHandle",
+    "FileSystemSync",
+    "FileSystemSyncAccessHandle",
+    "FileSystemWritableFileStream",
+    "FocusEvent",
+    "FontData",
+    "FontFace",
+    "FontFaceSet",
+    "FontFaceSetLoadEvent",
+    "FormData",
+    "FormDataEvent",
+    "FragmentDirective",
+    "GainNode",
+    "Gamepad",
+    "GamepadButton",
+    "GamepadEvent",
+    "GamepadHapticActuator",
+    "GamepadPose",
+    "Geolocation",
+    "GeolocationCoordinates",
+    "GeolocationPosition",
+    "GeolocationPositionError",
+    "GestureEvent",
+    "GPU",
+    "GPUAdapter",
+    "GPUAdapterInfo",
+    "GPUBindGroup",
+    "GPUBindGroupLayout",
+    "GPUBuffer",
+    "GPUCanvasContext",
+    "GPUCommandBuffer",
+    "GPUCommandEncoder",
+    "GPUCompilationInfo",
+    "GPUCompilationMessage",
+    "GPUComputePassEncoder",
+    "GPUComputePipeline",
+    "GPUDevice",
+    "GPUDeviceLostInfo",
+    "GPUError",
+    "GPUExternalTexture",
+    "GPUInternalError",
+    "GPUOutOfMemoryError",
+    "GPUPipelineError",
+    "GPUPipelineLayout",
+    "GPUQuerySet",
+    "GPUQueue",
+    "GPURenderBundle",
+    "GPURenderBundleEncoder",
+    "GPURenderPassEncoder",
+    "GPURenderPipeline",
+    "GPUSampler",
+    "GPUShaderModule",
+    "GPUSupportedFeatures",
+    "GPUSupportedLimits",
+    "GPUTexture",
+    "GPUTextureView",
+    "GPUUncapturedErrorEvent",
+    "GPUValidationError",
+    "GravitySensor",
+    "Gyroscope",
+    "HashChangeEvent",
+    "Headers",
+    "HID",
+    "HIDConnectionEvent",
+    "HIDDevice",
+    "HIDInputReportEvent",
+    "Highlight",
+    "HighlightRegistry",
+    "History",
+    "HkdfParams",
+    "HmacImportParams",
+    "HmacKeyGenParams",
+    "HMDVRDevice",
+    "HTMLAnchorElement",
+    "HTMLAreaElement",
+    "HTMLAudioElement",
+    "HTMLBaseElement",
+    "HTMLBodyElement",
+    "HTMLBRElement",
+    "HTMLButtonElement",
+    "HTMLCanvasElement",
+    "HTMLCollection",
+    "HTMLDataElement",
+    "HTMLDataListElement",
+    "HTMLDetailsElement",
+    "HTMLDialogElement",
+    "HTMLDivElement",
+    "HTMLDListElement",
+    "HTMLDocument",
+    "HTMLElement",
+    "HTMLEmbedElement",
+    "HTMLFieldSetElement",
+    "HTMLFontElement",
+    "HTMLFormControlsCollection",
+    "HTMLFormElement",
+    "HTMLFrameSetElement",
+    "HTMLHeadElement",
+    "HTMLHeadingElement",
+    "HTMLHRElement",
+    "HTMLHtmlElement",
+    "HTMLIFrameElement",
+    "HTMLImageElement",
+    "HTMLInputElement",
+    "HTMLLabelElement",
+    "HTMLLegendElement",
+    "HTMLLIElement",
+    "HTMLLinkElement",
+    "HTMLMapElement",
+    "HTMLMarqueeElement",
+    "HTMLMediaElement",
+    "HTMLMenuElement",
+    "HTMLMenuItemElement",
+    "HTMLMetaElement",
+    "HTMLMeterElement",
+    "HTMLModElement",
+    "HTMLObjectElement",
+    "HTMLOListElement",
+    "HTMLOptGroupElement",
+    "HTMLOptionElement",
+    "HTMLOptionsCollection",
+    "HTMLOutputElement",
+    "HTMLParagraphElement",
+    "HTMLParamElement",
+    "HTMLPictureElement",
+    "HTMLPreElement",
+    "HTMLProgressElement",
+    "HTMLQuoteElement",
+    "HTMLScriptElement",
+    "HTMLSelectElement",
+    "HTMLSlotElement",
+    "HTMLSourceElement",
+    "HTMLSpanElement",
+    "HTMLStyleElement",
+    "HTMLTableCaptionElement",
+    "HTMLTableCellElement",
+    "HTMLTableColElement",
+    "HTMLTableElement",
+    "HTMLTableRowElement",
+    "HTMLTableSectionElement",
+    "HTMLTemplateElement",
+    "HTMLTextAreaElement",
+    "HTMLTimeElement",
+    "HTMLTitleElement",
+    "HTMLTrackElement",
+    "HTMLUListElement",
+    "HTMLUnknownElement",
+    "HTMLVideoElement",
+    "IDBCursor",
+    "IDBCursorWithValue",
+    "IDBDatabase",
+    "IDBFactory",
+    "IDBIndex",
+    "IDBKeyRange",
+    "IDBLocaleAwareKeyRange",
+    "IDBObjectStore",
+    "IDBOpenDBRequest",
+    "IDBRequest",
+    "IDBTransaction",
+    "IDBVersionChangeEvent",
+    "IdentityCredential",
+    "IdleDeadline",
+    "IdleDetector",
+    "IIRFilterNode",
+    "ImageBitmap",
+    "ImageBitmapRenderingContext",
+    "ImageCapture",
+    "ImageData",
+    "ImageDecoder",
+    "ImageTrack",
+    "ImageTrackList",
+    "Ink",
+    "InkPresenter",
+    "InputDeviceCapabilities",
+    "InputDeviceInfo",
+    "InputEvent",
+    "InstallEvent",
+    "IntersectionObserver",
+    "IntersectionObserverEntry",
+    "InterventionReportBody",
+    "Keyboard",
+    "KeyboardEvent",
+    "KeyboardLayoutMap",
+    "KeyframeEffect",
+    "LargestContentfulPaint",
+    "LaunchParams",
+    "LaunchQueue",
+    "LayoutShift",
+    "LayoutShiftAttribution",
+    "LinearAccelerationSensor",
+    "Location",
+    "Lock",
+    "LockManager",
+    "Magnetometer",
+    "MathMLElement",
+    "MediaCapabilities",
+    "MediaDeviceInfo",
+    "MediaDevices",
+    "MediaElementAudioSourceNode",
+    "MediaEncryptedEvent",
+    "MediaError",
+    "MediaImage",
+    "MediaKeyMessageEvent",
+    "MediaKeys",
+    "MediaKeySession",
+    "MediaKeyStatusMap",
+    "MediaKeySystemAccess",
+    "MediaList",
+    "MediaMetadata",
+    "MediaQueryList",
+    "MediaQueryListEvent",
+    "MediaRecorder",
+    "MediaRecorderErrorEvent",
+    "MediaSession",
+    "MediaSource",
+    "MediaSourceHandle",
+    "MediaStream",
+    "MediaStreamAudioDestinationNode",
+    "MediaStreamAudioSourceNode",
+    "MediaStreamEvent",
+    "MediaStreamTrack",
+    "MediaStreamTrackAudioSourceNode",
+    "MediaStreamTrackEvent",
+    "MediaStreamTrackGenerator",
+    "MediaStreamTrackProcessor",
+    "MediaTrackConstraints",
+    "MediaTrackSettings",
+    "MediaTrackSupportedConstraints",
+    "MerchantValidationEvent",
+    "MessageChannel",
+    "MessageEvent",
+    "MessagePort",
+    "Metadata",
+    "MIDIAccess",
+    "MIDIConnectionEvent",
+    "MIDIInput",
+    "MIDIInputMap",
+    "MIDIMessageEvent",
+    "MIDIOutput",
+    "MIDIOutputMap",
+    "MIDIPort",
+    "MimeType",
+    "MimeTypeArray",
+    "MouseEvent",
+    "MouseScrollEvent",
+    "MutationEvent",
+    "MutationObserver",
+    "MutationRecord",
+    "NamedNodeMap",
+    "NavigateEvent",
+    "Navigation",
+    "NavigationCurrentEntryChangeEvent",
+    "NavigationDestination",
+    "NavigationHistoryEntry",
+    "NavigationPreloadManager",
+    "NavigationTransition",
+    "Navigator",
+    "NavigatorUAData",
+    "NDEFMessage",
+    "NDEFReader",
+    "NDEFReadingEvent",
+    "NDEFRecord",
+    "NetworkInformation",
+    "Node",
+    "NodeIterator",
+    "NodeList",
+    "Notification",
+    "NotificationEvent",
+    "NotifyAudioAvailableEvent",
+    "OES_draw_buffers_indexed",
+    "OfflineAudioCompletionEvent",
+    "OfflineAudioContext",
+    "OffscreenCanvas",
+    "OffscreenCanvasRenderingContext2D",
+    "OrientationSensor",
+    "OscillatorNode",
+    "OTPCredential",
+    "OverconstrainedError",
+    "PageTransitionEvent",
+    "PaintWorkletGlobalScope",
+    "PannerNode",
+    "PasswordCredential",
+    "Path2D",
+    "PaymentAddress",
+    "PaymentManager",
+    "PaymentMethodChangeEvent",
+    "PaymentRequest",
+    "PaymentRequestEvent",
+    "PaymentRequestUpdateEvent",
+    "PaymentResponse",
+    "Pbkdf2Params",
+    "Performance",
+    "PerformanceElementTiming",
+    "PerformanceEntry",
+    "PerformanceEventTiming",
+    "PerformanceLongTaskTiming",
+    "PerformanceMark",
+    "PerformanceMeasure",
+    "PerformanceNavigation",
+    "PerformanceNavigationTiming",
+    "PerformanceObserver",
+    "PerformanceObserverEntryList",
+    "PerformancePaintTiming",
+    "PerformanceResourceTiming",
+    "PerformanceServerTiming",
+    "PerformanceTiming",
+    "PeriodicSyncEvent",
+    "PeriodicSyncManager",
+    "PeriodicWave",
+    "Permissions",
+    "PermissionStatus",
+    "PictureInPictureEvent",
+    "PictureInPictureWindow",
+    "Plugin",
+    "PluginArray",
+    "Point",
+    "PointerEvent",
+    "PopStateEvent",
+    "PositionSensorVRDevice",
+    "Presentation",
+    "PresentationAvailability",
+    "PresentationConnection",
+    "PresentationConnectionAvailableEvent",
+    "PresentationConnectionCloseEvent",
+    "PresentationConnectionList",
+    "PresentationReceiver",
+    "PresentationRequest",
+    "ProcessingInstruction",
+    "ProgressEvent",
+    "PromiseRejectionEvent",
+    "PublicKeyCredential",
+    "PushEvent",
+    "PushManager",
+    "PushMessageData",
+    "PushSubscription",
+    "PushSubscriptionOptions",
+    "RadioNodeList",
+    "Range",
+    "ReadableByteStreamController",
+    "ReadableStream",
+    "ReadableStreamBYOBReader",
+    "ReadableStreamBYOBRequest",
+    "ReadableStreamDefaultController",
+    "ReadableStreamDefaultReader",
+    "RelativeOrientationSensor",
+    "RemotePlayback",
+    "Report",
+    "ReportBody",
+    "ReportingObserver",
+    "Request",
+    "ResizeObserver",
+    "ResizeObserverEntry",
+    "ResizeObserverSize",
+    "Response",
+    "RsaHashedImportParams",
+    "RsaHashedKeyGenParams",
+    "RsaOaepParams",
+    "RsaPssParams",
+    "RTCAudioSourceStats",
+    "RTCCertificate",
+    "RTCDataChannel",
+    "RTCDataChannelEvent",
+    "RTCDtlsTransport",
+    "RTCDTMFSender",
+    "RTCDTMFToneChangeEvent",
+    "RTCError",
+    "RTCErrorEvent",
+    "RTCIceCandidate",
+    "RTCIceCandidatePair",
+    "RTCIceCandidatePairStats",
+    "RTCIceCandidateStats",
+    "RTCIceParameters",
+    "RTCIceServer",
+    "RTCIceTransport",
+    "RTCIdentityAssertion",
+    "RTCInboundRtpStreamStats",
+    "RTCOutboundRtpStreamStats",
+    "RTCPeerConnection",
+    "RTCPeerConnectionIceErrorEvent",
+    "RTCPeerConnectionIceEvent",
+    "RTCPeerConnectionStats",
+    "RTCRemoteOutboundRtpStreamStats",
+    "RTCRtpCodecParameters",
+    "RTCRtpContributingSource",
+    "RTCRtpEncodingParameters",
+    "RTCRtpReceiver",
+    "RTCRtpSender",
+    "RTCRtpStreamStats",
+    "RTCRtpTransceiver",
+    "RTCSctpTransport",
+    "RTCSessionDescription",
+    "RTCStatsReport",
+    "RTCTrackEvent",
+    "Sanitizer",
+    "Scheduler",
+    "Screen",
+    "ScreenOrientation",
+    "ScriptProcessorNode",
+    "SecurityPolicyViolationEvent",
+    "Selection",
+    "Sensor",
+    "SensorErrorEvent",
+    "Serial",
+    "SerialPort",
+    "ServiceWorker",
+    "ServiceWorkerContainer",
+    "ServiceWorkerGlobalScope",
+    "ServiceWorkerRegistration",
+    "ShadowRoot",
+    "SharedWorker",
+    "SharedWorkerGlobalScope",
+    "SourceBuffer",
+    "SourceBufferList",
+    "SpeechGrammar",
+    "SpeechGrammarList",
+    "SpeechRecognition",
+    "SpeechRecognitionAlternative",
+    "SpeechRecognitionErrorEvent",
+    "SpeechRecognitionEvent",
+    "SpeechRecognitionResult",
+    "SpeechRecognitionResultList",
+    "SpeechSynthesis",
+    "SpeechSynthesisErrorEvent",
+    "SpeechSynthesisEvent",
+    "SpeechSynthesisUtterance",
+    "SpeechSynthesisVoice",
+    "StaticRange",
+    "StereoPannerNode",
+    "Storage",
+    "StorageEvent",
+    "StorageManager",
+    "StylePropertyMap",
+    "StylePropertyMapReadOnly",
+    "StyleSheet",
+    "StyleSheetList",
+    "SubmitEvent",
+    "SubtleCrypto",
+    "SVGAElement",
+    "SVGAngle",
+    "SVGAnimateColorElement",
+    "SVGAnimatedAngle",
+    "SVGAnimatedBoolean",
+    "SVGAnimatedEnumeration",
+    "SVGAnimatedInteger",
+    "SVGAnimatedLength",
+    "SVGAnimatedLengthList",
+    "SVGAnimatedNumber",
+    "SVGAnimatedNumberList",
+    "SVGAnimatedPreserveAspectRatio",
+    "SVGAnimatedRect",
+    "SVGAnimatedString",
+    "SVGAnimatedTransformList",
+    "SVGAnimateElement",
+    "SVGAnimateMotionElement",
+    "SVGAnimateTransformElement",
+    "SVGAnimationElement",
+    "SVGCircleElement",
+    "SVGClipPathElement",
+    "SVGComponentTransferFunctionElement",
+    "SVGCursorElement",
+    "SVGDefsElement",
+    "SVGDescElement",
+    "SVGElement",
+    "SVGEllipseElement",
+    "SVGEvent",
+    "SVGFEBlendElement",
+    "SVGFEColorMatrixElement",
+    "SVGFEComponentTransferElement",
+    "SVGFECompositeElement",
+    "SVGFEConvolveMatrixElement",
+    "SVGFEDiffuseLightingElement",
+    "SVGFEDisplacementMapElement",
+    "SVGFEDistantLightElement",
+    "SVGFEDropShadowElement",
+    "SVGFEFloodElement",
+    "SVGFEFuncAElement",
+    "SVGFEFuncBElement",
+    "SVGFEFuncGElement",
+    "SVGFEFuncRElement",
+    "SVGFEGaussianBlurElement",
+    "SVGFEImageElement",
+    "SVGFEMergeElement",
+    "SVGFEMergeNodeElement",
+    "SVGFEMorphologyElement",
+    "SVGFEOffsetElement",
+    "SVGFEPointLightElement",
+    "SVGFESpecularLightingElement",
+    "SVGFESpotLightElement",
+    "SVGFETileElement",
+    "SVGFETurbulenceElement",
+    "SVGFilterElement",
+    "SVGFontElement",
+    "SVGFontFaceElement",
+    "SVGFontFaceFormatElement",
+    "SVGFontFaceNameElement",
+    "SVGFontFaceSrcElement",
+    "SVGFontFaceUriElement",
+    "SVGForeignObjectElement",
+    "SVGGElement",
+    "SVGGeometryElement",
+    "SVGGlyphElement",
+    "SVGGlyphRefElement",
+    "SVGGradientElement",
+    "SVGGraphicsElement",
+    "SVGHKernElement",
+    "SVGImageElement",
+    "SVGLength",
+    "SVGLengthList",
+    "SVGLinearGradientElement",
+    "SVGLineElement",
+    "SVGMarkerElement",
+    "SVGMaskElement",
+    "SVGMetadataElement",
+    "SVGMissingGlyphElement",
+    "SVGMPathElement",
+    "SVGNumber",
+    "SVGNumberList",
+    "SVGPathElement",
+    "SVGPatternElement",
+    "SVGPoint",
+    "SVGPointList",
+    "SVGPolygonElement",
+    "SVGPolylineElement",
+    "SVGPreserveAspectRatio",
+    "SVGRadialGradientElement",
+    "SVGRect",
+    "SVGRectElement",
+    "SVGRenderingIntent",
+    "SVGScriptElement",
+    "SVGSetElement",
+    "SVGStopElement",
+    "SVGStringList",
+    "SVGStyleElement",
+    "SVGSVGElement",
+    "SVGSwitchElement",
+    "SVGSymbolElement",
+    "SVGTextContentElement",
+    "SVGTextElement",
+    "SVGTextPathElement",
+    "SVGTextPositioningElement",
+    "SVGTitleElement",
+    "SVGTransform",
+    "SVGTransformList",
+    "SVGTRefElement",
+    "SVGTSpanElement",
+    "SVGUnitTypes",
+    "SVGUseElement",
+    "SVGViewElement",
+    "SVGVKernElement",
+    "SyncEvent",
+    "SyncManager",
+    "TaskAttributionTiming",
+    "TaskController",
+    "TaskPriorityChangeEvent",
+    "TaskSignal",
+    "Text",
+    "TextDecoder",
+    "TextDecoderStream",
+    "TextEncoder",
+    "TextEncoderStream",
+    "TextMetrics",
+    "TextTrack",
+    "TextTrackCue",
+    "TextTrackCueList",
+    "TextTrackList",
+    "TimeEvent",
+    "TimeRanges",
+    "ToggleEvent",
+    "Touch",
+    "TouchEvent",
+    "TouchList",
+    "TrackEvent",
+    "TransformStream",
+    "TransformStreamDefaultController",
+    "TransitionEvent",
+    "TreeWalker",
+    "TrustedHTML",
+    "TrustedScript",
+    "TrustedScriptURL",
+    "TrustedTypePolicy",
+    "TrustedTypePolicyFactory",
+    "UIEvent",
+    "URL",
+    "URLPattern",
+    "URLSearchParams",
+    "USB",
+    "USBAlternateInterface",
+    "USBConfiguration",
+    "USBConnectionEvent",
+    "USBDevice",
+    "USBEndpoint",
+    "USBInterface",
+    "USBInTransferResult",
+    "USBIsochronousInTransferPacket",
+    "USBIsochronousInTransferResult",
+    "USBIsochronousOutTransferPacket",
+    "USBIsochronousOutTransferResult",
+    "USBOutTransferResult",
+    "UserActivation",
+    "ValidityState",
+    "VideoColorSpace",
+    "VideoDecoder",
+    "VideoEncoder",
+    "VideoFrame",
+    "VideoPlaybackQuality",
+    "VideoTrack",
+    "VideoTrackList",
+    "ViewTransition",
+    "VirtualKeyboard",
+    "VisualViewport",
+    "VRDisplay",
+    "VRDisplayCapabilities",
+    "VRDisplayEvent",
+    "VREyeParameters",
+    "VRFieldOfView",
+    "VRFrameData",
+    "VRLayerInit",
+    "VRPose",
+    "VRStageParameters",
+    "VTTCue",
+    "VTTRegion",
+    "WakeLock",
+    "WakeLockSentinel",
+    "WaveShaperNode",
+    "WebGL2RenderingContext",
+    "WebGLActiveInfo",
+    "WebGLBuffer",
+    "WebGLContextEvent",
+    "WebGLFramebuffer",
+    "WebGLObject",
+    "WebGLProgram",
+    "WebGLQuery",
+    "WebGLRenderbuffer",
+    "WebGLRenderingContext",
+    "WebGLSampler",
+    "WebGLShader",
+    "WebGLShaderPrecisionFormat",
+    "WebGLSync",
+    "WebGLTexture",
+    "WebGLTransformFeedback",
+    "WebGLUniformLocation",
+    "WebGLVertexArrayObject",
+    "WebSocket",
+    "WebTransport",
+    "WebTransportBidirectionalStream",
+    "WebTransportDatagramDuplexStream",
+    "WebTransportError",
+    "WebTransportReceiveStream",
+    "WheelEvent",
+    "Window",
+    "WindowClient",
+    "WindowControlsOverlay",
+    "WindowControlsOverlayGeometryChangeEvent",
+    "Worker",
+    "WorkerGlobalScope",
+    "WorkerLocation",
+    "WorkerNavigator",
+    "Worklet",
+    "WorkletGlobalScope",
+    "WritableStream",
+    "WritableStreamDefaultController",
+    "WritableStreamDefaultWriter",
+    "XMLDocument",
+    "XMLHttpRequest",
+    "XMLHttpRequestEventTarget",
+    "XMLHttpRequestUpload",
+    "XMLSerializer",
+    "XPathEvaluator",
+    "XPathException",
+    "XPathExpression",
+    "XPathNSResolver",
+    "XPathResult",
+    "XRAnchor",
+    "XRAnchorSet",
+    "XRBoundedReferenceSpace",
+    "XRCompositionLayer",
+    "XRCPUDepthInformation",
+    "XRCubeLayer",
+    "XRCylinderLayer",
+    "XRDepthInformation",
+    "XREquirectLayer",
+    "XRFrame",
+    "XRHand",
+    "XRHitTestResult",
+    "XRHitTestSource",
+    "XRInputSource",
+    "XRInputSourceArray",
+    "XRInputSourceEvent",
+    "XRInputSourcesChangeEvent",
+    "XRJointPose",
+    "XRJointSpace",
+    "XRLayer",
+    "XRLayerEvent",
+    "XRLightEstimate",
+    "XRLightProbe",
+    "XRMediaBinding",
+    "XRPose",
+    "XRProjectionLayer",
+    "XRQuadLayer",
+    "XRRay",
+    "XRReferenceSpace",
+    "XRReferenceSpaceEvent",
+    "XRRenderState",
+    "XRRigidTransform",
+    "XRSession",
+    "XRSessionEvent",
+    "XRSpace",
+    "XRSubImage",
+    "XRSystem",
+    "XRTransientInputHitTestResult",
+    "XRTransientInputHitTestSource",
+    "XRView",
+    "XRViewerPose",
+    "XRViewport",
+    "XRWebGLBinding",
+    "XRWebGLDepthInformation",
+    "XRWebGLLayer",
+    "XRWebGLSubImage",
+    "XSLTProcessor"
   )
 
 }
diff --git a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/utils/AstGenRunner.scala b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/utils/AstGenRunner.scala
index debe70a01..dfcf2ee62 100644
--- a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/utils/AstGenRunner.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/utils/AstGenRunner.scala
@@ -28,7 +28,14 @@ object AstGenRunner {
   private val MinifiedPathRegex: Regex = ".*([.-]min\\..*js|bundle\\.js)".r
 
   private val IgnoredTestsRegex: Seq[Regex] =
-    List(".*[.-]spec\\.js".r, ".*[.-]mock\\.js".r, ".*[.-]e2e\\.js".r, ".*[.-]test\\.js".r)
+    List(
+      ".*[.-]spec\\.js".r,
+      ".*[.-]mock\\.js".r,
+      ".*[.-]e2e\\.js".r,
+      ".*[.-]test\\.js".r,
+      ".*cypress\\.json".r,
+      ".*test.*\\.json".r
+    )
 
   private val IgnoredFilesRegex: Seq[Regex] = List(
     ".*jest\\.config.*".r,
@@ -45,7 +52,10 @@ object AstGenRunner {
     ".*rollup\\.config.*".r,
     ".*\\.types\\.js".r,
     ".*\\.cjs\\.js".r,
-    ".*eslint-local-rules\\.js".r
+    ".*eslint-local-rules\\.js".r,
+    ".*\\.devcontainer\\.json".r,
+    ".*Gruntfile\\.js".r,
+    ".*i18n.*\\.json".r
   )
 
   case class AstGenRunnerResult(
diff --git a/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/DendenciesFromRequirementsTxtPass.scala b/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/DependenciesFromRequirementsTxtPass.scala
similarity index 91%
rename from joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/DendenciesFromRequirementsTxtPass.scala
rename to joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/DependenciesFromRequirementsTxtPass.scala
index bedd88131..67ab741a5 100644
--- a/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/DendenciesFromRequirementsTxtPass.scala
+++ b/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/DependenciesFromRequirementsTxtPass.scala
@@ -20,8 +20,8 @@ MarkupSafe==1.1.1
 Werkzeug==1.0.1
 ```
  */
-class DendenciesFromRequirementsTxtPass(cpg: Cpg) extends CpgPass(cpg) {
-  private val logger: Logger = LoggerFactory.getLogger(classOf[DendenciesFromRequirementsTxtPass])
+class DependenciesFromRequirementsTxtPass(cpg: Cpg) extends CpgPass(cpg) {
+  private val logger: Logger = LoggerFactory.getLogger(classOf[DependenciesFromRequirementsTxtPass])
   override def run(dstGraph: DiffGraphBuilder): Unit = {
     cpg.configFile.filter(_.name.endsWith("requirements.txt")).foreach { node =>
       val lines = node.content.split("\n")
diff --git a/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/Py2Cpg.scala b/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/Py2Cpg.scala
index 285b8f931..e5fd52220 100644
--- a/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/Py2Cpg.scala
+++ b/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/Py2Cpg.scala
@@ -45,6 +45,6 @@ class Py2Cpg(
     BatchedUpdate.applyDiff(outputCpg.graph, diffGraph)
     new CodeToCpg(outputCpg, inputProviders).createAndApply()
     new ConfigPass(outputCpg, configInputProviders).createAndApply()
-    new DendenciesFromRequirementsTxtPass(outputCpg).createAndApply()
+    new DependenciesFromRequirementsTxtPass(outputCpg).createAndApply()
   }
 }
diff --git a/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/PythonTypeRecovery.scala b/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/PythonTypeRecovery.scala
index 3cb9f22d6..1b3032c0e 100644
--- a/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/PythonTypeRecovery.scala
+++ b/joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/PythonTypeRecovery.scala
@@ -322,9 +322,10 @@ private class RecoverForPythonFile(cpg: Cpg, cu: File, builder: DiffGraphBuilder
   }
 
   override protected def visitIdentifierAssignedToTypeRef(i: Identifier, t: TypeRef, rec: Option[String]): Set[String] =
-    t.typ.referencedTypeDecl.astSiblings
-      .collectFirst { case td: TypeDecl => td }
-      .map(td => symbolTable.append(CallAlias(i.name, rec), Set(td.fullName)))
+    t.typ.referencedTypeDecl
+      .map(_.fullName.stripSuffix("<meta>"))
+      .map(td => symbolTable.append(CallAlias(i.name, rec), Set(td)))
+      .headOption
       .getOrElse(super.visitIdentifierAssignedToTypeRef(i, t, rec))
 
 }
diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/java/io/joern/rubysrc2cpg/parser/RubyLexerBase.java b/joern-cli/frontends/rubysrc2cpg/src/main/java/io/joern/rubysrc2cpg/parser/RubyLexerBase.java
deleted file mode 100644
index a778303c4..000000000
--- a/joern-cli/frontends/rubysrc2cpg/src/main/java/io/joern/rubysrc2cpg/parser/RubyLexerBase.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package io.joern.rubysrc2cpg.parser;
-
-import org.antlr.v4.runtime.CharStream;
-import org.antlr.v4.runtime.Lexer;
-import org.antlr.v4.runtime.Token;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-/** Aggregates auxiliary features to RubyLexer in a single place. */
-public abstract class RubyLexerBase extends Lexer {
-    protected RubyLexerBase(CharStream input) {
-        super(input);
-    }
-
-    /* When encountering '/', we need to decide whether this is a binary operator (e.g. `x / y`) or
-     * a regular expression delimiter (e.g. `/(eu|us)/`) occurrence. Our approach is to look at the
-     * previously emitted token and decide accordingly.
-     */
-    private final Set<Integer> regexTogglingTokens = new HashSet<>(Arrays.asList(
-            // When '/' is the first token in the stream.
-            null,
-            
-            // When '/' occurs after an opening parenthesis, brace or bracket.
-            RubyLexer.LPAREN,
-            RubyLexer.LCURLY,
-            RubyLexer.LBRACK,
-            
-            // When '/' occurs after a NL.
-            RubyLexer.NL,
-            
-            // When '/' occurs after an operator.
-            RubyLexer.EMARK,
-            RubyLexer.EMARKEQ,
-            RubyLexer.EMARKTILDE,
-            RubyLexer.AMP,
-            RubyLexer.AMP2,
-            RubyLexer.AMPDOT,
-            RubyLexer.BAR,
-            RubyLexer.BAR2,
-            RubyLexer.EQ,
-            RubyLexer.EQ2,
-            RubyLexer.EQ3,
-            RubyLexer.CARET,
-            RubyLexer.LTEQGT,
-            RubyLexer.EQTILDE,
-            RubyLexer.GT,
-            RubyLexer.GTEQ,
-            RubyLexer.LT,
-            RubyLexer.LTEQ,
-            RubyLexer.LT2,
-            RubyLexer.GT2,
-            RubyLexer.PLUS,
-            RubyLexer.MINUS,
-            RubyLexer.STAR,
-            RubyLexer.STAR2,
-            RubyLexer.SLASH,
-            RubyLexer.PERCENT,
-            RubyLexer.TILDE,
-            RubyLexer.PLUSAT,
-            RubyLexer.MINUSAT,
-            RubyLexer.ASSIGNMENT_OPERATOR
-    ));
-
-    /** The previously (non-WS) emitted token (in DEFAULT_CHANNEL.) */
-    private Token previousNonWsToken = null;
-
-    // Same original behaviour, just updating `previousNonWsToken`.
-    @Override
-    public Token nextToken() {
-        Token token = super.nextToken();
-        if (token.getChannel() == Token.DEFAULT_CHANNEL && token.getType() != RubyLexer.WS){
-            previousNonWsToken = token;
-        }
-        return token;
-    }
-
-    /** To be invoked when encountering `/`, deciding if it should emit a
-     * `REGULAR_EXPRESSION_START` token. */
-    protected boolean isStartOfRegex(){
-        Integer previousNonWsTokenType = previousNonWsToken == null ? null : previousNonWsToken.getType();
-        return regexTogglingTokens.contains(previousNonWsTokenType);
-    }
-
-    /** To be invoked when in `DEFAULT_MODE`, to check if we are in the context of a string interpolation. */
-    protected boolean isInStringInterpolationMode() {
-        return _modeStack.size() > 1 && _modeStack.peek() == RubyLexer.DOUBLE_QUOTED_STRING_MODE;
-    }
-
-    /** To be invoked when in `DEFAULT_MODE`, to check if we are in the context of a regular expression interpolation. */
-    protected boolean isInRegularExpressionInterpolationMode() {
-        return _modeStack.size() > 1 && _modeStack.peek() == RubyLexer.REGULAR_EXPRESSION_MODE;
-    }
-
-}
diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala
index 9dcae0aea..e77a73c12 100644
--- a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala
+++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala
@@ -106,6 +106,7 @@ class AstCreator(filename: String, global: Global)
     val none            = "<operator>.none"
     val patternMatch    = "<operator>.patternMatch"
     val notPatternMatch = "<operator>.notPatternMatch"
+    val scopeResolution = "<operator>.scopeResolution"
   }
   private def getOperatorName(token: Token): String = token.getType match {
     case AMP                 => Operators.logicalAnd
@@ -138,6 +139,7 @@ class AstCreator(filename: String, global: Global)
     case TILDE               => Operators.not
     case NOT                 => Operators.not
     case STAR2               => Operators.exponentiation
+    case COLON2              => RubyOperators.scopeResolution
     case _                   => RubyOperators.none
   }
 
@@ -204,8 +206,21 @@ class AstCreator(filename: String, global: Global)
         .columnNumber(localVar.getSymbol.getCharPositionInLine())
       Seq(callAst(callNode, xAsts ++ Seq(yAst)))
     case ctx: ScopedConstantAccessSingleLeftHandSideContext =>
-      // TODO to be implemented
-      Seq(Ast())
+      val localVar  = ctx.CONSTANT_IDENTIFIER()
+      val varSymbol = localVar.getSymbol()
+      val node = createIdentifierWithScope(ctx, varSymbol.getText, varSymbol.getText, Defines.Any, List(Defines.Any))
+      val constAst     = Ast(node)
+      val operatorName = getOperatorName(ctx.COLON2().getSymbol)
+      val callNode = NewCall()
+        .name(operatorName)
+        .code(ctx.getText)
+        .methodFullName(operatorName)
+        .signature("")
+        .dispatchType(DispatchTypes.STATIC_DISPATCH)
+        .typeFullName(Defines.Any)
+        .lineNumber(ctx.COLON2().getSymbol().getLine())
+        .columnNumber(ctx.COLON2().getSymbol().getCharPositionInLine())
+      Seq(callAst(callNode, Seq(constAst)))
     case _ =>
       logger.error("astForSingleLeftHandSideContext() All contexts mismatched.")
       Seq(Ast())
@@ -746,10 +761,11 @@ class AstCreator(filename: String, global: Global)
     val node     = createIdentifierWithScope(ctx, varSymbol.getText, varSymbol.getText, Defines.Any, List(Defines.Any))
     val constAst = Ast(node)
 
+    val operatorName = getOperatorName(ctx.COLON2().getSymbol)
     val callNode = NewCall()
-      .name(ctx.COLON2().getText)
-      .code(ctx.COLON2().getText)
-      .methodFullName(MethodFullNames.OperatorPrefix + ctx.COLON2().getText)
+      .name(operatorName)
+      .code(ctx.getText)
+      .methodFullName(operatorName)
       .signature("")
       .dispatchType(DispatchTypes.STATIC_DISPATCH)
       .typeFullName(Defines.Any)
@@ -1369,9 +1385,52 @@ class AstCreator(filename: String, global: Global)
       .toSeq
   }
 
+  def astForRescueClauseContext(ctx: RescueClauseContext): Ast = {
+    val asts = ListBuffer[Ast]()
+
+    if (ctx.exceptionClass() != null) {
+      val exceptionClass = ctx.exceptionClass()
+
+      if (exceptionClass.expression() != null) {
+        asts.addAll(astForExpressionContext(exceptionClass.expression()))
+      } else {
+        asts.addAll(astForMultipleRightHandSideContext(exceptionClass.multipleRightHandSide()))
+      }
+    }
+
+    if (ctx.exceptionVariableAssignment() != null) {
+      asts.addAll(astForSingleLeftHandSideContext(ctx.exceptionVariableAssignment().singleLeftHandSide()))
+    }
+
+    asts.addAll(astForThenClauseContext(ctx.thenClause()))
+    val blockNode = NewBlock()
+      .code(ctx.getText)
+      .lineNumber(ctx.RESCUE().getSymbol.getLine)
+      .columnNumber(ctx.RESCUE().getSymbol.getCharPositionInLine)
+    blockAst(blockNode, asts.toList)
+  }
+
   def astForBodyStatementContext(ctx: BodyStatementContext): Seq[Ast] = {
-    astForStatementsContext(ctx.compoundStatement().statements())
-    // TODO rescue else and ensure to be implemented
+    val compoundStatementAsts = astForStatementsContext(ctx.compoundStatement().statements())
+    val mainBodyAsts = if (ctx.ensureClause() != null) {
+      val ensureAsts = astForStatementsContext(ctx.ensureClause().compoundStatement().statements())
+      compoundStatementAsts ++ ensureAsts
+    } else {
+      compoundStatementAsts
+    }
+
+    val rescueAsts = ctx
+      .rescueClause()
+      .asScala
+      .map(astForRescueClauseContext(_))
+      .toSeq
+
+    if (ctx.elseClause() != null) {
+      val elseClauseAsts = astForElseClauseContext(ctx.elseClause())
+      mainBodyAsts ++ rescueAsts ++ elseClauseAsts
+    } else {
+      mainBodyAsts ++ rescueAsts
+    }
   }
 
   def astForMethodDefinitionContext(ctx: MethodDefinitionContext): Seq[Ast] = {
@@ -1557,10 +1616,11 @@ class AstCreator(filename: String, global: Global)
     val varSymbol = localVar.getSymbol()
     val node      = createIdentifierWithScope(ctx, varSymbol.getText, varSymbol.getText, Defines.Any, List(Defines.Any))
 
+    val operatorName = getOperatorName(ctx.COLON2().getSymbol)
     val callNode = NewCall()
-      .name(ctx.COLON2().getText)
+      .name(operatorName)
       .code(ctx.getText)
-      .methodFullName(MethodFullNames.OperatorPrefix + ctx.COLON2().getText)
+      .methodFullName(operatorName)
       .signature("")
       .dispatchType(DispatchTypes.STATIC_DISPATCH)
       .typeFullName(Defines.Any)
diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerBase.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerBase.scala
new file mode 100644
index 000000000..86c8390da
--- /dev/null
+++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerBase.scala
@@ -0,0 +1,24 @@
+package io.joern.rubysrc2cpg.parser
+
+import io.joern.rubysrc2cpg.parser.RubyLexer._
+import org.antlr.v4.runtime.{CharStream, Lexer, Token}
+
+/** Aggregates auxiliary features to RubyLexer in a single place. */
+abstract class RubyLexerBase(input: CharStream)
+    extends Lexer(input)
+    with RubyLexerRegexHandling
+    with RubyLexerStringInterpolationHandling {
+
+  /** The previously (non-WS) emitted token (in DEFAULT_CHANNEL.) */
+  protected var previousNonWsToken: Option[Token] = None
+
+  // Same original behaviour, just updating `previousNonWsToken`.
+  override def nextToken: Token = {
+    val token: Token = super.nextToken
+    if (token.getChannel == Token.DEFAULT_CHANNEL && token.getType != WS) {
+      previousNonWsToken = Some(token)
+    }
+    token
+  }
+
+}
diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerRegexHandling.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerRegexHandling.scala
new file mode 100644
index 000000000..94a4286b3
--- /dev/null
+++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerRegexHandling.scala
@@ -0,0 +1,63 @@
+package io.joern.rubysrc2cpg.parser
+
+import io.joern.rubysrc2cpg.parser.RubyLexer._
+
+trait RubyLexerRegexHandling { this: RubyLexerBase =>
+
+  /* When encountering '/', we need to decide whether this is a binary operator (e.g. `x / y`) or
+   * a regular expression delimiter (e.g. `/(eu|us)/`) occurrence. Our approach is to look at the
+   * previously emitted token and decide accordingly.
+   */
+  private val regexTogglingTokens: Set[Any] = Set(
+    // When '/' is the first token in the stream.
+    null,
+    // When '/' occurs after an opening parenthesis, brace or bracket.
+    LPAREN,
+    LCURLY,
+    LBRACK,
+    // When '/' occurs after a NL.
+    NL,
+    // When '/' occurs after a ','.
+    COMMA,
+    // When '/' occurs after an operator.
+    EMARK,
+    EMARKEQ,
+    EMARKTILDE,
+    AMP,
+    AMP2,
+    AMPDOT,
+    BAR,
+    BAR2,
+    EQ,
+    EQ2,
+    EQ3,
+    CARET,
+    LTEQGT,
+    EQTILDE,
+    GT,
+    GTEQ,
+    LT,
+    LTEQ,
+    LT2,
+    GT2,
+    PLUS,
+    MINUS,
+    STAR,
+    STAR2,
+    SLASH,
+    PERCENT,
+    TILDE,
+    PLUSAT,
+    MINUSAT,
+    ASSIGNMENT_OPERATOR
+  )
+
+  /** To be invoked when encountering `/`, deciding if it should emit a `REGULAR_EXPRESSION_START` token. */
+  protected def isStartOfRegex: Boolean =
+    regexTogglingTokens.contains(previousNonWsToken.map(_.getType).orNull)
+
+  /** To be invoked when in `DEFAULT_MODE`, to check if we are in the context of a regular expression interpolation. */
+  protected def isInRegularExpressionInterpolationMode: Boolean =
+    _modeStack.size > 1 && _modeStack.peek == REGULAR_EXPRESSION_MODE
+
+}
diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerStringInterpolationHandling.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerStringInterpolationHandling.scala
new file mode 100644
index 000000000..d156ab822
--- /dev/null
+++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyLexerStringInterpolationHandling.scala
@@ -0,0 +1,11 @@
+package io.joern.rubysrc2cpg.parser
+
+import io.joern.rubysrc2cpg.parser.RubyLexer._
+
+trait RubyLexerStringInterpolationHandling { this: RubyLexerBase =>
+
+  /** To be invoked when in `DEFAULT_MODE`, to check if we are in the context of a string interpolation. */
+  protected def isInStringInterpolationMode: Boolean =
+    _modeStack.size > 1 && _modeStack.peek == DOUBLE_QUOTED_STRING_MODE
+
+}
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgcreation/CfgCreator.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgcreation/CfgCreator.scala
index 56e5aa7aa..e6ea790c2 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgcreation/CfgCreator.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgcreation/CfgCreator.scala
@@ -5,7 +5,6 @@ import io.shiftleft.codepropertygraph.generated.{ControlStructureTypes, Dispatch
 import io.shiftleft.semanticcpg.language._
 import io.joern.x2cpg.passes.controlflow.cfgcreation.Cfg.CfgEdgeType
 import overflowdb.BatchedUpdate.DiffGraphBuilder
-import overflowdb.traversal.Traversal
 
 /** Translation of abstract syntax trees into control flow graphs
   *
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/CpgCfgAdapter.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/CpgCfgAdapter.scala
index 6a6efa144..8fe7fb1d9 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/CpgCfgAdapter.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/CpgCfgAdapter.scala
@@ -2,14 +2,12 @@ package io.joern.x2cpg.passes.controlflow.cfgdominator
 
 import io.shiftleft.codepropertygraph.generated.nodes.StoredNode
 
-import scala.jdk.CollectionConverters._
-
 class CpgCfgAdapter extends CfgAdapter[StoredNode] {
-  override def successors(node: StoredNode): IterableOnce[StoredNode] = {
+
+  override def successors(node: StoredNode): IterableOnce[StoredNode] =
     node._cfgOut
-  }
 
-  override def predecessors(node: StoredNode): IterableOnce[StoredNode] = {
+  override def predecessors(node: StoredNode): IterableOnce[StoredNode] =
     node._cfgIn
-  }
+
 }
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/ReverseCpgCfgAdapter.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/ReverseCpgCfgAdapter.scala
index 3e62837b3..1bf429345 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/ReverseCpgCfgAdapter.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/cfgdominator/ReverseCpgCfgAdapter.scala
@@ -2,14 +2,12 @@ package io.joern.x2cpg.passes.controlflow.cfgdominator
 
 import io.shiftleft.codepropertygraph.generated.nodes.StoredNode
 
-import scala.jdk.CollectionConverters._
-
 class ReverseCpgCfgAdapter extends CfgAdapter[StoredNode] {
-  override def successors(node: StoredNode): IterableOnce[StoredNode] = {
+
+  override def successors(node: StoredNode): IterableOnce[StoredNode] =
     node._cfgIn
-  }
 
-  override def predecessors(node: StoredNode): IterableOnce[StoredNode] = {
+  override def predecessors(node: StoredNode): IterableOnce[StoredNode] =
     node._cfgOut
-  }
+
 }
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala
index 49edc53c0..fb42b0e5f 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala
@@ -42,7 +42,7 @@ class CdgPass(cpg: Cpg) extends ForkJoinParallelCpgPass[Method](cpg) {
           if (containsIn == null || !containsIn.hasNext) {
             logger.warn(s"Found CDG edge starting at $nodeLabel node. This is most likely caused by an invalid CFG.")
           } else {
-            val method = containsIn.next
+            val method = containsIn.next()
             logger.warn(
               s"Found CDG edge starting at $nodeLabel node. This is most likely caused by an invalid CFG." +
                 s" Method: ${method match {
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CpgPostDomTreeAdapter.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CpgPostDomTreeAdapter.scala
index 028d7e6c2..ec47bdab9 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CpgPostDomTreeAdapter.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CpgPostDomTreeAdapter.scala
@@ -2,11 +2,10 @@ package io.joern.x2cpg.passes.controlflow.codepencegraph
 
 import io.shiftleft.codepropertygraph.generated.nodes.StoredNode
 import io.joern.x2cpg.passes.controlflow.cfgdominator.DomTreeAdapter
-import overflowdb.traversal._
 
 class CpgPostDomTreeAdapter extends DomTreeAdapter[StoredNode] {
 
-  override def immediateDominator(cfgNode: StoredNode): Option[StoredNode] = {
+  override def immediateDominator(cfgNode: StoredNode): Option[StoredNode] =
     cfgNode._postDominateIn.nextOption()
-  }
+
 }
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeHintCallLinker.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeHintCallLinker.scala
index c15568dd4..d5e814223 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeHintCallLinker.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeHintCallLinker.scala
@@ -167,7 +167,7 @@ abstract class XTypeHintCallLinker(cpg: Cpg) extends CpgPass(cpg) {
       NewNamespaceBlock().name(XTypeHintCallLinker.namespace).fullName(XTypeHintCallLinker.namespace)
 
     builder.addNode(speculativeNamespace)
-    newMethods
+    newMethods.iterator
       .filter(_.astParentFullName == XTypeHintCallLinker.namespace)
       .foreach(m => builder.addEdge(speculativeNamespace, m, EdgeTypes.AST))
   }
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeRecovery.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeRecovery.scala
index 4d17bf328..15c6f64df 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeRecovery.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/frontend/XTypeRecovery.scala
@@ -937,16 +937,7 @@ abstract class RecoverForXCompilationUnit[CompilationUnitType <: AstNode](
     baseTypes
       .map(t => if (t.endsWith(funcName)) t else s"$t$pathSep$funcName")
       .flatMap(p => cpg.method.fullNameExact(p))
-      .map { m =>
-        (
-          m,
-          NewMethodRef()
-            .code(s"${baseName.map(_.appended(pathSep)).getOrElse("")}$funcName")
-            .methodFullName(m.fullName)
-            .lineNumber(funcPtr.lineNumber)
-            .columnNumber(funcPtr.columnNumber)
-        )
-      }
+      .map(m => m -> createMethodRef(baseName, funcName, m.fullName, funcPtr.lineNumber, funcPtr.columnNumber))
       .filterNot { case (_, mRef) =>
         addedNodes.contains((funcPtr.id(), s"${mRef.label()}$pathSep${mRef.methodFullName}"))
       }
@@ -955,21 +946,42 @@ abstract class RecoverForXCompilationUnit[CompilationUnitType <: AstNode](
           .filterNot(_.astChildren.isMethodRef.methodFullNameExact(mRef.methodFullName).nonEmpty)
           .foreach { inCall =>
             state.changesWereMade.compareAndSet(false, true)
-            builder.addNode(mRef)
-            builder.addEdge(mRef, m, EdgeTypes.REF)
-            builder.addEdge(inCall, mRef, EdgeTypes.AST)
-            inCall match {
-              case x: Call =>
-                builder.addEdge(x, mRef, EdgeTypes.ARGUMENT)
-                mRef.argumentIndex(x.argumentOut.size + 1)
-              case x =>
-                mRef.argumentIndex(x.astChildren.size + 1)
-            }
+            integrateMethodRef(funcPtr, m, mRef, inCall)
           }
-        addedNodes.add((funcPtr.id(), s"${mRef.label()}$pathSep${mRef.methodFullName}"))
       }
   }
 
+  private def createMethodRef(
+    baseName: Option[String],
+    funcName: String,
+    methodFullName: String,
+    lineNo: Option[Integer],
+    columnNo: Option[Integer]
+  ): NewMethodRef =
+    NewMethodRef()
+      .code(s"${baseName.map(_.appended(pathSep)).getOrElse("")}$funcName")
+      .methodFullName(methodFullName)
+      .lineNumber(lineNo)
+      .columnNumber(columnNo)
+
+  /** Integrate this method ref node into the CPG according to schema rules. Since we're adding this after the base
+    * passes, we need to add the necessary linking manually.
+    */
+  private def integrateMethodRef(funcPtr: Expression, m: Method, mRef: NewMethodRef, inCall: AstNode) = {
+    builder.addNode(mRef)
+    builder.addEdge(mRef, m, EdgeTypes.REF)
+    builder.addEdge(inCall, mRef, EdgeTypes.AST)
+    builder.addEdge(funcPtr.method, mRef, EdgeTypes.CONTAINS)
+    inCall match {
+      case x: Call =>
+        builder.addEdge(x, mRef, EdgeTypes.ARGUMENT)
+        mRef.argumentIndex(x.argumentOut.size + 1)
+      case x =>
+        mRef.argumentIndex(x.astChildren.size + 1)
+    }
+    addedNodes.add((funcPtr.id(), s"${mRef.label()}$pathSep${mRef.methodFullName}"))
+  }
+
   protected def persistType(x: StoredNode, types: Set[String]): Unit = {
     val filteredTypes = if (state.config.enabledDummyTypes) types else types.filterNot(XTypeRecovery.isDummyType)
     if (filteredTypes.nonEmpty) {
diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala
index a3f9a9ec2..004efa4d8 100644
--- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala
+++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala
@@ -13,7 +13,6 @@ import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import overflowdb.NodeDb
 import overflowdb.PropertyKey
-import overflowdb.traversal.Traversal
 import overflowdb.NodeRef
 import overflowdb.traversal._
 import overflowdb.traversal.ChainedImplicitsTemp._
diff --git a/project/SimpleCache.scala b/project/SimpleCache.scala
index 5d919489e..e73eda672 100644
--- a/project/SimpleCache.scala
+++ b/project/SimpleCache.scala
@@ -1,5 +1,6 @@
 import sbt.{IO, URL}
 import java.io.File
+import java.net.URI
 import java.net.URLEncoder
 
 object SimpleCache {
@@ -12,7 +13,7 @@ object SimpleCache {
     val localFile = encodeFile(url)
     if (!localFile.exists) {
       println(s"downloading $url")
-      sbt.io.Using.urlInputStream(new URL(url)) { inputStream =>
+      sbt.io.Using.urlInputStream(new URI(url).toURL) { inputStream =>
         IO.transfer(inputStream, localFile)
       }
     }
diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CallGraphGenerator.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CallGraphGenerator.scala
index c938da219..d06bb6458 100644
--- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CallGraphGenerator.scala
+++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CallGraphGenerator.scala
@@ -11,7 +11,7 @@ class CallGraphGenerator {
 
   def generate(cpg: Cpg): Graph = {
     val subgraph = mutable.HashMap.empty[String, Seq[StoredNode]]
-    val vertices = cpg.all.collect { case m: Method => m }.l
+    val vertices = cpg.method.l
     val edges = for {
       srcMethod <- vertices
       _ = storeInSubgraph(srcMethod, subgraph)
diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CdgGenerator.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CdgGenerator.scala
index 265186ed3..2507bcf9e 100644
--- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CdgGenerator.scala
+++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CdgGenerator.scala
@@ -10,10 +10,7 @@ class CdgGenerator extends CfgGenerator {
 
   override val edgeType: String = EdgeTypes.CDG
 
-  override def expand(v: StoredNode): Iterator[Edge] = {
-    v._cdgOut
-      .filter(_.isInstanceOf[StoredNode])
-      .map(node => Edge(v, node, edgeType = edgeType))
-  }
+  override def expand(v: StoredNode): Iterator[Edge] =
+    v._cdgOut.map(node => Edge(v, node, edgeType = edgeType))
 
 }
diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CfgGenerator.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CfgGenerator.scala
index c99c146b9..45999fbe4 100644
--- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CfgGenerator.scala
+++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/CfgGenerator.scala
@@ -6,8 +6,6 @@ import io.shiftleft.semanticcpg.dotgenerator.DotSerializer.{Edge, Graph}
 import io.shiftleft.semanticcpg.language._
 import overflowdb.Node
 
-import scala.jdk.CollectionConverters._
-
 class CfgGenerator {
 
   val edgeType: String = EdgeTypes.CFG
@@ -43,19 +41,21 @@ class CfgGenerator {
     )
   }
 
-  protected def expand(v: StoredNode): Iterator[Edge] = {
-    v._cfgOut
-      .filter(_.isInstanceOf[StoredNode])
-      .map(node => Edge(v, node, edgeType = edgeType))
+  protected def expand(v: StoredNode): Iterator[Edge] =
+    v._cfgOut.map(node => Edge(v, node, edgeType = edgeType))
+
+  private def isConditionInControlStructure(v: Node): Boolean = v match {
+    case id: Identifier => id.astParent.isControlStructure
+    case _              => false
   }
 
-  def cfgNodeShouldBeDisplayed(v: Node): Boolean = !(
-    v.isInstanceOf[Literal] ||
-      v.isInstanceOf[Identifier] ||
-      v.isInstanceOf[Block] ||
-      v.isInstanceOf[ControlStructure] ||
-      v.isInstanceOf[JumpTarget] ||
-      v.isInstanceOf[MethodParameterIn]
-  )
+  private def cfgNodeShouldBeDisplayed(v: Node): Boolean =
+    isConditionInControlStructure(v) ||
+      !(v.isInstanceOf[Literal] ||
+        v.isInstanceOf[Identifier] ||
+        v.isInstanceOf[Block] ||
+        v.isInstanceOf[ControlStructure] ||
+        v.isInstanceOf[JumpTarget] ||
+        v.isInstanceOf[MethodParameterIn])
 
 }
diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/TypeHierarchyGenerator.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/TypeHierarchyGenerator.scala
index a75258ed8..e3097cb9e 100644
--- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/TypeHierarchyGenerator.scala
+++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/dotgenerator/TypeHierarchyGenerator.scala
@@ -11,8 +11,8 @@ class TypeHierarchyGenerator {
 
   def generate(cpg: Cpg): Graph = {
     val subgraph         = mutable.HashMap.empty[String, Seq[StoredNode]]
-    val vertices         = cpg.all.collect { case m: TypeDecl => m }.l
-    val typeToIsExternal = cpg.all.collect { case m: TypeDecl => m }.map { t => t.fullName -> t.isExternal }.toMap
+    val vertices         = cpg.typeDecl.l
+    val typeToIsExternal = vertices.map { t => t.fullName -> t.isExternal }.toMap
     val edges = for {
       srcTypeDecl <- vertices
       srcType     <- srcTypeDecl._typeViaRefIn.l
diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/nodemethods/AstNodeMethods.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/nodemethods/AstNodeMethods.scala
index cfaae4dec..4dc11891b 100644
--- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/nodemethods/AstNodeMethods.scala
+++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/nodemethods/AstNodeMethods.scala
@@ -131,7 +131,6 @@ class AstNodeMethods(val node: AstNode) extends AnyVal with NodeExtension {
 
 object AstNodeMethods {
 
-  import scala.jdk.CollectionConverters._
   private def lastExpressionInBlock(block: Block): Option[Expression] =
     block._astOut
       .collect {


Test patch:
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/ReachingDefTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/ReachingDefTests.scala
index 65f227b8d..c1c41699e 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/ReachingDefTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/ReachingDefTests.scala
@@ -64,7 +64,7 @@ class ReachingDefTests extends DataFlowCodeToCpgSuite {
       id.name shouldBe "y"
 
       val List(ret) = cpg.method("foo").ast.isReturn.l
-      flowGraph.succ(ret).toSet shouldBe Set(paramOut1)
+      flowGraph.succ(ret).iterator.to(Set) shouldBe Set(paramOut1)
       flowGraph.succ(paramOut1) shouldBe List(paramOut2)
       flowGraph.succ(paramOut2) shouldBe List(fooMethod.methodReturn)
     }
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/io/dotgenerator/DotCfgGeneratorTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/io/dotgenerator/DotCfgGeneratorTests.scala
index 237944ea4..8aabae3e4 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/io/dotgenerator/DotCfgGeneratorTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/io/dotgenerator/DotCfgGeneratorTests.scala
@@ -66,4 +66,34 @@ class DotCfgGeneratorTests extends CCodeToCpgSuite {
 
   }
 
+  "DotCfgGeneratorTest3" should {
+    val cpg = code("""
+        |int example(int a, int b, int c) {
+        |  int x = 3;
+        |  if(a) {
+        |    foo();
+        |  }
+        |  if(b) {
+        |    foo_2();
+        |  }
+        |  if (c) {
+        |    foo_3();
+        |  }
+        |}
+        |""".stripMargin)
+
+    "contain identifiers as conditions" in {
+      inside(cpg.method.name("example").dotCfg.l) { case List(dotStr) =>
+        dotStr should (
+          startWith("digraph \"example\" {") and
+            include("<(IDENTIFIER,a,if (a))<SUB>4</SUB>>") and
+            include("<(IDENTIFIER,b,if (b))<SUB>7</SUB>>") and
+            include("<(IDENTIFIER,c,if (c))<SUB>10</SUB>>") and
+            endWith("}\n")
+        )
+      }
+    }
+
+  }
+
 }
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/ast/AstCreationPassTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/ast/AstCreationPassTests.scala
index e9f8a47a9..cf18d0f12 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/ast/AstCreationPassTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/ast/AstCreationPassTests.scala
@@ -11,7 +11,6 @@ import io.shiftleft.codepropertygraph.generated.nodes._
 import io.shiftleft.semanticcpg.language._
 import io.shiftleft.semanticcpg.language.operatorextension.OpNodes
 import io.shiftleft.semanticcpg.language.types.structure.NamespaceTraversal
-import overflowdb.traversal.NodeOps
 import overflowdb.traversal.toNodeTraversal
 
 class AstCreationPassTests extends AbstractPassTest {
diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala
index 7ad59c663..39b8ef0af 100644
--- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala
+++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala
@@ -52,4 +52,43 @@ class DataFlowTests extends DataFlowCodeToCpgSuite {
     }
   }
 
+  "Return via call with initialization" should {
+    val cpg = code("""
+        |def add(p)
+        |q = 5
+        |q = p
+        |return q
+        |end
+        |
+        |n = 1
+        |ret = add(n)
+        |puts ret
+        |""".stripMargin)
+
+    "be found" in {
+      val src  = cpg.identifier.name("n").l
+      val sink = cpg.call.name("puts").l
+      sink.reachableByFlows(src).l.size shouldBe 2
+    }
+  }
+
+  "Return via call w/o initialization" ignore {
+    val cpg = code("""
+        |def add(p)
+        |q = p
+        |return q
+        |end
+        |
+        |n = 1
+        |ret = add(n)
+        |puts ret
+        |""".stripMargin)
+
+    "be found" in {
+      val src  = cpg.identifier.name("n").l
+      val sink = cpg.call.name("puts").l
+      sink.reachableByFlows(src).l.size shouldBe 2
+    }
+  }
+
 }
diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RegexTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RegexTests.scala
index 206fb7197..fbe449e95 100644
--- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RegexTests.scala
+++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RegexTests.scala
@@ -62,7 +62,7 @@ class RegexTests extends RubyParserAbstractTest {
       }
     }
 
-    "as the argument to an parenthesized invocation" should {
+    "as the sole argument to a parenthesized invocation" should {
       val code = "puts(//)"
 
       "be parsed as such" in {
@@ -84,6 +84,37 @@ class RegexTests extends RubyParserAbstractTest {
             |    )""".stripMargin
       }
     }
+
+    "as the second argument to a parenthesized invocation" should {
+      val code = "puts(1, //)"
+
+      "be parsed as such" in {
+        printAst(_.expressionOrCommand(), code) shouldEqual
+          """ExpressionExpressionOrCommand
+            | PrimaryExpression
+            |  InvocationWithParenthesesPrimary
+            |   MethodIdentifier
+            |    puts
+            |   ArgsOnlyArgumentsWithParentheses
+            |    (
+            |    BlockExprAssocTypeArguments
+            |     Expressions
+            |      PrimaryExpression
+            |       LiteralPrimary
+            |        NumericLiteralLiteral
+            |         NumericLiteral
+            |          UnsignedNumericLiteral
+            |           1
+            |      ,
+            |      WsOrNl
+            |      PrimaryExpression
+            |       LiteralPrimary
+            |        RegularExpressionLiteral
+            |         /
+            |         /
+            |    )""".stripMargin
+      }
+    }
   }
 
   "A non-interpolated regex literal" when {
diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RubyLexerTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RubyLexerTests.scala
index ca9e7b0ab..976c61175 100644
--- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RubyLexerTests.scala
+++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/parser/RubyLexerTests.scala
@@ -333,4 +333,9 @@ class RubyLexerTests extends AnyFlatSpec with Matchers {
       EOF
     )
   }
+
+  "Division operator between identifiers" should "not be confused with regex start" in {
+    val code = "x / y"
+    tokenize(code) shouldBe Seq(LOCAL_VARIABLE_IDENTIFIER, WS, SLASH, WS, LOCAL_VARIABLE_IDENTIFIER, EOF)
+  }
 }
diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/passes/ast/SimpleAstCreationPassTest.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/passes/ast/SimpleAstCreationPassTest.scala
index 837fb266c..29beb65eb 100644
--- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/passes/ast/SimpleAstCreationPassTest.scala
+++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/passes/ast/SimpleAstCreationPassTest.scala
@@ -23,31 +23,31 @@ class SimpleAstCreationPassTest extends RubyCode2CpgFixture {
       arg.columnNumber shouldBe Some(5)
     }
 
-    "have correct structure for an unsigned, decimal integer literal" ignore {
+    "have correct structure for an unsigned, decimal integer literal" in {
       val cpg           = code("123")
       val List(literal) = cpg.literal.l
       literal.typeFullName shouldBe Defines.Integer
       literal.code shouldBe "123"
       literal.lineNumber shouldBe Some(1)
-      literal.columnNumber shouldBe Some(1)
+      literal.columnNumber shouldBe Some(0)
     }
 
-    "have correct structure for a +integer, decimal literal" ignore {
+    "have correct structure for a +integer, decimal literal" in {
       val cpg           = code("+1")
       val List(literal) = cpg.literal.l
       literal.typeFullName shouldBe Defines.Integer
       literal.code shouldBe "+1"
       literal.lineNumber shouldBe Some(1)
-      literal.columnNumber shouldBe Some(1)
+      literal.columnNumber shouldBe Some(0)
     }
 
-    "have correct structure for a -integer, decimal literal" ignore {
+    "have correct structure for a -integer, decimal literal" in {
       val cpg           = code("-1")
       val List(literal) = cpg.literal.l
       literal.typeFullName shouldBe Defines.Integer
       literal.code shouldBe "-1"
       literal.lineNumber shouldBe Some(1)
-      literal.columnNumber shouldBe Some(1)
+      literal.columnNumber shouldBe Some(0)
     }
 
     "have correct structure for an unsigned, decimal float literal" in {
@@ -257,6 +257,15 @@ class SimpleAstCreationPassTest extends RubyCode2CpgFixture {
       literal.columnNumber shouldBe Some(0)
     }
 
+    "have correct structure for an empty regular expression literal used as the second argument to a call" in {
+      val cpg           = code("puts(x, //)")
+      val List(literal) = cpg.literal.l
+      literal.typeFullName shouldBe Defines.Regexp
+      literal.code shouldBe "//"
+      literal.lineNumber shouldBe Some(1)
+      literal.columnNumber shouldBe Some(8)
+    }
+
     "have correct structure for a single left had side call" in {
       val cpg            = code("array[n] = 10")
       val List(callNode) = cpg.call.name(Operators.indexAccess).l
@@ -487,5 +496,23 @@ class SimpleAstCreationPassTest extends RubyCode2CpgFixture {
       methodNode.lineNumberEnd shouldBe Some(4)
       methodNode.columnNumber shouldBe Some(4)
     }
+
+    "have correct structure for scope resolution operator call" in {
+      val cpg = code("""
+          |def foo(param)
+          |::SomeConstant = param
+          |end
+          |""".stripMargin)
+
+      val List(callNode) = cpg.call.name("<operator>.scopeResolution").l
+      callNode.code shouldBe "::SomeConstant"
+      callNode.lineNumber shouldBe Some(3)
+      callNode.columnNumber shouldBe Some(0)
+
+      val List(identifierNode) = cpg.identifier.name("SomeConstant").l
+      identifierNode.code shouldBe "SomeConstant"
+      identifierNode.lineNumber shouldBe Some(3)
+      identifierNode.columnNumber shouldBe Some(0)
+    }
   }
 }
diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala
index a9af29127..495b7d858 100644
--- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala
+++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala
@@ -266,6 +266,7 @@ class IdentifierTests extends RubyCode2CpgFixture {
       cpg.call.name("application").size shouldBe 1
       cpg.call.name("configure").size shouldBe 1
       cpg.call.name("new").size shouldBe 1
+      cpg.call.name("<operator>.scopeResolution").size shouldBe 2
       cpg.identifier.name("Rails").l.size shouldBe 1
       cpg.identifier.name("config").l.size shouldBe 1
       cpg.identifier.name("Formatter").l.size shouldBe 1
@@ -907,4 +908,49 @@ class IdentifierTests extends RubyCode2CpgFixture {
       cpg.method.name("method3").dotAst.l
     }
   }
+
+  "CPG for code with rescue clause" should {
+    val cpg = code("""
+        |begin
+        |  puts "In begin"
+        |rescue SomeException
+        |  puts "SomeException occurred"
+        |rescue => SomeOtherException
+        |  puts "SomeOtherException occurred"
+        |rescue
+        |  puts "Catch-all block"
+        |end
+        |
+        |""".stripMargin)
+
+    "recognise all literal nodes" in {
+      cpg.literal
+        .code("\"In begin\"")
+        .l
+        .size shouldBe 1
+      cpg.literal
+        .code("\"SomeException occurred\"")
+        .l
+        .size shouldBe 1
+      cpg.literal
+        .code("\"SomeOtherException occurred\"")
+        .l
+        .size shouldBe 1
+      cpg.literal
+        .code("\"Catch-all block\"")
+        .l
+        .size shouldBe 1
+    }
+
+    "recognise all call nodes" in {
+      cpg.call
+        .name("puts")
+        .l
+        .size shouldBe 4
+    }
+
+    "successfully plot ASTs" in {
+      cpg.method.name(":program").dotAst.l
+    }
+  }
 }
diff --git a/semanticcpg/src/test/scala/io/shiftleft/semanticcpg/language/StepsTest.scala b/semanticcpg/src/test/scala/io/shiftleft/semanticcpg/language/StepsTest.scala
index 878753a6a..04533b937 100644
--- a/semanticcpg/src/test/scala/io/shiftleft/semanticcpg/language/StepsTest.scala
+++ b/semanticcpg/src/test/scala/io/shiftleft/semanticcpg/language/StepsTest.scala
@@ -9,7 +9,6 @@ import org.json4s._
 import org.json4s.native.JsonMethods.parse
 import org.scalatest.matchers.should.Matchers
 import org.scalatest.wordspec.AnyWordSpec
-import overflowdb.traversal.Traversal
 
 import scala.jdk.CollectionConverters.IteratorHasAsScala