diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 4 | ||||
-rw-r--r-- | cpp/src/slice2js/Gen.cpp | 267 | ||||
-rw-r--r-- | cpp/src/slice2js/Gen.h | 6 | ||||
-rw-r--r-- | cpp/src/slice2js/JsUtil.cpp | 28 | ||||
-rw-r--r-- | cpp/src/slice2js/Main.cpp | 27 |
5 files changed, 184 insertions, 148 deletions
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index fbe9ff6cf76..b95e0623ce4 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -16,10 +16,6 @@ #include <cstring> #include <iterator> -#ifdef _WIN32 -# include <io.h> -#endif - // TODO: fix this warning once we no longer support VS2013 and earlier #if defined(_MSC_VER) && (_MSC_VER >= 1900) # pragma warning(disable:4589) // Constructor of abstract class 'Slice::Type' ignores initializer... diff --git a/cpp/src/slice2js/Gen.cpp b/cpp/src/slice2js/Gen.cpp index 93d461b9ec7..a59ced63bc9 100644 --- a/cpp/src/slice2js/Gen.cpp +++ b/cpp/src/slice2js/Gen.cpp @@ -633,15 +633,15 @@ Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const st _fileBase = base.substr(pos + 1); } - string file = _fileBase + (typeScript ? ".d.ts" : ".js"); + string file = _fileBase + ".js"; if(!dir.empty()) { file = dir + '/' + file; } - _out.open(file.c_str()); - if(!_out) + _jsout.open(file.c_str()); + if(!_jsout) { ostringstream os; os << "cannot open `" << file << "': " << IceUtilInternal::errorToString(errno); @@ -649,13 +649,30 @@ Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const st } FileTracker::instance()->addFile(file); - printHeader(_out); - printGeneratedHeader(_out, _fileBase + ".ice"); + if(typeScript) + { + file = _fileBase + ".d.ts"; + + if(!dir.empty()) + { + file = dir + '/' + file; + } + + _tsout.open(file.c_str()); + if(!_tsout) + { + ostringstream os; + os << "cannot open `" << file << "': " << IceUtilInternal::errorToString(errno); + throw FileException(__FILE__, __LINE__, os.str()); + } + FileTracker::instance()->addFile(file); + } } Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const string& /*dir*/, bool typeScript, ostream& out) : - _out(out), + _jsout(out), + _tsout(out), _includePaths(includePaths), _useStdout(true), _typeScript(typeScript) @@ -666,49 +683,133 @@ Slice::Gen::Gen(const string& base, const vector<string>& includePaths, const st { _fileBase = base.substr(pos + 1); } - - printHeader(_out); - printGeneratedHeader(_out, _fileBase + ".ice"); } Slice::Gen::~Gen() { - if(_out.isOpen() || _useStdout) + if(_jsout.isOpen() || _useStdout) + { + _jsout << '\n'; + } + + if(_tsout.isOpen() || _useStdout) { - _out << '\n'; + _tsout << '\n'; } } void Slice::Gen::generate(const UnitPtr& p) { + string module; + DefinitionContextPtr dc = p->findDefinitionContext(p->topLevelFile()); + assert(dc); + + { + const string prefix = "js:module:"; + const string m = dc->findMetaData(prefix); + if(!m.empty()) + { + module = m.substr(prefix.size()); + } + } + + if(_useStdout) + { + _jsout << "\n"; + _jsout << "/** slice2js: " << _fileBase << ".js generated begin module:\"" << module << "\" **/"; + _jsout << "\n"; + } + printHeader(_jsout); + printGeneratedHeader(_jsout, _fileBase + ".ice"); + + // + // Check for global "js:module:ice" metadata. If this is set then we are building Ice. // - // Check for "js:module:ice" metadata. If this - // is set then we are building Ice. + bool icejs = module == "ice"; + + // + // Check for global "js:es6-module" metadata. If this is set we are using es6 module mapping // - ModuleList modules = p->modules(); - bool icejs = false; - for(ModuleList::const_iterator i = modules.begin(); i != modules.end(); i++) + bool es6module = dc->findMetaData("js:es6-module") == "js:es6-module"; + + _jsout << nl << "/* eslint-disable */"; + _jsout << nl << "/* jshint ignore: start */"; + _jsout << nl; + + if(!es6module) { - if(p->topLevelFile() == (*i)->definitionContext()->filename() && - getModuleMetadata(ContainedPtr::dynamicCast(*i)) == "ice") + if(icejs) { - icejs = true; - break; + _jsout.zeroIndent(); + _jsout << nl << "/* slice2js browser-bundle-skip */"; + _jsout.restoreIndent(); + } + _jsout << nl << "(function(module, require, exports)"; + _jsout << sb; + if(icejs) + { + _jsout.zeroIndent(); + _jsout << nl << "/* slice2js browser-bundle-skip-end */"; + _jsout.restoreIndent(); } } + RequireVisitor requireVisitor(_jsout, _includePaths, icejs, es6module); + p->visit(&requireVisitor, false); + vector<string> seenModules = requireVisitor.writeRequires(p); + + TypesVisitor typesVisitor(_jsout, seenModules, icejs); + p->visit(&typesVisitor, false); // - // Check for global "js:es6-module" metadata. + // Export the top-level modules. // - DefinitionContextPtr dc = p->findDefinitionContext(p->topLevelFile()); - assert(dc); - StringList globalMetaData = dc->getMetaData(); - bool es6module = find(globalMetaData.begin(), globalMetaData.end(), "js:es6-module") != globalMetaData.end(); + ExportVisitor exportVisitor(_jsout, icejs, es6module); + p->visit(&exportVisitor, false); + + if(!es6module) + { + if(icejs) + { + _jsout.zeroIndent(); + _jsout << nl << "/* slice2js browser-bundle-skip */"; + _jsout.restoreIndent(); + } + + _jsout << eb; + _jsout << nl << "(typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? module : undefined," + << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? require :" + << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self.Ice._require : window.Ice._require," + << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? exports :" + << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self : window));"; + + if(icejs) + { + _jsout.zeroIndent(); + _jsout << nl << "/* slice2js browser-bundle-skip-end */"; + _jsout.restoreIndent(); + } + } + + if(_useStdout) + { + _jsout << "\n"; + _jsout << "/** slice2js: generated end **/"; + _jsout << "\n"; + } if(_typeScript) { - TypeScriptRequireVisitor requireVisitor(_out); + if(_useStdout) + { + _tsout << "\n"; + _tsout << "/** slice2js: " << _fileBase << ".d.ts generated begin module:\"" << module << "\" **/"; + _tsout << "\n"; + } + printHeader(_tsout); + printGeneratedHeader(_tsout, _fileBase + ".ice"); + + TypeScriptRequireVisitor requireVisitor(_tsout, icejs); p->visit(&requireVisitor, false); // @@ -717,71 +818,18 @@ Slice::Gen::generate(const UnitPtr& p) // a type alias when there is an abiguity. // see: https://github.com/Microsoft/TypeScript/issues/983 // - TypeScriptAliasVisitor aliasVisitor(_out); + TypeScriptAliasVisitor aliasVisitor(_tsout); p->visit(&aliasVisitor, false); aliasVisitor.writeAlias(p); - TypeScriptVisitor typeScriptVisitor(_out, requireVisitor.imports()); + TypeScriptVisitor typeScriptVisitor(_tsout, requireVisitor.imports()); p->visit(&typeScriptVisitor, false); - } - else - { - _out << nl << "/* eslint-disable */"; - _out << nl << "/* jshint ignore: start */"; - _out << nl; - - if(!es6module) - { - if(icejs) - { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip */"; - _out.restoreIndent(); - } - _out << nl << "(function(module, require, exports)"; - _out << sb; - if(icejs) - { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip-end */"; - _out.restoreIndent(); - } - } - RequireVisitor requireVisitor(_out, _includePaths, icejs, es6module); - p->visit(&requireVisitor, false); - vector<string> seenModules = requireVisitor.writeRequires(p); - - TypesVisitor typesVisitor(_out, seenModules, icejs); - p->visit(&typesVisitor, false); - // - // Export the top-level modules. - // - ExportVisitor exportVisitor(_out, icejs, es6module); - p->visit(&exportVisitor, false); - - if(!es6module) + if(_useStdout) { - if(icejs) - { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip */"; - _out.restoreIndent(); - } - - _out << eb; - _out << nl << "(typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? module : undefined," - << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? require :" - << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self.Ice._require : window.Ice._require," - << nl << " typeof(global) !== \"undefined\" && typeof(global.process) !== \"undefined\" ? exports :" - << nl << " (typeof WorkerGlobalScope !== \"undefined\" && self instanceof WorkerGlobalScope) ? self : window));"; - - if(icejs) - { - _out.zeroIndent(); - _out << nl << "/* slice2js browser-bundle-skip-end */"; - _out.restoreIndent(); - } + _tsout << "\n"; + _tsout << "/** slice2js: generated end **/"; + _tsout << "\n"; } } } @@ -789,7 +837,15 @@ Slice::Gen::generate(const UnitPtr& p) void Slice::Gen::closeOutput() { - _out.close(); + if(_jsout.isOpen()) + { + _jsout.close(); + } + + if(_tsout.isOpen()) + { + _tsout.close(); + } } Slice::Gen::RequireVisitor::RequireVisitor(IceUtilInternal::Output& out, vector<string> includePaths, @@ -2173,8 +2229,9 @@ Slice::Gen::ExportVisitor::visitModuleStart(const ModulePtr& p) return false; } -Slice::Gen::TypeScriptRequireVisitor::TypeScriptRequireVisitor(IceUtilInternal::Output& out) : +Slice::Gen::TypeScriptRequireVisitor::TypeScriptRequireVisitor(IceUtilInternal::Output& out, bool icejs) : JsVisitor(out), + _icejs(icejs), _nextImport(0) { } @@ -2264,15 +2321,9 @@ Slice::Gen::TypeScriptRequireVisitor::visitModuleStart(const ModulePtr& p) // // Import ice module if not building Ice // - if(UnitPtr::dynamicCast(p->container())) + if(UnitPtr::dynamicCast(p->container()) && !_icejs && _imports.empty()) { - const string prefix = "js:module:"; - string m; - findMetaData(prefix, p->getMetaData(), m); - if(_imports.empty() && m != "ice") - { - _imports.push_back(make_pair("ice", nextImportPrefix())); - } + _imports.push_back(make_pair("ice", nextImportPrefix())); } return true; } @@ -2592,20 +2643,9 @@ Slice::Gen::TypeScriptVisitor::visitModuleStart(const ModulePtr& p) UnitPtr unit = UnitPtr::dynamicCast(p->container()); if(unit) { - string module = getModuleMetadata(ContainedPtr::dynamicCast(p)); - _out << sp; - if(module.empty()) - { - writeImports(); - _out << nl << "export namespace " << fixId(p->name()) << sb; - } - else - { - _out << nl << "declare module \"" << fixId(module) << "\"" << sb; - writeImports(); - _out << nl << "namespace " << fixId(p->name()) << sb; - } + writeImports(); + _out << nl << "export namespace " << fixId(p->name()) << sb; } else { @@ -2615,18 +2655,9 @@ Slice::Gen::TypeScriptVisitor::visitModuleStart(const ModulePtr& p) } void -Slice::Gen::TypeScriptVisitor::visitModuleEnd(const ModulePtr& p) +Slice::Gen::TypeScriptVisitor::visitModuleEnd(const ModulePtr&) { _out << eb; // namespace end - - if(UnitPtr::dynamicCast(p->container())) - { - string module = getModuleMetadata(ContainedPtr::dynamicCast(p)); - if(!module.empty()) - { - _out << eb; // module end - } - } } bool diff --git a/cpp/src/slice2js/Gen.h b/cpp/src/slice2js/Gen.h index bc6a4d132c7..7c588740e39 100644 --- a/cpp/src/slice2js/Gen.h +++ b/cpp/src/slice2js/Gen.h @@ -66,7 +66,8 @@ public: private: - IceUtilInternal::Output _out; + IceUtilInternal::Output _jsout; + IceUtilInternal::Output _tsout; std::vector<std::string> _includePaths; std::string _fileBase; @@ -150,7 +151,7 @@ private: { public: - TypeScriptRequireVisitor(::IceUtilInternal::Output&); + TypeScriptRequireVisitor(::IceUtilInternal::Output&, bool); virtual bool visitModuleStart(const ModulePtr&); virtual bool visitClassDefStart(const ClassDefPtr&); @@ -167,6 +168,7 @@ private: std::string nextImportPrefix(); + bool _icejs; int _nextImport; std::map<std::string, std::string> _modulePrefix; }; diff --git a/cpp/src/slice2js/JsUtil.cpp b/cpp/src/slice2js/JsUtil.cpp index 002919087f0..b368e7f05e6 100644 --- a/cpp/src/slice2js/JsUtil.cpp +++ b/cpp/src/slice2js/JsUtil.cpp @@ -200,32 +200,16 @@ Slice::JsGenerator::getModuleMetadata(const TypePtr& type) } string -Slice::JsGenerator::getModuleMetadata(const ContainedPtr& cont) +Slice::JsGenerator::getModuleMetadata(const ContainedPtr& p) { // - // Traverse to the top-level module. + // Check if the file contains the python:pkgdir global metadata. // - ModulePtr m; - ContainedPtr p = cont; - while (true) - { - if(ModulePtr::dynamicCast(p)) - { - m = ModulePtr::dynamicCast(p); - } - - ContainerPtr c = p->container(); - p = ContainedPtr::dynamicCast(c); // This cast fails for Unit. - if(!p) - { - break; - } - } - + DefinitionContextPtr dc = p->definitionContext(); + assert(dc); const string prefix = "js:module:"; - string value; - findMetaData(prefix, m->getMetaData(), value); - return value; + const string value = dc->findMetaData(prefix); + return value.empty() ? value : value.substr(prefix.size()); } bool diff --git a/cpp/src/slice2js/Main.cpp b/cpp/src/slice2js/Main.cpp index 062abe2083f..d7cd236135f 100644 --- a/cpp/src/slice2js/Main.cpp +++ b/cpp/src/slice2js/Main.cpp @@ -75,7 +75,7 @@ usage(const string& n) "--depend-file FILE Write dependencies to FILE instead of standard output.\n" "--validate Validate command line options.\n" "--stdout Print generated code to stdout.\n" - "--typescript Generate TypeScript declaration file\n" + "--typescript Generate TypeScript declarations.\n" "--depend-json Generate dependency information in JSON format.\n" "--ice Allow reserved Ice prefix in Slice identifiers\n" " deprecated: use instead [[\"ice-prefix\"]] metadata.\n" @@ -249,6 +249,8 @@ compile(const vector<string>& argv) } } + map<string, vector<string> > moduleInfo; + for(vector<string>::const_iterator i = sources.begin(); i != sources.end();) { PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); @@ -273,7 +275,8 @@ compile(const vector<string>& argv) bool last = (++i == sources.end()); if(!icecpp->printMakefileDependencies(os, - depend ? Preprocessor::JavaScript : (dependJSON ? Preprocessor::JavaScriptJSON : Preprocessor::SliceXML), + depend ? Preprocessor::JavaScript : (dependJSON ? Preprocessor::JavaScriptJSON : + Preprocessor::SliceXML), includePaths, "-D__SLICE2JS__")) { @@ -328,6 +331,26 @@ compile(const vector<string>& argv) } else { + DefinitionContextPtr dc = p->findDefinitionContext(p->topLevelFile()); + assert(dc); + const string prefix = "js:module:"; + string m = dc->findMetaData(prefix); + if(!m.empty()) + { + m = m.substr(prefix.size()); + } + + if(moduleInfo.find(m) == moduleInfo.end()) + { + vector<string> files; + files.push_back(*i); + moduleInfo[m] = files; + } + else + { + moduleInfo[m].push_back(*i); + } + try { if(useStdout) |