From 366019216f1c14a8dccc56514b62ade82b96861c Mon Sep 17 00:00:00 2001 From: Ryan Brown Date: Fri, 7 Dec 2018 19:03:58 +0000 Subject: [PATCH 1/2] Interoperate with rules_typescript --- closure/compiler/closure_js_library.bzl | 22 +++- closure/compiler/test/typescript/BUILD | 101 ++++++++++++++++++ closure/compiler/test/typescript/a.js | 23 ++++ closure/compiler/test/typescript/b.js | 26 +++++ closure/compiler/test/typescript/c.js | 28 +++++ .../test/typescript/fake_ts_library.bzl | 43 ++++++++ .../compiler/test/typescript/use_closure.js | 2 + closure/private/defs.bzl | 3 + closure/repositories.bzl | 15 +++ third_party/clutz/BUILD | 5 + third_party/clutz/clutz.BUILD | 45 ++++++++ third_party/clutz/externs.js | 8 ++ 12 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 closure/compiler/test/typescript/BUILD create mode 100644 closure/compiler/test/typescript/a.js create mode 100644 closure/compiler/test/typescript/b.js create mode 100644 closure/compiler/test/typescript/c.js create mode 100644 closure/compiler/test/typescript/fake_ts_library.bzl create mode 100644 closure/compiler/test/typescript/use_closure.js create mode 100644 third_party/clutz/BUILD create mode 100644 third_party/clutz/clutz.BUILD create mode 100644 third_party/clutz/externs.js diff --git a/closure/compiler/closure_js_library.bzl b/closure/compiler/closure_js_library.bzl index a463d5acf1..fa23204cec 100644 --- a/closure/compiler/closure_js_library.bzl +++ b/closure/compiler/closure_js_library.bzl @@ -49,6 +49,7 @@ def closure_js_library_impl( convention='CLOSURE', no_closure_library=False, internal_expect_failure=False, + ts_lib=None, # These file definitions for our outputs are deprecated, # and will be replaced with |actions.declare_file()| soon. @@ -81,6 +82,15 @@ def closure_js_library_impl( ijs_file = _maybe_declare_file( actions, deprecated_ijs_file, '%s.i.js' % label.name) + # 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 ts_lib: + srcs = srcs + 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 + ts_lib.typescript.runtime_deps.to_list() + suppress = suppress + ["checkTypes", "reportUnknownTypes", "analyzerChecks", "JSC_EXTRA_REQUIRE_WARNING"] + # Create a list of direct children of this rule. If any direct dependencies # have the exports attribute, those labels become direct dependencies here. deps = unfurl(deps, provider="closure_js_library") @@ -283,12 +293,12 @@ def closure_js_library_impl( has_closure_library=js.has_closure_library)) 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) @@ -313,6 +323,7 @@ def _closure_js_library(ctx): ctx.attr.convention, ctx.attr.no_closure_library, ctx.attr.internal_expect_failure, + ctx.attr.ts_lib, # Deprecated output files. ctx.outputs.info, ctx.outputs.stderr, @@ -352,6 +363,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 1d1e322117..c1d8ce86d3 100644 --- a/closure/private/defs.bzl +++ b/closure/private/defs.bzl @@ -131,6 +131,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 9b84a72b4a..e5686624cd 100644 --- a/closure/repositories.bzl +++ b/closure/repositories.bzl @@ -53,6 +53,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, @@ -136,6 +137,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: @@ -776,6 +779,18 @@ def fonts_noto_mono_deb(): sha256 = "71ff715cf50a74a8cc11b02e7c906b69a242d3d677e739e0b2d18cd23b7de375", ) +def io_angular_clutz(): + native.new_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 From 73fe70fe852a667bf2baf91427ff258aaba11fe6 Mon Sep 17 00:00:00 2001 From: Ryan Brown Date: Tue, 11 Dec 2018 05:07:24 +0000 Subject: [PATCH 2/2] Fix runfiles. --- closure/compiler/closure_js_library.bzl | 29 +++++++++++++------------ closure/repositories.bzl | 4 ++-- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/closure/compiler/closure_js_library.bzl b/closure/compiler/closure_js_library.bzl index 59973ce0ec..cebc6b5bbd 100644 --- a/closure/compiler/closure_js_library.bzl +++ b/closure/compiler/closure_js_library.bzl @@ -108,7 +108,6 @@ def _closure_js_library_impl( convention = "CLOSURE", no_closure_library = False, internal_expect_failure = False, - ts_lib=None, # These file definitions for our outputs are deprecated, # and will be replaced with |actions.declare_file()| soon. @@ -150,15 +149,6 @@ def _closure_js_library_impl( "%s.i.js" % label.name, ) - # 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 ts_lib: - srcs = srcs + 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 + ts_lib.typescript.runtime_deps.to_list() - suppress = suppress + ["checkTypes", "reportUnknownTypes", "analyzerChecks", "JSC_EXTRA_REQUIRE_WARNING"] - # Create a list of direct children of this rule. If any direct dependencies # have the exports attribute, those labels become direct dependencies here. deps = unfurl(deps, provider = "closure_js_library") @@ -393,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, @@ -410,7 +412,6 @@ def _closure_js_library(ctx): ctx.attr.convention, ctx.attr.no_closure_library, ctx.attr.internal_expect_failure, - ctx.attr.ts_lib, # Deprecated output files. ctx.outputs.info, @@ -429,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", ), ) | diff --git a/closure/repositories.bzl b/closure/repositories.bzl index ebb5a51efa..3dec9facf0 100644 --- a/closure/repositories.bzl +++ b/closure/repositories.bzl @@ -696,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")), ) @@ -800,7 +800,7 @@ def fonts_noto_mono_deb(): ) def io_angular_clutz(): - native.new_http_archive( + http_archive( name = "io_angular_clutz", build_file = str(Label("//third_party/clutz:clutz.BUILD")), sha256 = "7a5c785dbcc3ae0daa1fcf4507de6a23bbecdb2bf80460651e4c2b88c1ad7582",