ronantakizawa/codereview-bench huggingface dataset:
Repository: expo/expo
File: templates/expo-template-default/src/app/index.tsx (TypeScript)

Code before:
import * as Device from 'expo-device';
import { Platform, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import { AnimatedIcon } from '@/components/animated-icon';
import { HintRow } from '@/components/hint-row';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { WebBadge } from '@/components/web-badge';
import { BottomTabInset, MaxContentWidth, Spacing } from '@/constants/theme';

function getDevMenuHint() {
  if (Device.isDevice) {
    return 'shake device';
  }
  const shortcut = Platform.OS === 'android' ? 'cmd+m' : 'cmd+d';
  return (
    <>
      press <ThemedText type="code">{shortcut}</ThemedText>
    </>
  );
}

export default function HomeScreen() {
  return (
    <ThemedView style={styles.container}>
      <SafeAreaView style={styles.safeArea}>
        <ThemedView style={styles.heroSection}>
          <AnimatedIcon />
          <ThemedText type="title" style={styles.title}>
            Welcome to&nbsp;Expo
          </ThemedText>
        </ThemedView>

        <ThemedText type="code" style={styles.code}>
          get started
        </ThemedText>

        <ThemedView type="backgroundElement" style={styles.stepContainer}>

Review comment (suggestion):
We could say sth like
```
shake device 
or
enter 'm' in the terminal window
```
since the latter is often much more convenient

Code after:
import * as Device from 'expo-device';
import { Platform, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import { AnimatedIcon } from '@/components/animated-icon';
import { HintRow } from '@/components/hint-row';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { WebBadge } from '@/components/web-badge';
import { BottomTabInset, MaxContentWidth, Spacing } from '@/constants/theme';

function getDevMenuHint() {
  if (Platform.OS === 'web') {
    return <ThemedText type="small">use browser devtools</ThemedText>;
  }
  if (Device.isDevice) {
    return (
      <ThemedText type="small">
        shake device or press <ThemedText type="code">m</ThemedText> in terminal
      </ThemedText>
    );
  }
  const shortcut = Platform.OS === 'android' ? 'cmd+m (or ctrl+m)' : 'cmd+d';
  return (
    <ThemedText type="small">
      press <ThemedText type="code">{shortcut}</ThemedText>
    </ThemedText>
  );
}

export default function HomeScreen() {
  return (
    <ThemedView style={styles.container}>
      <SafeAreaView style={styles.safeArea}>
        <ThemedView style={styles.heroSection}>
          <AnimatedIcon />
          <ThemedText type="title" style={styles.title}>
            Welcome to&nbsp;Expo
          </ThemedText>
Repository: expo/expo
File: packages/expo-video/ios/Cache/CachingHelpers.swift (Swift)

Code before:
  guard let mimeUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeUnretainedValue() else {
    return nil
  }
  return UTTypeCopyPreferredTagWithClass(mimeUTI, kUTTagClassFilenameExtension)?.takeRetainedValue() as? String
}

internal extension Int {
  var MB: Int { return self * 1024 * 1024 }
}

internal extension Array {
  subscript(safe index: Int) -> Element? {
    return indices.contains(index) ? self[index] : nil
  }
}

internal extension Data {
  func subdata(request: URLRequest, response: HTTPURLResponse) -> Data? {
    let (requestStart, requestEnd) = getRangeFromRequest(request: request)
    let (responseStart, responseEnd) = getRangeFromResponse(response: response)

    guard let responseStart, let responseEnd, let requestStart else {
      return nil
    }

    guard requestStart >= responseStart, requestStart <= responseEnd else {
      return nil
    }

    let startIndex = requestStart - responseStart

    guard startIndex >= 0 && startIndex < self.count else {
      return nil
    }

    var endIndex: Int

    if let requestEnd = requestEnd {
      let requestedLength = requestEnd - requestStart + 1
      endIndex = startIndex + requestedLength
    } else {
      // If requestEnd is nil, return data to the end
      endIndex = self.count
    }

    endIndex = Swift.min(endIndex, self.count)

    guard startIndex <= endIndex else {
      return nil
    }


Review comment (suggestion):
Ranges may look nicer

```suggestion
    guard (responseStart...responseEnd).contains(requestStart) else {
```

Code after:
  guard let mimeUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeUnretainedValue() else {
    return nil
  }
  return UTTypeCopyPreferredTagWithClass(mimeUTI, kUTTagClassFilenameExtension)?.takeRetainedValue() as? String
}

internal extension Int {
  var MB: Int { return self * 1024 * 1024 }
}

internal extension Array {
  subscript(safe index: Int) -> Element? {
    return indices.contains(index) ? self[index] : nil
  }
}

internal extension Data {
  func subdata(request: URLRequest, response: HTTPURLResponse) -> Data? {
    let (requestStart, requestEnd) = getRangeFromRequest(request: request)
    let (responseStart, responseEnd) = getRangeFromResponse(response: response)

    guard let responseStart, let responseEnd, let requestStart else {
      return nil
    }

    guard responseStart <= responseEnd, (responseStart...responseEnd).contains(requestStart) else {
      return nil
    }

    let startIndex = requestStart - responseStart

    guard startIndex >= 0 && startIndex < self.count else {
      return nil
    }

    var endIndex: Int

    if let requestEnd = requestEnd {
      let requestedLength = requestEnd - requestStart + 1
      endIndex = startIndex + requestedLength
    } else {
      // If requestEnd is nil, return data to the end
      endIndex = self.count
    }

    endIndex = Swift.min(endIndex, self.count)

    guard startIndex <= endIndex else {
      return nil
    }
Repository: expo/expo
File: packages/expo-server/src/types.ts (TypeScript)

Code before:
import type { _ImmutableHeaders, _ImmutableRequest } from './ImmutableRequest';

/** An immutable version of the Fetch API's `Headers` object. It cannot be mutated or modified.
 */
export interface ImmutableHeaders extends _ImmutableHeaders {}

/** An immutable version of the Fetch API's `Request` object. It cannot be mutated or modified, its
 * headers are immutable, and you won't have access to the request body.
 */
export interface ImmutableRequest extends _ImmutableRequest {
  readonly url: string;
  readonly method: string;
}

/**
 * Middleware function type. Middleware run for every request in your app, or on
 * specified conditionally matched methods and path patterns, as per {@link MiddlewareMatcher}.
 * @param request - An `ImmutableRequest` with read-only headers and no body access
 * @example
 * ```ts
 * import type { MiddlewareFunction } from 'expo-server';
 *
 * const middleware: MiddlewareFunction = async (request) => {
 *   console.log(`Middleware executed for: ${request.url}`);
 * };
 *
 * export default middleware;
 * ```
 * @see [Server middleware](https://docs.expo.dev/router/web/middleware/) for more information.
 */
export type MiddlewareFunction = (
  request: ImmutableRequest
) => Promise<Response | void> | Response | void;


Review comment (suggestion):
```suggestion
/** 
 * An immutable version of the Fetch API's `Request` object. It cannot be mutated or modified, its
 * headers are immutable, and you won't have access to the request body.
 */
```

We should use consistent formatting with TypeDoc comments.

Code after:
import type { _ImmutableHeaders, _ImmutableRequest } from './ImmutableRequest';

/**
 * An immutable version of the Fetch API's `Headers` object. It cannot be mutated or modified.
 */
export interface ImmutableHeaders extends _ImmutableHeaders {}

/**
 * An immutable version of the Fetch API's `Request` object. It cannot be mutated or modified, its
 * headers are immutable, and you won't have access to the request body.
 */
export interface ImmutableRequest extends _ImmutableRequest {
  readonly url: string;
  readonly method: string;
}

/**
 * Middleware function type. Middleware run for every request in your app, or on
 * specified conditionally matched methods and path patterns, as per {@link MiddlewareMatcher}.
 * @param request - An `ImmutableRequest` with read-only headers and no body access
 * @example
 * ```ts
 * import type { MiddlewareFunction } from 'expo-server';
 *
 * const middleware: MiddlewareFunction = async (request) => {
 *   console.log(`Middleware executed for: ${request.url}`);
 * };
 *
 * export default middleware;
 * ```
 * @see [Server middleware](https://docs.expo.dev/router/web/middleware/) for more information.
 */
export type MiddlewareFunction = (
  request: ImmutableRequest
Repository: expo/expo
File: packages/expo-router/src/layouts/stack-utils/screen/StackScreenTitle.tsx (TypeScript)

Code before:
export type StackScreenTitleProps = {
  children?: string;
  style?: StyleProp<{
    fontFamily?: TextStyle['fontFamily'];
    fontSize?: TextStyle['fontSize'];
    fontWeight?: Exclude<TextStyle['fontWeight'], number>;
    // TODO(@ubax): This should be ColorValue, but react-navigation types
    // currently only accept string for color props. In RN v8 we can change this to ColorValue.
    color?: string;
    textAlign?: 'left' | 'center';
  }>;
  /**
   * Style properties for the large title header.
   *
   * @platform ios
   */
  largeStyle?: StyleProp<{
    fontFamily?: TextStyle['fontFamily'];
    fontSize?: TextStyle['fontSize'];
    fontWeight?: Exclude<TextStyle['fontWeight'], number>;
    // TODO(@ubax): This should be ColorValue, but react-navigation types
    // currently only accept string for color props. In RN v8 we can change this to ColorValue.
    color?: string;
  }>;
  /**
   * Whether to use large title mode.
   *
   * @platform ios
   */
  large?: boolean;
};

/**
 * Component to set the screen title.
 *
 * Can be used inside Stack.Screen in a layout or directly inside a screen component.
 *
 * @example
 * ```tsx
 * import { Stack } from 'expo-router';
 *
 * export default function Layout() {
 *   return (
 *     <Stack>
 *       <Stack.Screen name="index">
 *         <Stack.Screen.Title large>Home</Stack.Screen.Title>
 *       </Stack.Screen>
 *     </Stack>
 *   );
 * }
 * ```

Review comment (suggestion):
```suggestion
   * Enables large title mode.
```

Code after:
export type StackScreenTitleProps = {
  children?: string;
  style?: StyleProp<{
    fontFamily?: TextStyle['fontFamily'];
    fontSize?: TextStyle['fontSize'];
    fontWeight?: Exclude<TextStyle['fontWeight'], number>;
    // TODO(@ubax): This should be ColorValue, but react-navigation types
    // currently only accept string for color props. In RN v8 we can change this to ColorValue.
    color?: string;
    textAlign?: 'left' | 'center';
  }>;
  /**
   * Style properties for the large title header.
   *
   * @platform ios
   */
  largeStyle?: StyleProp<{
    fontFamily?: TextStyle['fontFamily'];
    fontSize?: TextStyle['fontSize'];
    fontWeight?: Exclude<TextStyle['fontWeight'], number>;
    // TODO(@ubax): This should be ColorValue, but react-navigation types
    // currently only accept string for color props. In RN v8 we can change this to ColorValue.
    color?: string;
  }>;
  /**
   * Enables large title mode.
   *
   * @platform ios
   */
  large?: boolean;
};

/**
 * Component to set the screen title.
 *
 * Can be used inside Stack.Screen in a layout or directly inside a screen component.
 *
 * @example
 * ```tsx
 * import { Stack } from 'expo-router';
 *
 * export default function Layout() {
 *   return (
 *     <Stack>
 *       <Stack.Screen name="index">
 *         <Stack.Screen.Title large>Home</Stack.Screen.Title>
 *       </Stack.Screen>
 *     </Stack>
 *   );
 * }
 * ```
Repository: expo/expo
File: packages/@expo/env/src/parse.ts (TypeScript)

Code before:
    DOTENV_SUBSTITUTION_REGEX,
    (match, escaped, _dollarSign, _openBrace, key, defaultValue, _closeBrace) => {
      if (escaped === '\\') {
        return match.slice(1);
      } else if (sourceEnv[key]) {
        return sourceEnv[key] === inputEnv[key]
          ? sourceEnv[key]
          : interpolate(sourceEnv[key], key, sourceEnv, inputEnv);
      } else if (inputEnv[key] && key !== sourceKey) {
        return interpolate(inputEnv[key], key, sourceEnv, inputEnv);
      } else if (defaultValue) {
        return defaultValue.startsWith('$')
          ? interpolate(defaultValue, key, sourceEnv, inputEnv)
          : defaultValue;
      } else {
        return '';
      }
    }
  );
}

export function expand(inputEnv: EnvOutput, sourceEnv: EnvOutput): EnvOutput {
  const outputEnv = { ...inputEnv };
  for (const key in outputEnv) {
    let value = outputEnv[key];
    if (Object.prototype.hasOwnProperty.call(sourceEnv, key)) {
      value =
        value != null && sourceEnv[key] === value
          ? interpolate(value, key, sourceEnv, outputEnv)
          : sourceEnv[key];
    } else if (value != null) {
      value = interpolate(value, key, sourceEnv, outputEnv);
    }
    if (value != null) {
      outputEnv[key] = value.replace(/\\\$/g, '$');
    }
  }
  return outputEnv;
}


Review comment (suggestion):
We do allow references to the same `.env` file's variables, but we don't self-mutate this anymore to allow this to be repeatable. Technically, this isn't in use, since `expand` is never called on a re-used object, but this is to self-document that we want to avoid mutating env objects.

`dotenv-expand` **did** mutate the input env object.

Code after:
  inputEnv: EnvOutput
): string {
  return value.replace(
    DOTENV_SUBSTITUTION_REGEX,
    (match, escaped, _dollarSign, _openBrace, key, defaultValue, _closeBrace) => {
      if (escaped === '\\') {
        return match.slice(1);
      } else if (sourceEnv[key]) {
        return sourceEnv[key] === inputEnv[key]
          ? sourceEnv[key]
          : interpolate(sourceEnv[key], key, sourceEnv, inputEnv);
      } else if (inputEnv[key] && key !== sourceKey) {
        return interpolate(inputEnv[key], key, sourceEnv, inputEnv);
      } else if (defaultValue) {
        return defaultValue.startsWith('$')
          ? interpolate(defaultValue, key, sourceEnv, inputEnv)
          : defaultValue;
      } else {
        return '';
      }
    }
  );
}

export function expand(inputEnv: EnvOutput, sourceEnv: EnvOutput): EnvOutput {
  const outputEnv = { ...inputEnv };
  for (const key in outputEnv) {
    let value = outputEnv[key];
    if (Object.prototype.hasOwnProperty.call(sourceEnv, key)) {
      value =
        value != null && sourceEnv[key] === value
          ? interpolate(value, key, sourceEnv, outputEnv)
          : sourceEnv[key];
    } else if (value != null) {
      value = interpolate(value, key, sourceEnv, outputEnv);
    }
    if (value != null) {
      outputEnv[key] = value.replace(/\\\$/g, '$');
    }
  }
  return outputEnv;
}
Repository: expo/expo
File: packages/expo-ui/src/swift-ui/modifiers/contentShape.ts (TypeScript)

Code before:
import { createModifier } from './createModifier';
import type { Shape } from './shapes/index';

/**
 * Defines the content shape for hit-testing purposes.
 * 
 * This modifier is essential for making entire view areas (including `Spacer` or empty space)
 * interactive. Without it, only visible elements like `Text` or `Image` respond to tap gestures.
 * 
 * @param shape - A shape configuration from the shapes API (rectangle, circle, capsule, ellipse, roundedRectangle)
 * 
 * @example
 * ```tsx
 * import { HStack, List, Section, Spacer, Text } from "@expo/ui/swift-ui";
 * import { contentShape, onTapGesture } from "@expo/ui/swift-ui/modifiers";
 * import { shapes } from "@expo/ui/swift-ui/modifiers";
 * 
 * function InteractiveRow() {
 *   return (
 *     <List>
 *       <Section title="Settings">
 *         <HStack
 *           modifiers={[
 *             contentShape(shapes.rectangle()),
 *             onTapGesture(() => console.log("Row tapped!"))
 *           ]}
 *         >
 *           <Text>Label</Text>
 *           <Spacer />
 *           <Text>Value</Text>
 *         </HStack>
 *       </Section>
 *     </List>
 *   );
 * }

Review comment (suggestion):
```suggestion
 * @param shape - A shape configuration from the shapes API (rectangle, circle, capsule, ellipse, roundedRectangle).
```

Missing period

Code after:
import { createModifier } from './createModifier';
import type { Shape } from './shapes/index';

/**
 * Defines the content shape for hit-testing purposes.
 *
 * This modifier is essential for making entire view areas (including `Spacer` or empty space)
 * interactive. Without it, only visible elements like `Text` or `Image` respond to tap gestures.
 *
 * @param shape - A shape configuration from the shapes API (rectangle, circle, capsule, ellipse, roundedRectangle).
 *
 * @example
 * ```tsx
 * import { HStack, List, Section, Spacer, Text } from "@expo/ui/swift-ui";
 * import { contentShape, onTapGesture } from "@expo/ui/swift-ui/modifiers";
 * import { shapes } from "@expo/ui/swift-ui/modifiers";
 *
 * function InteractiveRow() {
 *   return (
 *     <List>
 *       <Section title="Settings">
 *         <HStack
 *           modifiers={[
 *             contentShape(shapes.rectangle()),
 *             onTapGesture(() => console.log("Row tapped!"))
 *           ]}
 *         >
 *           <Text>Label</Text>
 *           <Spacer />
 *           <Text>Value</Text>
 *         </HStack>
 *       </Section>
 *     </List>
 *   );
 * }
Repository: expo/expo
File: packages/@expo/cli/src/utils/downloadExpoGoAsync.ts (TypeScript)

Code before:
      url,
      // Save all encrypted cache data to `~/.expo/expo-go`
      cacheDirectory: 'expo-go',
      outputPath,
      extract: shouldExtractResults,
      onProgress({ progress, total }) {
        if (progress && total) {
          if (!bar) {
            if (spinner.isSpinning) {
              spinner.stop();
            }
            bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', {
              width: 64,
              total: 100,
              // clear: true,
              complete: '=',
              incomplete: ' ',
            });
          } else {
            bar.update(progress, total);
          }
        }
      },
    });
    return outputPath;
  } finally {
    spinner.stop();
    (bar as ProgressBar | null)?.terminate();
  }
}


Review comment (bug):
If we're not awaiting to run this concurrently we should maybe add some debug calls for ourselves and add a catch call for uncaugt errors.

Not sure if this was accidental though 

Code after:
    sdkVersion: string;
  }
): Promise<string> {
  const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform];

  const spinner = ora({ text: 'Fetching Expo Go', color: 'white' }).start();

  let bar: ProgressBar | null = null;

  try {
    if (!url) {
      const version = await getExpoGoVersionEntryAsync(sdkVersion);

      debug(`Installing Expo Go version for SDK ${sdkVersion} at URL: ${version[versionsKey]}`);
      url = version[versionsKey] as string;
    }
  } catch (error) {
    spinner.fail();
    throw error;
  }

  const filename = path.parse(url).name;

  try {
    const outputPath = getFilePath(filename);
    cleanupOldExpoGoCacheEntriesAsync(path.dirname(outputPath));
    debug(`Downloading Expo Go from "${url}" to "${outputPath}".`);
    debug(
      `The requested copy of Expo Go might already be cached in: "${getExpoHomeDirectory()}". You can disable the cache with EXPO_NO_CACHE=1`
    );
    await profile(downloadAppAsync)({
      url,
      // Save all encrypted cache data to `~/.expo/expo-go`
      cacheDirectory: 'expo-go',
      outputPath,
      extract: shouldExtractResults,
      onProgress({ progress, total }) {
        if (progress && total) {
          if (!bar) {
            if (spinner.isSpinning) {
              spinner.stop();
            }
            bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', {
              width: 64,
              total: 100,
              // clear: true,
              complete: '=',
              incomplete: ' ',
            });
          } else {
            bar.update(progress, total);
Repository: expo/expo
File: packages/expo-ui/ios/SliderView.swift (Swift)

Code before:
// Copyright 2025-present 650 Industries. All rights reserved.

import SwiftUI
import ExpoModulesCore

struct SliderView: ExpoSwiftUI.View {
  @ObservedObject var props: SliderProps
  @State var value: Float = 0.0

  init(props: SliderProps) {
    self.props = props
    var initialValue = props.value ?? 0.0
    _value = State(initialValue: initialValue)
  }

  var body: some View {
#if !os(tvOS)
    sliderContent
      .onChange(of: value) { newValue in
        if props.value != newValue {
          props.onValueChanged([
            "value": newValue
          ])
        }
      }
      .onReceive(props.value.publisher, perform: { newValue in
        var sliderValue = newValue
        value = sliderValue
      })
#else
    Text("Slider is not supported on tvOS")
#endif
  }

#if !os(tvOS)
  @ViewBuilder
  private var sliderContent: some View {

Review comment (suggestion):
[🐧 nit] Nit: `var` is unused as a mutable — this could be `let` or inlined:
```swift
_value = State(initialValue: props.value ?? 0.0)
```

Code after:
// Copyright 2025-present 650 Industries. All rights reserved.

import SwiftUI
import ExpoModulesCore

struct SliderView: ExpoSwiftUI.View {
  @ObservedObject var props: SliderProps
  @State var value: Float = 0.0

  init(props: SliderProps) {
    self.props = props
    _value = State(initialValue: props.value ?? 0.0)
  }

  var body: some View {
#if !os(tvOS)
    sliderContent
      .onChange(of: value) { newValue in
        if props.value != newValue {
          props.onValueChanged([
            "value": newValue
          ])
        }
      }
      .onReceive(props.value.publisher, perform: { newValue in
        var sliderValue = newValue
        value = sliderValue
      })
#else
    Text("Slider is not supported on tvOS")
#endif
  }

#if !os(tvOS)
  @ViewBuilder
  private var sliderContent: some View {
    let label = props.children?.compactMap({ $0.childView as? SliderLabelView })
Repository: expo/expo
File: packages/expo-video/android/src/main/java/expo/modules/video/records/PlayerBuilderOptions.kt (Kotlin)

Code before:
package expo.modules.video.records

import androidx.media3.common.util.UnstableApi
import expo.modules.kotlin.records.Field
import expo.modules.kotlin.records.Record
import java.io.Serializable

@UnstableApi
class PlayerBuilderOptions(
  @Field var seekBackwardIncrement: Double? = null,
  @Field var seekForwardIncrement: Double? = null
) : Record, Serializable


Review comment (suggestion):
```suggestion
  @Field var seekBackwardIncrement: Duration? = null,
  @Field var seekForwardIncrement: Duration? = null
```
You can use the `Duration` class to automatically represent a JS value as seconds in Kotlin.

Code after:
package expo.modules.video.records

import androidx.media3.common.util.UnstableApi
import expo.modules.kotlin.records.Field
import expo.modules.kotlin.records.Record
import java.io.Serializable
import kotlin.time.Duration

@UnstableApi
class PlayerBuilderOptions(
  @Field var seekBackwardIncrement: Duration? = null,
  @Field var seekForwardIncrement: Duration? = null
) : Record, Serializable