Skip to content

Default args for facades should be js.native #565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .scalafix.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
rules = [
DefaultFacadeArgs,
ExplicitResultTypes,
OrganizeImports,
RemoveUnused,
Expand Down
58 changes: 29 additions & 29 deletions api-reports/2_12.txt

Large diffs are not rendered by default.

130 changes: 65 additions & 65 deletions api-reports/2_13.txt

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions prePR.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import Build._
import Dependencies.Ver._

addCommandAlias("prePR", "+prePR_nonCross")

addCommandAlias("quickPrePR", s"++$scala212; prePR_nonCross; ++$scala213; prePR_nonCross")

val prePR_nonCross = taskKey[Unit]("Performs all necessary work required before submitting a PR, for a single version of Scala.")

// Unfortunately we can't just call `root/Test/compile` because it doesn't take aggregation into account :(
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
org.scalajs.dom.scalafix.DefaultFacadeArgs
org.scalajs.dom.scalafix.GenerateApiReport
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.scalajs.dom.scalafix

import scala.meta._
import scalafix.v1._

class DefaultFacadeArgs extends SemanticRule("DefaultFacadeArgs") {

override def fix(implicit doc: SemanticDocument): Patch =
doc.tree.collect {

case Defn.Def(mods, _, _, paramss, _, body) if Util.isJsNative(body) =>

// https://github.com/scala-js/scala-js/issues/4553
// `js.native` as default arg doesn't compile for top-level method facades.
if (Util.isJSGlobal(mods)) {
// Ignore for now
Patch.empty

} else {
// Replace default argument with js.native
lazy val jsNative = body.toString
paramss.iterator.flatten.foldLeft(Patch.empty) { (patch, param) =>
param.default match {
case Some(d) if d.toString != jsNative => patch + Patch.replaceTree(d, jsNative)
case _ => patch
}
}
}
}.asPatch

}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class GenerateApiReport extends SemanticRule("GenerateApiReport") {
.replaceAll(" {2,}", " ")
.trim
.stripSuffix(" = js.native")
.replaceAll(" = js.native(?=[^\n])", "?")
.replaceAll(" = js\\.(native|undefined)(?=[^\n])", "?")

// "?" means that type aliases come before everything else
val name = Util.termName(t2).fold("?")(_.value)
Expand Down
13 changes: 13 additions & 0 deletions scalafix/src/main/scala/org/scalajs/dom/scalafix/Util.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ object Util {

// ===================================================================================================================

def isJSGlobal(mods: List[Mod]): Boolean =
mods.exists {
case Mod.Annot(Init(Type.Name("JSGlobal"), _, _)) => true
case _ => false
}

def isJsNative(t: Term): Boolean = {
val s = t.toString
s == "js.native" || s == "native"
}

// ===================================================================================================================

def parents(sym: Symbol)(implicit doc: SemanticDocument): List[SemanticType] =
dealias(sym).info match {
case Some(i) => parents(i.signature)
Expand Down
24 changes: 12 additions & 12 deletions src/main/scala/org/scalajs/dom/Audio.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class AudioContext extends EventTarget {
* The number of channels in the input audio streams, which the output stream will contain; the default is 6 is
* this parameter is not specified.
*/
def createChannelMerger(numberOfInputs: Int = 6): ChannelMergerNode = js.native
def createChannelMerger(numberOfInputs: Int = js.native): ChannelMergerNode = js.native

/** Creates a ChannelSplitterNode, which is used to access the individual channels of an audio stream and process them
* separately.
Expand All @@ -90,7 +90,7 @@ class AudioContext extends EventTarget {
* The number of channels in the input audio stream that you want to output separately; the default is 6 is this
* parameter is not specified.
*/
def createChannelSplitter(numberOfOutputs: Int = 6): ChannelSplitterNode = js.native
def createChannelSplitter(numberOfOutputs: Int = js.native): ChannelSplitterNode = js.native

/** Creates a ConvolverNode, which can be used to apply convolution effects to your audio graph, for example a
* reverberation effect.
Expand Down Expand Up @@ -414,15 +414,15 @@ trait AudioBufferSourceNode extends AudioNode {
* The duration parameter, which defaults to the length of the asset minus the value of offset, defines the length
* of the portion of the asset to be played.
*/
def start(when: Double = 0.0, offset: Double = 0.0, duration: Double = js.native): Unit = js.native
def start(when: Double = js.native, offset: Double = js.native, duration: Double = js.native): Unit = js.native

/** Schedules the end of the playback of an audio asset.
*
* @param when
* The when parameter defines when the playback will stop. If it represents a time in the past, the playback will
* end immediately. If this method is called twice or more, an exception is raised.
*/
def stop(when: Double = 0.0): Unit = js.native
def stop(when: Double = js.native): Unit = js.native

/** Is an EventHandler containing the callback associated with the ended event. */
var onended: js.Function1[Event, _] = js.native
Expand Down Expand Up @@ -481,7 +481,7 @@ trait AudioListener extends AudioNode {
* @param z
* The z position of the listener in 3D space.
*/
def setPosition(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Unit = js.native
def setPosition(x: Double = js.native, y: Double = js.native, z: Double = js.native): Unit = js.native

/** Defines the orientation of the listener.
*
Expand All @@ -508,8 +508,8 @@ trait AudioListener extends AudioNode {
* @param zUp
* The z value of the up vector of the listener.
*/
def setOrientation(x: Double = 0.0, y: Double = 0.0, z: Double = -1.0, xUp: Double = 0.0, yUp: Double = 1.0,
zUp: Double = 0.0): Unit = js.native
def setOrientation(x: Double = js.native, y: Double = js.native, z: Double = js.native, xUp: Double = js.native,
yUp: Double = js.native, zUp: Double = js.native): Unit = js.native
}

/** The AudioParam interface represents an audio-related parameter, usually a parameter of an AudioNode (such as
Expand Down Expand Up @@ -891,10 +891,10 @@ trait OscillatorNode extends AudioNode {
var `type`: String = js.native // Not sure if this is correct ...

/** This method specifies the exact time to start playing the tone. */
def start(when: Double = 0.0): Unit = js.native
def start(when: Double = js.native): Unit = js.native

/** This method specifies the exact time to stop playing the tone. */
def stop(when: Double = 0.0): Unit = js.native
def stop(when: Double = js.native): Unit = js.native

/** Used to point to a PeriodicWave defining a periodic waveform that can be used to shape the oscillator's output,
* when type = "custom" is used.
Expand Down Expand Up @@ -977,7 +977,7 @@ trait PannerNode extends AudioNode {
* @param z
* The z position of the panner in 3D space.
*/
def setPosition(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Unit = js.native
def setPosition(x: Double = js.native, y: Double = js.native, z: Double = js.native): Unit = js.native

/** Defines the direction the audio source is playing in. This can have a big effect if the sound is very directional
* — controlled by the three cone-related attributes PannerNode.coneInnerAngle, PannerNode.coneOuterAngle, and
Expand All @@ -996,7 +996,7 @@ trait PannerNode extends AudioNode {
* @param z
* The z value of the panner's direction vector in 3D space.
*/
def setOrientation(x: Double = 1.0, y: Double = 0.0, z: Double = 0.0): Unit = js.native
def setOrientation(x: Double = js.native, y: Double = js.native, z: Double = js.native): Unit = js.native

/** Defines the velocity vector of the audio source — how fast it is moving and in what direction.
*
Expand All @@ -1015,7 +1015,7 @@ trait PannerNode extends AudioNode {
* @param z
* The z value of the panner's velocity vector.
*/
def setVelocity(x: Double = 0.0, y: Double = 0.0, z: Double = 0.0): Unit = js.native
def setVelocity(x: Double = js.native, y: Double = js.native, z: Double = js.native): Unit = js.native
}

/** The StereoPannerNode interface of the Web Audio API represents a simple stereo panner node that can be used to pan
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/org/scalajs/dom/Fetch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object Fetch extends js.Object {
* @param init
* @return
*/
def fetch(info: RequestInfo, init: RequestInit = null): js.Promise[Response] = js.native
def fetch(info: RequestInfo, init: RequestInit = js.native): js.Promise[Response] = js.native
}

/** The Request interface of the Fetch API represents a resource request.
Expand Down Expand Up @@ -151,7 +151,7 @@ object Response extends js.Object {
* @return
* a new Response
*/
def redirect(url: String, status: Int = 302): Response = js.native
def redirect(url: String, status: Int = js.native): Response = js.native
}

/** See [[https://fetch.spec.whatwg.org/#response-class ¶6.4 Response class]] definition in whatwg Fetch spec. */
Expand Down
18 changes: 9 additions & 9 deletions src/main/scala/org/scalajs/dom/IDBTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ class IDBObjectStore extends js.Object {
def put(value: js.Any, key: js.Any = js.native): IDBRequest = js.native

/** The method sets the position of the cursor to the appropriate record, based on the specified direction. */
def openCursor(range: js.UndefOr[IDBKeyRange | js.Any] = js.undefined,
direction: js.UndefOr[IDBCursorDirection] = js.undefined): IDBRequest = js.native
def openCursor(range: js.UndefOr[IDBKeyRange | js.Any] = js.native,
direction: js.UndefOr[IDBCursorDirection] = js.native): IDBRequest = js.native

/** The method sets the position of the cursor to the appropriate key, based on the specified direction. */
def openKeyCursor(range: js.UndefOr[IDBKeyRange | js.Any] = js.undefined,
direction: js.UndefOr[IDBCursorDirection] = js.undefined): IDBRequest = js.native
def openKeyCursor(range: js.UndefOr[IDBKeyRange | js.Any] = js.native,
direction: js.UndefOr[IDBCursorDirection] = js.native): IDBRequest = js.native

/** Note that this method must be called only from a VersionChange transaction mode callback. Note that this method
* synchronously modifies the IDBObjectStore.indexNames property.
Expand All @@ -99,14 +99,14 @@ class IDBObjectStore extends js.Object {
/** If a value is successfully found, then a structured clone of it is created and set as the result of the request
* object.
*/
def getAll(query: js.UndefOr[IDBKeyRange | js.Any] = js.undefined,
count: js.UndefOr[Int] = js.undefined): IDBRequest = js.native
def getAll(query: js.UndefOr[IDBKeyRange | js.Any] = js.native,
count: js.UndefOr[Int] = js.native): IDBRequest = js.native

/** If a value is successfully found, then a structured clone of it is created and set as the result of the request
* object.
*/
def getAllKeys(query: js.UndefOr[IDBKeyRange | js.Any] = js.undefined,
count: js.UndefOr[Int] = js.undefined): IDBRequest = js.native
def getAllKeys(query: js.UndefOr[IDBKeyRange | js.Any] = js.native,
count: js.UndefOr[Int] = js.native): IDBRequest = js.native

/** If a value is successfully found, then a structured clone of it is created and set as the result of the request
* object.
Expand Down Expand Up @@ -237,7 +237,7 @@ class IDBCursor extends js.Object {
*
* W3C
*/
def continue(key: js.Any = ???): Unit = js.native
def continue(key: js.Any = js.native): Unit = js.native

/** Returns an IDBRequest object, and, in a separate thread, deletes the record at the cursor's position, without
* changing the cursor's position.
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/org/scalajs/dom/OffscreenCanvas.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class OffscreenCanvas(var width: Double, var height: Double) extends js.Object {
def getContext(contextType: String, contextAttributes: TwoDContextAttributes): js.Dynamic = js.native

/** Creates a Blob object representing the image contained in the canvas. */
def convertToBlob(options: ConvertToBlobOptions = ???): js.Promise[Blob] = js.native
def convertToBlob(options: ConvertToBlobOptions = js.native): js.Promise[Blob] = js.native

/** Creates an ImageBitmap object from the most recently rendered image of the OffscreenCanvas. */
def transferToImageBitmap(): ImageBitmap = js.native
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/org/scalajs/dom/Stream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ trait WriteableStream[-T] extends js.Object {
*
* @param reason
*/
def abort(reason: js.UndefOr[Any] = js.undefined): js.Promise[Unit] = js.native
def abort(reason: js.UndefOr[Any] = js.native): js.Promise[Unit] = js.native

/** The close method signals that the producer is done writing chunks to the stream and wishes to move the stream to a
* "closed" state. This queues an action to close the stream, such that once any currently queued-up writes complete,
Expand Down Expand Up @@ -118,7 +118,7 @@ trait ReadableStream[+T] extends js.Object {
* @return
* a Promise
*/
def cancel(reason: js.UndefOr[Any] = js.undefined): js.Promise[Unit] = js.native
def cancel(reason: js.UndefOr[Any] = js.native): js.Promise[Unit] = js.native

/** See [[https://streams.spec.whatwg.org/#rs-get-reader ¶3.2.4.3. getReader()]] of whatwg streams spec. Also see the
* example usage there.
Expand Down Expand Up @@ -153,7 +153,7 @@ trait ReadableStream[+T] extends js.Object {
* //todo: determine the type of options
*/
def pipeThrough[U](pair: Any, // TODO js.Tuple2[WriteableStream[T], ReadableStream[U]]
options: Any = js.undefined): ReadableStream[U] = js.native
options: Any = js.native): ReadableStream[U] = js.native

/** See
* [[https://streams.spec.whatwg.org/#rs-pipe-to ¶3.2.4.5. pipeTo(dest, { preventClose, preventAbort, preventCancel } = {})]]
Expand All @@ -169,7 +169,7 @@ trait ReadableStream[+T] extends js.Object {
*
* //todo: determine the type of options
*/
def pipeTo(dest: WriteableStream[T], options: Any = js.undefined): Unit = js.native
def pipeTo(dest: WriteableStream[T], options: Any = js.native): Unit = js.native

/** See [[https://streams.spec.whatwg.org/#rs-tee ¶3.2.4.6. tee()]] of whatwg streams spec.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ trait WindowOrWorkerGlobalScope extends WindowBase64 with WindowTimers {
def origin: String = js.native //should be USVString

/** Starts the process of fetching a resource from the network. */
def fetch(info: RequestInfo, init: RequestInit = null): js.Promise[Response] = js.native
def fetch(info: RequestInfo, init: RequestInit = js.native): js.Promise[Response] = js.native

/** Enqueues a microtask—a short function to be executed after execution of the JavaScript code completes and control
* isn't being returned to a JavaScript caller, but before handling callbacks and other tasks.
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/org/scalajs/dom/beacon.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ trait BeaconNavigator extends js.Object {
* @param data
* The data parameter is the ArrayBufferView, Blob, DOMString, or FormData data that is to be transmitted.
*/
def sendBeacon(url: String, data: dom.BodyInit = null): Boolean = js.native
def sendBeacon(url: String, data: dom.BodyInit = js.native): Boolean = js.native
}

/** The Beacon interface is used to schedule an asynchronous and non-blocking request to a web server. Beacon requests
Expand All @@ -48,5 +48,5 @@ trait BeaconWorkerNavigator extends js.Object {
* @param data
* The data parameter is the ArrayBufferView, Blob, DOMString, or FormData data that is to be transmitted.
*/
def sendBeacon(url: String, data: dom.BodyInit = null): Boolean = js.native
def sendBeacon(url: String, data: dom.BodyInit = js.native): Boolean = js.native
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,12 @@ trait ServiceWorkerRegistration extends EventTarget {
* have many active but differently-scoped service worker registrations. Notifications created by one service worker
* on the same origin will not be available to other active services workers on that same origin.
*/
def getNotifications(options: GetNotificationOptions = ???): js.Promise[Sequence[Notification]] = js.native
def getNotifications(options: GetNotificationOptions = js.native): js.Promise[Sequence[Notification]] = js.native

/** The showNotification() method of the ServiceWorkerRegistration interface creates a notification on an active
* service worker.
*/
def showNotification(title: String, options: NotificationOptions = ???): js.Promise[Unit] = js.native
def showNotification(title: String, options: NotificationOptions = js.native): js.Promise[Unit] = js.native
}

/** An object containing options to filter the notifications returned. */
Expand All @@ -212,8 +212,7 @@ trait ServiceWorkerContainer extends EventTarget {
* method can't return a ServiceWorkerRegistration, it returns a Promise. You can call this method unconditionally
* from the controlled page, i.e., you don't need to first check whether there's an active registration.
*/
def register(scriptURL: String,
options: js.Object = new js.Object()): js.Promise[ServiceWorkerRegistration] = js.native
def register(scriptURL: String, options: js.Object = js.native): js.Promise[ServiceWorkerRegistration] = js.native

/** The ServiceWorkerContainer.controller read-only property of the ServiceWorkerContainer interface returns the
* ServiceWorker whose state is activated (the same object returned by ServiceWorkerRegistration.active). This
Expand All @@ -224,7 +223,7 @@ trait ServiceWorkerContainer extends EventTarget {
/** Gets a ServiceWorkerRegistration object whose scope URL matches the document URL. If the method can't return a
* ServiceWorkerRegistration, it returns a Promise.
*/
def getRegistration(scope: String = ""): js.Promise[js.UndefOr[ServiceWorkerRegistration]] = js.native
def getRegistration(scope: String = js.native): js.Promise[js.UndefOr[ServiceWorkerRegistration]] = js.native

/** The getRegistrations() method of the ServiceWorkerContainer interface returns all ServiceWorkerRegistrations
* associated with a ServiceWorkerContainer in an array. If the method can't return ServiceWorkerRegistrations, it
Expand Down
Loading