Skip to content

Commit

Permalink
Merge pull request #123 from ScalablyTyped/beta6
Browse files Browse the repository at this point in the history
Beta6
  • Loading branch information
oyvindberg authored Mar 21, 2020
2 parents fb14f37 + 4f68b59 commit f61c5d8
Show file tree
Hide file tree
Showing 284 changed files with 9,864 additions and 2,562 deletions.
191 changes: 191 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
---
id: changelog
title: Changelog
---

## 1.0.0-beta6

[Full changelog](https://github.com/ScalablyTyped/Converter/compare/v1.0.0-beta5...v1.0.0-beta6)

This is a big release because we finally enable expansion of [type mappings](http://typescript) for most static cases.

Given the following typescript definition:

```typescript
interface Person {
name: string
age: number
favouriteColor: "red" | "blue"
}

declare const patch: (p: Person, pp: Pick<Partial<Person>, "name" | "age">) => Person;

```

We now end up with these Scala.js definitions:
```scala
trait Person extends js.Object {
var age: Double = js.native
var favouriteColor: red | blue = js.native
var name: String = js.native
}

/* Inlined std.Pick<std.Partial<type-mappings.Person>, 'name' | 'age'> */
trait PickPartialPersonnameage extends js.Object {
var age: js.UndefOr[Double] = js.native
var name: js.UndefOr[String] = js.native
}

@JSGlobal("patch")
@js.native
object patch extends js.Object {
def apply(p: Person, pp: PickPartialPersonnameage): Person = js.native
}
```

This functionality is widely used in typescript, so finally enabling this is a big improvement.

Note that the functionality has been enabled for a few
[selected libraries](https://github.com/ScalablyTyped/Converter/pull/123/commits/b5ca33fc89ae5c387190117f6480195bd770174d#diff-dda33cf244aa28da6ffad51bad89b6ee) for quite a while.

Also note that this still has quite a few limitations, in particular it gives up when encountering most conditional types.
This can be improved down the road. This functionality will probably never be available for cases like `Partial<T>`.

### Improved naming scheme for anonymous object types

There has long been a naming scheme in order to name anonymous things like this:
```typescript
declare const foo: (someObject: {foo: number, bar?: string}) => void;
```
```scala
@JSGlobal("foo")
@js.native
object foo extends js.Object {
def apply(someObject: AnonFooBar): Unit = js.native
}
```

Since we suddenly got a lot more anonymous object types because of the expanded type mappings, the scheme needed some improvements.
Generated names like AnonFoo will generally be shorter than before.

### Rewritten tag detection in slinky flavour

For the slinky flavour the generated components receive an element type like `a`, `div`, etc.

This enables the user to supply DOM props with normal Slinky syntax. For instance a component like this
```scala
import slinky.web.html.button.tag
// import ...

object Paper
extends ExternalComponentWithAttributesWithRefType[tag.type, default] {
/* The following DOM/SVG props were specified: className, contentEditable, dangerouslySetInnerHTML, defaultChecked, defaultValue, dir, draggable, height, hidden, id, lang, placeholder, spellCheck, style, suppressContentEditableWarning, tabIndex, title, width */
def apply(about: String = null /*, ... */) = ???
}
```
can be used like this
```scala
Paper(about = "foo")(className := "className")
```

After the rewrite both element detection and props trimming is much more reliable than before.

In particular we used to only check if the actual props matched the name of a prop for the identified element,
now we only trim it if the type is exactly what the given element would accept.

### Improved parser
For better or worse ScalablyTyped has it's own parser.
It received some improvements and is now able to parse 100% of DefinitelyTyped for the first time

### Improved plugin
- Fixed a bug where we compile the same library simultaneously and ended up with corrupt jar files. Fixed by a file-level lock
- Should now be less susceptible to OOM after a usage of a class loader cache was removed.

### Contributors
17 Øyvind Raddum Berg
1 Jocelyn Boullier
1 Lorenzo Gabriele
1 Mushtaq Ahmed

## 1.0.0-beta5
[Full changelog](https://github.com/ScalablyTyped/Converter/compare/v1.0.0-beta4...v1.0.0-beta5)

- Full support for Scala.js 1.0.0
- Redesigned the sbt plugin to use `allDependencies` rather than `unmanagedDependencies`

### Contributors
18 Øyvind Raddum Berg
1 FabioPinheiro

## 1.0.0-beta4
[Full changelog](https://github.com/ScalablyTyped/Converter/compare/v1.0.0-beta3...v1.0.0-beta4)

Rewrote the plugin from just a source generator to compiling all the libraries for you.
For most use cases this is a huge improvement.

### Contributors
8 Øyvind Raddum Berg

## 1.0.0-beta3 and 1.0.0-beta2
Bugfix releases

## 1.0.0-beta1 - Beta release announcement!

It's a great pleasure to finally open source the ScalablyTyped converter
and release the project as an sbt plugin.

You now decide your own Scala version, your own Scala.js version and your own versions of libraries.

All projects built with the plugin will now continue to build forever, as opposed to the old distribution method
where libraries had to be culled every now and then.


## Important changes:

### The [published ScalablyTyped distribution](https://github.com/oyvindberg/ScalablyTyped) is deprecated.

Once you factor in cross builds and flavours it's impossible to keep a useful set of precompiled binaries.

Going forward it'll continue to serve as QA to ensure that we're able to
convert the newest versions of important libraries.

It'll also be updated immediately to the newest available versions, Scala 2.13 and Scala.js 1.0.0 pre-releases.

All usage should be migrated to the new plugin.

### Facades are deprecated
Most usage of facades have been to enable better usage with react.
This is now solved by [flavours](flavour.md) instead.

In particular the react-facade which was widely used in the demos and saw some use outside is now deprecated.

If you want to keep using it feel free to copy it into your own repository (it's MIT licensed).

If we come across anything which is not solved by (potentially writing new) flavours, we can revisit this.

### New naming convention

One of the recognizable features of ScalablyTyped was the rather peculiar naming scheme which served to avoid name collisions.

The final feature which was merged before release was "adaptive naming", which manages the same while generating much nicer looking code.

It typically looked like this:
```scala
import typings.reactDashRouter.reactDashRouterMod.RouteProps
```

After the change, the same import is now
```scala
import typings.reactRouter.mod.RouteProps
```

Everyone migrating to the plugin from the ScalablyTyped distribution will have to rewrite most of their imports.
It should be easy once you see the pattern. Most module names will have lost part of it's prefix, and the top-level
module for each library is now simply called `mod`.

Consult [this commit](https://github.com/ScalablyTyped/SlinkyTypedDemos/commit/e135fc55aeaf53162d9cd472f5cc0bee76bdabe0)
to see what was needed to port the Slinky demos.




Original file line number Diff line number Diff line change
@@ -1,81 +1,9 @@
package org.scalablytyped.converter.internal.importer

import org.scalablytyped.converter.Selection
import org.scalablytyped.converter.internal.ts.{TsIdentLibrary, TsIdentLibraryScoped, TsIdentLibrarySimple}
import org.scalablytyped.converter.internal.ts.TsIdentLibrary

object EnabledTypeMappingExpansion {
val DefaultSelection: Selection[TsIdentLibrary] =
Selection.NoneExcept(
TsIdentLibrary("amap-js-api"),
TsIdentLibrary("antd"),
TsIdentLibrary("instagram-private-api"),
TsIdentLibrary("jest-config"),
TsIdentLibrary("react-autosuggest"),
TsIdentLibrary("react-dropzone"),
TsIdentLibrary("react-native"),
TsIdentLibrary("react-onsenui"),
TsIdentLibrary("react-select"),
TsIdentLibraryScoped("ant-design", "colors"),
TsIdentLibraryScoped("ant-design", "create-react-context"),
TsIdentLibraryScoped("ant-design", "dark-theme"),
TsIdentLibraryScoped("ant-design", "icons"),
TsIdentLibraryScoped("ant-design", "icons-angular"),
TsIdentLibraryScoped("ant-design", "icons-react"),
TsIdentLibraryScoped("ant-design", "icons-react-native"),
TsIdentLibraryScoped("ant-design", "icons-vue"),
TsIdentLibraryScoped("ant-design", "pro-layout"),
TsIdentLibraryScoped("ant-design", "react-native"),
TsIdentLibraryScoped("material-ui", "core"),
TsIdentLibraryScoped("material-ui", "icons"),
TsIdentLibraryScoped("material-ui", "lab"),
TsIdentLibraryScoped("material-ui", "system"),
TsIdentLibraryScoped("material-ui", "utils"),
TsIdentLibraryScoped("nivo", "annotations"),
TsIdentLibraryScoped("nivo", "axes"),
TsIdentLibraryScoped("nivo", "bar"),
TsIdentLibraryScoped("nivo", "bullet"),
TsIdentLibraryScoped("nivo", "calendar"),
TsIdentLibraryScoped("nivo", "chord"),
TsIdentLibraryScoped("nivo", "circle-packing"),
TsIdentLibraryScoped("nivo", "colors"),
TsIdentLibraryScoped("nivo", "core"),
TsIdentLibraryScoped("nivo", "generators"),
TsIdentLibraryScoped("nivo", "geo"),
TsIdentLibraryScoped("nivo", "heatmap"),
TsIdentLibraryScoped("nivo", "legends"),
TsIdentLibraryScoped("nivo", "line"),
TsIdentLibraryScoped("nivo", "parallel-coordinates"),
TsIdentLibraryScoped("nivo", "pie"),
TsIdentLibraryScoped("nivo", "radar"),
TsIdentLibraryScoped("nivo", "sankey"),
TsIdentLibraryScoped("nivo", "scales"),
TsIdentLibraryScoped("nivo", "scatterplot"),
TsIdentLibraryScoped("nivo", "stream"),
TsIdentLibraryScoped("nivo", "sunburst"),
TsIdentLibraryScoped("nivo", "tooltip"),
TsIdentLibraryScoped("nivo", "treemap"),
TsIdentLibraryScoped("nivo", "voronoi"),
TsIdentLibraryScoped("nivo", "waffle"),
TsIdentLibraryScoped("react-navigation", "core"),
TsIdentLibraryScoped("react-navigation", "native"),
TsIdentLibraryScoped("tensorflow", "tfjs"),
TsIdentLibraryScoped("tensorflow", "tfjs-converter"),
TsIdentLibraryScoped("tensorflow", "tfjs-core"),
TsIdentLibraryScoped("tensorflow", "tfjs-data"),
TsIdentLibraryScoped("tensorflow", "tfjs-layers"),
TsIdentLibraryScoped("tensorflow", "tfjs-node"),
TsIdentLibraryScoped("uifabric", "foundation"),
TsIdentLibraryScoped("uifabric", "icons"),
TsIdentLibraryScoped("uifabric", "merge-styles"),
TsIdentLibraryScoped("uifabric", "react-hooks"),
TsIdentLibraryScoped("uifabric", "set-version"),
TsIdentLibraryScoped("uifabric", "styling"),
TsIdentLibraryScoped("uifabric", "utilities"),
TsIdentLibrarySimple("react-navigation"),
TsIdentLibrarySimple("react-navigation-drawer"),
TsIdentLibrarySimple("react-navigation-material-bottom-tabs"),
TsIdentLibrarySimple("react-navigation-stack"),
TsIdentLibrary("@storybook/api"),
TsIdentLibrary("styled-components"),
)
Selection.AllExcept("std", "prop-types", "react").map(TsIdentLibrary.apply)
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ class ImportType(stdNames: QualifiedName.StdNames) {
def c = Comments(Comment.warning(s"Unsupported type mapping: \n${TsTypeFormatter(tpe)}\n"))

scope.stack collectFirst {
case x: TsDeclTypeAlias if x.name === TsIdent.Record =>
TypeRef.StringDictionary(TypeRef(ImportName(x.tparams.head.name)), NoComments)
case x: TsDeclTypeAlias if x.codePath.forceHasPath.codePath === TsQIdent.Std.Record =>
TypeRef.StringDictionary(TypeRef(ImportName(x.tparams(1).name)), NoComments)
case x: TsNamedDecl =>
TypeRef.Intersection(IArray(TypeRef.StringLiteral(x.name.value), base)).withComments(c)
} getOrElse base.withComments(c)
Expand Down Expand Up @@ -205,15 +205,27 @@ class ImportType(stdNames: QualifiedName.StdNames) {
case TsTypeKeyOf(_) =>
TypeRef.String

case TsTypeTuple(StrippedRepeat(targs)) =>
TypeRef(
QualifiedName.Array,
IArray(TypeRef.Union(targs map apply(wildcards.maybeAllow, scope, importName), false)),
NoComments,
)

case TsTypeTuple(targs) =>
TypeRef.Tuple(targs map apply(wildcards.maybeAllow, scope, importName))
targs match {
case IArray.initLast(init, TsTypeRepeated(repeated)) =>
ts.FollowAliases(scope)(repeated) match {
case TsTypeRef(
_,
TsQIdent.Std.Array | TsQIdent.Std.ReadonlyArray | TsQIdent.Array | TsQIdent.ReadonlyArray,
IArray.exactlyOne(elem),
) =>
TypeRef(
importName(TsQIdent.Array),
IArray(apply(wildcards, scope, importName)(TsTypeUnion(init :+ elem))).distinct,
NoComments,
)
case other =>
val c = Comment.warning(s"repeated non-array type: ${TsTypeFormatter(other)}")
TypeRef(importName(TsQIdent.Array), Empty, Comments(c))
}
case nonRepeating =>
TypeRef.Tuple(nonRepeating map apply(wildcards.maybeAllow, scope, importName))
}

case TsTypeRepeated(underlying) =>
TypeRef.Repeated(apply(wildcards, scope, importName)(underlying), NoComments)
Expand All @@ -226,8 +238,8 @@ class ImportType(stdNames: QualifiedName.StdNames) {
TypeRef.Boolean
}

case TsTypeAsserts(ident) =>
TypeRef.Boolean.withComments(Comments(s"/* asserts ${ident.value} */"))
case TsTypeAsserts(ident, isOpt) =>
TypeRef.Boolean.withComments(Comments(s"/* asserts ${ident.value} ${isOpt.fold("")("is " + _)}*/"))

case TsTypeLiteral(lit) =>
lit match {
Expand Down Expand Up @@ -301,17 +313,4 @@ class ImportType(stdNames: QualifiedName.StdNames) {
orAny(wildcards, scope / param, importName)(param.tpe) withOptional param.isOptional withComments Comments(
s"/* ${param.name.value} */",
)

private object StrippedRepeat {
def unapply(types: IArray[TsType]): Option[IArray[TsType]] = {
var found = false
val ret = types.map {
case TsTypeRepeated(x) =>
found = true
x
case other => other
}
if (found) Some(ret) else None
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ object Phase1ReadTypescript {
T.DefaultedTypeArguments.visitTsParsedFile(scope.caching), //after FlattenTrees
T.InlineTrivialParents.visitTsParsedFile(scope.caching), //after FlattenTrees and DefaultedTypeArguments
if (expandTypeMappings(libName)) T.ExpandTypeMappings.visitTsParsedFile(scope.caching) else identity, // before ExtractInterfaces
if (expandTypeMappings(libName)) T.ExpandTypeMappings.After(libName, scope) else identity, // before ExtractInterfaces
if (expandTypeMappings(libName)) T.ExpandTypeMappings.After.visitTsParsedFile(scope.caching) else identity, // before ExtractInterfaces
(
T.SimplifyConditionals >> // after ExpandTypeMappings
T.TypeAliasToConstEnum >>
Expand Down
Loading

0 comments on commit f61c5d8

Please sign in to comment.