瀏覽代碼

Feat: add import-style=commonjs_strict option to the compiler

Peter Marton 7 年之前
父節點
當前提交
1062d985b9
共有 3 個文件被更改,包括 33 次插入10 次删除
  1. 1 0
      js/README.md
  2. 27 6
      src/google/protobuf/compiler/js/js_generator.cc
  3. 5 4
      src/google/protobuf/compiler/js/js_generator.h

+ 1 - 0
js/README.md

@@ -144,6 +144,7 @@ Some examples:
   The `import_style` option is left to the default, which is `closure`.
   The `import_style` option is left to the default, which is `closure`.
 - `--js_out=import_style=commonjs,binary:protos`: this contains the options
 - `--js_out=import_style=commonjs,binary:protos`: this contains the options
   `import_style=commonjs` and `binary` and outputs to the directory `protos`.
   `import_style=commonjs` and `binary` and outputs to the directory `protos`.
+  `import_style=commonjs_strict` doesn't expose the output on the global scope.
 
 
 API
 API
 ===
 ===

+ 27 - 6
src/google/protobuf/compiler/js/js_generator.cc

@@ -276,7 +276,8 @@ string GetEnumPath(const GeneratorOptions& options,
 string MaybeCrossFileRef(const GeneratorOptions& options,
 string MaybeCrossFileRef(const GeneratorOptions& options,
                          const FileDescriptor* from_file,
                          const FileDescriptor* from_file,
                          const Descriptor* to_message) {
                          const Descriptor* to_message) {
-  if (options.import_style == GeneratorOptions::kImportCommonJs &&
+  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+       options.import_style == GeneratorOptions::kImportCommonJsStrict) &&
       from_file != to_message->file()) {
       from_file != to_message->file()) {
     // Cross-file ref in CommonJS needs to use the module alias instead of
     // Cross-file ref in CommonJS needs to use the module alias instead of
     // the global name.
     // the global name.
@@ -1675,8 +1676,18 @@ void Generator::GenerateProvides(const GeneratorOptions& options,
       //
       //
       //   // Later generated code expects foo.bar = {} to exist:
       //   // Later generated code expects foo.bar = {} to exist:
       //   foo.bar.Baz = function() { /* ... */ }
       //   foo.bar.Baz = function() { /* ... */ }
-      printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
-                     *it);
+
+      // Do not use global scope in strict mode
+      if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+        string namespaceObject = *it;
+        // Remove "proto." from the namespace object
+        namespaceObject.erase(0, 6);
+        printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name",
+                namespaceObject);
+      } else {
+        printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
+                *it);
+      }
     }
     }
   }
   }
 }
 }
@@ -3321,6 +3332,8 @@ bool GeneratorOptions::ParseFromOptions(
         import_style = kImportClosure;
         import_style = kImportClosure;
       } else if (options[i].second == "commonjs") {
       } else if (options[i].second == "commonjs") {
         import_style = kImportCommonJs;
         import_style = kImportCommonJs;
+      } else if (options[i].second == "commonjs_strict") {
+        import_style = kImportCommonJsStrict;
       } else if (options[i].second == "browser") {
       } else if (options[i].second == "browser") {
         import_style = kImportBrowser;
         import_style = kImportBrowser;
       } else if (options[i].second == "es6") {
       } else if (options[i].second == "es6") {
@@ -3430,10 +3443,17 @@ void Generator::GenerateFile(const GeneratorOptions& options,
   GenerateHeader(options, printer);
   GenerateHeader(options, printer);
 
 
   // Generate "require" statements.
   // Generate "require" statements.
-  if (options.import_style == GeneratorOptions::kImportCommonJs) {
+  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+       options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
     printer->Print("var jspb = require('google-protobuf');\n");
     printer->Print("var jspb = require('google-protobuf');\n");
     printer->Print("var goog = jspb;\n");
     printer->Print("var goog = jspb;\n");
-    printer->Print("var global = Function('return this')();\n\n");
+
+    // Do not use global scope in strict mode
+    if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+      printer->Print("var proto = {};\n\n");
+    } else {
+      printer->Print("var global = Function('return this')();\n\n");
+    }
 
 
     for (int i = 0; i < file->dependency_count(); i++) {
     for (int i = 0; i < file->dependency_count(); i++) {
       const string& name = file->dependency(i)->name();
       const string& name = file->dependency(i)->name();
@@ -3477,7 +3497,8 @@ void Generator::GenerateFile(const GeneratorOptions& options,
     GenerateExtension(options, printer, *it);
     GenerateExtension(options, printer, *it);
   }
   }
 
 
-  if (options.import_style == GeneratorOptions::kImportCommonJs) {
+  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+       options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
     printer->Print("goog.object.extend(exports, $package$);\n",
     printer->Print("goog.object.extend(exports, $package$);\n",
                    "package", GetFilePath(options, file));
                    "package", GetFilePath(options, file));
   }
   }

+ 5 - 4
src/google/protobuf/compiler/js/js_generator.h

@@ -63,10 +63,11 @@ struct GeneratorOptions {
   bool binary;
   bool binary;
   // What style of imports should be used.
   // What style of imports should be used.
   enum ImportStyle {
   enum ImportStyle {
-    kImportClosure,   // goog.require()
-    kImportCommonJs,  // require()
-    kImportBrowser,   // no import statements
-    kImportEs6,       // import { member } from ''
+    kImportClosure,         // goog.require()
+    kImportCommonJs,        // require()
+    kImportCommonJsStrict,  // require() with no global export
+    kImportBrowser,         // no import statements
+    kImportEs6,             // import { member } from ''
   } import_style;
   } import_style;
 
 
   GeneratorOptions()
   GeneratorOptions()