diff --git a/closure/compiler/closure_js_library.bzl b/closure/compiler/closure_js_library.bzl index aedb0f394d..cebc6b5bbd 100644 --- a/closure/compiler/closure_js_library.bzl +++ b/closure/compiler/closure_js_library.bzl @@ -367,12 +367,12 @@ def _closure_js_library_impl( ) def _closure_js_library(ctx): - if not ctx.files.srcs and not ctx.files.externs and not ctx.attr.exports: - fail("Either 'srcs' or 'exports' must be specified") + if not ctx.files.srcs and not ctx.files.externs and not ctx.attr.exports and not ctx.attr.ts_lib: + fail("Either 'srcs', 'exports', or 'ts_lib' must be specified") if not ctx.files.srcs and ctx.attr.deps: fail("'srcs' must be set when using 'deps', otherwise consider 'exports'") - if not ctx.files.srcs and (ctx.attr.suppress or ctx.attr.lenient): - fail("'srcs' must be set when using 'suppress' or 'lenient'") + if not (ctx.files.srcs or ctx.attr.ts_lib) and (ctx.attr.suppress or ctx.attr.lenient): + fail("Either 'srcs' or 'ts_lib' must be set when using 'suppress' or 'lenient'") if ctx.attr.language: print("The closure_js_library 'language' attribute is now removed and " + "is always set to " + JS_LANGUAGE_IN) @@ -383,14 +383,26 @@ def _closure_js_library(ctx): print("closure_js_library 'externs' is deprecated; just use 'srcs'") srcs = ctx.files.externs + srcs + deps = ctx.attr.deps + suppress = ctx.attr.suppress + + # Wrapper around a ts_library. It's like creating a closure_js_library with + # the runtime_deps of the ts_library, and the srcs are the tsickle outputs from + # the ts_library. + if ctx.attr.ts_lib: + srcs = srcs + ctx.attr.ts_lib.typescript.transitive_es6_sources.to_list() + # Note that we need to modify deps before calling unfurl below for exports to work. + deps = deps + ctx.attr.ts_lib.typescript.runtime_deps.to_list() + suppress = suppress + ["checkTypes", "strictCheckTypes", "reportUnknownTypes", "analyzerChecks", "JSC_EXTRA_REQUIRE_WARNING"] + library = _closure_js_library_impl( ctx.actions, ctx.label, ctx.workspace_name, srcs, - ctx.attr.deps, + deps, ctx.attr.testonly, - ctx.attr.suppress, + suppress, ctx.attr.lenient, ctx.files._closure_library_base, ctx.executable._ClosureWorker, @@ -418,7 +430,7 @@ def _closure_js_library(ctx): transitive_files = (depset([] if ctx.attr.no_closure_library else ctx.files._closure_library_base) | collect_runfiles( unfurl( - ctx.attr.deps, + deps+ctx.attr.exports, provider = "closure_js_library", ), ) | @@ -448,6 +460,9 @@ closure_js_library = rule( "srcs": attr.label_list(allow_files = JS_FILE_TYPE), "suppress": attr.string_list(), "lenient": attr.bool(), + "ts_lib": attr.label( + providers = ["typescript"], + ), # deprecated "externs": attr.label_list(allow_files = JS_FILE_TYPE), diff --git a/closure/compiler/test/typescript/BUILD b/closure/compiler/test/typescript/BUILD new file mode 100644 index 0000000000..149a368e8d --- /dev/null +++ b/closure/compiler/test/typescript/BUILD @@ -0,0 +1,101 @@ +# Copyright 2018 The Closure Rules Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package(default_testonly = True) + +licenses(["notice"]) # Apache 2.0 + +load("//closure/private:file_test.bzl", "file_test") +load("//closure:defs.bzl", "closure_js_binary") +load("//closure:defs.bzl", "closure_js_library") +load(":fake_ts_library.bzl", "fake_ts_library") + +fake_ts_library( + name = "a", + srcs = ["a.js"], +) + +fake_ts_library( + name = "b", + srcs = ["b.js"], + deps = [":a"], +) + +closure_js_library( + name = "b_js", + ts_lib = ":b", +) + +closure_js_library( + name = "c", + srcs = ["c.js"], + deps = [":b_js"], +) + +file_test( + name = "c_noWarnings", + content = "", + file = "c-stderr.txt", +) + +file_test( + name = "b_js_noWarnings", + content = "", + file = "b_js-stderr.txt", +) + +closure_js_binary( + name = "c_bin", + entry_points = ["c"], + deps = ["c"], +) + +file_test( + name = "c_bin_noWarnings", + content = "", + file = "c_bin-stderr.txt", +) + +fake_ts_library( + name = "ts_closure", + runtime_deps = ["//closure/library"], +) + +fake_ts_library( + name = "use_closure", + srcs = ["use_closure.js"], + deps = ["ts_closure"], +) + +closure_js_library( + name = "use_closure_js", + ts_lib = "use_closure", +) + +closure_js_binary( + name = "use_closure_bin", + deps = ["use_closure_js"], +) + +file_test( + name = "use_closure_js_noWarnings", + content = "", + file = "use_closure_js-stderr.txt", +) + +file_test( + name = "use_closure_bin_noWarnings", + content = "", + file = "use_closure_bin-stderr.txt", +) diff --git a/closure/compiler/test/typescript/a.js b/closure/compiler/test/typescript/a.js new file mode 100644 index 0000000000..64d6b52697 --- /dev/null +++ b/closure/compiler/test/typescript/a.js @@ -0,0 +1,23 @@ +// Copyright 2016 The Closure Rules Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('a'); + + +/** + * Function A. + */ +a.a = function() { + console.log('a'); +}; diff --git a/closure/compiler/test/typescript/b.js b/closure/compiler/test/typescript/b.js new file mode 100644 index 0000000000..f121b59c9e --- /dev/null +++ b/closure/compiler/test/typescript/b.js @@ -0,0 +1,26 @@ +// Copyright 2016 The Closure Rules Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('b'); + +goog.require('a'); + + +/** + * Function B. + */ +b.b = function() { + a.a(); + console.log('b'); +}; diff --git a/closure/compiler/test/typescript/c.js b/closure/compiler/test/typescript/c.js new file mode 100644 index 0000000000..fb1f5774b8 --- /dev/null +++ b/closure/compiler/test/typescript/c.js @@ -0,0 +1,28 @@ +// Copyright 2016 The Closure Rules Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +goog.provide('c'); + +goog.require('b'); + + +/** + * Function C. + */ +c.c = function() { + b.b(); + console.log('c'); +}; + +goog.exportSymbol('test.c',c.c); \ No newline at end of file diff --git a/closure/compiler/test/typescript/fake_ts_library.bzl b/closure/compiler/test/typescript/fake_ts_library.bzl new file mode 100644 index 0000000000..f8506f3643 --- /dev/null +++ b/closure/compiler/test/typescript/fake_ts_library.bzl @@ -0,0 +1,43 @@ +# Copyright 2018 The Closure Rules Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +def _fake_ts_library(ctx): + return struct(typescript=struct( + es6_sources=depset(ctx.files.srcs), + transitive_es6_sources=depset( + ctx.files.srcs, + transitive=[d.typescript.transitive_es6_sources for d in ctx.attr.deps]), + declarations=depset(), + runtime_deps=depset( + ctx.attr.runtime_deps, + transitive=[d.typescript.runtime_deps for d in ctx.attr.deps]), + ), + internal_expect_failure=ctx.attr.internal_expect_failure) + +fake_ts_library = rule( + attrs = { + "srcs": attr.label_list(allow_files = True), + "deps": attr.label_list(providers = ["typescript"]), + "data": attr.label_list( + default = [], + allow_files = True, + cfg = "data", + ), + "runtime_deps": attr.label_list( + default = [], + ), + "internal_expect_failure": attr.bool(default = False), + }, + implementation = _fake_ts_library, +) diff --git a/closure/compiler/test/typescript/use_closure.js b/closure/compiler/test/typescript/use_closure.js new file mode 100644 index 0000000000..d99faf8ff0 --- /dev/null +++ b/closure/compiler/test/typescript/use_closure.js @@ -0,0 +1,2 @@ +import {TagName} from 'goog:goog.dom'; +console.log(TagName.A); \ No newline at end of file diff --git a/closure/private/defs.bzl b/closure/private/defs.bzl index aee2f5cc25..aa0ec72dcc 100644 --- a/closure/private/defs.bzl +++ b/closure/private/defs.bzl @@ -145,6 +145,9 @@ def collect_runfiles(targets): data += target.data_runfiles.files if hasattr(target, "default_runfiles"): data += target.default_runfiles.files + if hasattr(target, "closure_js_aspect") and hasattr(target, "typescript"): + if hasattr(target.typescript, "transitive_es6_sources"): + data += target.typescript.transitive_es6_sources return data def find_js_module_roots(srcs, workspace_name, label, includes): diff --git a/closure/repositories.bzl b/closure/repositories.bzl index e25c7a8cd7..3dec9facf0 100644 --- a/closure/repositories.bzl +++ b/closure/repositories.bzl @@ -55,6 +55,7 @@ def closure_repositories( omit_com_squareup_javapoet = False, omit_fonts_noto_hinted_deb = False, omit_fonts_noto_mono_deb = False, + omit_io_angular_clutz=False, omit_javax_annotation_jsr250_api = False, omit_javax_inject = False, omit_libexpat_amd64_deb = False, @@ -140,6 +141,8 @@ def closure_repositories( fonts_noto_hinted_deb() if not omit_fonts_noto_mono_deb: fonts_noto_mono_deb() + if not omit_io_angular_clutz: + io_angular_clutz() if not omit_javax_annotation_jsr250_api: javax_annotation_jsr250_api() if not omit_javax_inject: @@ -693,7 +696,7 @@ def com_google_protobuf_js(): ], sha256 = "2244b0308846bb22b4ff0bcc675e99290ff9f1115553ae9671eba1030af31bc0", strip_prefix = "protobuf-3.6.1.2/js", - patches = ["//closure:patch_protobuf.patch"], + patches = ["@io_bazel_rules_closure//closure:patch_protobuf.patch"], patch_args = ["-p1"], build_file = str(Label("//closure/protobuf:protobuf_js.BUILD")), ) @@ -796,6 +799,18 @@ def fonts_noto_mono_deb(): sha256 = "71ff715cf50a74a8cc11b02e7c906b69a242d3d677e739e0b2d18cd23b7de375", ) +def io_angular_clutz(): + http_archive( + name = "io_angular_clutz", + build_file = str(Label("//third_party/clutz:clutz.BUILD")), + sha256 = "7a5c785dbcc3ae0daa1fcf4507de6a23bbecdb2bf80460651e4c2b88c1ad7582", + strip_prefix = "clutz-7f1a3ee9ad9f85a9056084dc039496bbd35e11f6", + urls = [ + "https://mirror.bazel.build/github.com/angular/clutz/archive/7f1a3ee9ad9f85a9056084dc039496bbd35e11f6.tar.gz", # 2017-11-02 + "https://github.com/angular/clutz/archive/7f1a3ee9ad9f85a9056084dc039496bbd35e11f6.tar.gz", + ], + ) + def javax_annotation_jsr250_api(): java_import_external( name = "javax_annotation_jsr250_api", diff --git a/third_party/clutz/BUILD b/third_party/clutz/BUILD new file mode 100644 index 0000000000..b0968f5aa7 --- /dev/null +++ b/third_party/clutz/BUILD @@ -0,0 +1,5 @@ +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # MIT + +exports_files(["clutz.BUILD","externs.js"]) \ No newline at end of file diff --git a/third_party/clutz/clutz.BUILD b/third_party/clutz/clutz.BUILD new file mode 100644 index 0000000000..a925915710 --- /dev/null +++ b/third_party/clutz/clutz.BUILD @@ -0,0 +1,45 @@ +# Description: +# Build tool for making TypeScript .d.ts files from Closure JavaScript. + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # MIT + +exports_files([ + "LICENSE", + "src/resources/closure.lib.d.ts", + "src/resources/partial_goog_base.js", +]) + +JVM_FLAGS = [ + "-Xss20m", # JSCompiler needs big stacks for recursive parsing + "-XX:+UseParallelGC", # Best GC when app isn't latency sensitive +] + +java_binary( + name = "clutz", + srcs = glob(["src/main/java/com/google/javascript/clutz/**/*.java"]), + jvm_flags = JVM_FLAGS, + main_class = "com.google.javascript.clutz.DeclarationGenerator", + deps = [ + "@args4j", + "@com_google_code_findbugs_jsr305", + "@com_google_code_gson", + "@com_google_guava", + "@com_google_javascript_closure_compiler", + ], +) + +java_binary( + name = "gents", + srcs = glob(["src/main/java/com/google/javascript/gents/**/*.java"]), + jvm_flags = JVM_FLAGS, + main_class = "com.google.javascript.gents.TypeScriptGenerator", + deps = [ + "@args4j", + "@com_google_code_findbugs_jsr305", + "@com_google_code_gson", + "@com_google_guava", + "@com_google_javascript_closure_compiler", + ], +) diff --git a/third_party/clutz/externs.js b/third_party/clutz/externs.js new file mode 100644 index 0000000000..4feb06a550 --- /dev/null +++ b/third_party/clutz/externs.js @@ -0,0 +1,8 @@ +/** + * @fileoverview + * @externs needed for incremental clutz. + */ +/** @typedef {{then:?}} */ +var Thenable; +/** @typedef {function(...?):?} */ +var Function; \ No newline at end of file