summaryrefslogtreecommitdiff
path: root/cpp/src/slice2js
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/slice2js')
-rw-r--r--cpp/src/slice2js/Gen.cpp267
-rw-r--r--cpp/src/slice2js/Gen.h6
-rw-r--r--cpp/src/slice2js/JsUtil.cpp28
-rw-r--r--cpp/src/slice2js/Main.cpp27
4 files changed, 184 insertions, 144 deletions
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)