Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation missing default language_in and language_out modes #3679

Open
juj opened this issue Sep 9, 2020 · 3 comments
Open

Documentation missing default language_in and language_out modes #3679

juj opened this issue Sep 9, 2020 · 3 comments
Labels
feat Feature Request

Comments

@juj
Copy link

juj commented Sep 9, 2020

In wiki page https://github.com/google/closure-compiler/wiki/Flags-and-Options, the docs

--language_in VAL
Sets the language spec to which input sources should conform. Options: ECMASCRIPT3, ECMASCRIPT5, ECMASCRIPT5_STRICT, ECMASCRIPT6_TYPED (experimental), ECMASCRIPT_2015, ECMASCRIPT_2016, ECMASCRIPT_2017, ECMASCRIPT_2018, ECMASCRIPT_2019, STABLE, ECMASCRIPT_NEXT

--language_out VAL
Sets the language spec to which output should conform. Options: ECMASCRIPT3, ECMASCRIPT5, ECMASCRIPT5_STRICT, ECMASCRIPT_2015, ECMASCRIPT_2016, ECMASCRIPT_2017, ECMASCRIPT_2018, ECMASCRIPT_2019, STABLE

do not say what are the default options for these settings. That would be good to add?

Also, it would be good to describe the behavior of what happens if one passes only one of --language_in, or --language_out, but not the other? (e.g. does --language_in ECMASCRIPT_2018 without an explicitly specified --language_out directive imply --language_out ECMASCRIPT_2018? Or does e.g. --language_out ECMASCRIPT_2018 without an explicitly specified --language_in directive imply --language_in ECMASCRIPT_2018?)

@juj
Copy link
Author

juj commented Sep 9, 2020

Also it seems that there is an option --language_out NO_TRANSPILE, but that is not documented in the list?

Also, related question I have is:

If one specifies --language_in ECMASCRIPT_2018, can/will Closure emit ES2018 constructs of its own (during the minification process) to the build output? How about if --language_in ECMASCRIPT_2018 --language_out NO_TRANSPILE is passed?

What I would like to achieve is to enable the source code that I am minifying to (possibly) contain ES 2018 constructs, but have Closure not emit any ES 2018 constructs by itself during minification process, but only emit ES5 constructs.

In other words, is there a set of --language_in and --language_out flags, such that, given an input file that is either ECMASCRIPT_2018 or ES5 (at the time of invocation it is unknown which):

  • if the input file is ECMASCRIPT_2018, Closure should not do any transpiling on it (can keep output as ECMASCRIPT_2018),
  • if the input file is ES5, the output file should also be ES5.

The motivation for this comes from providing a set of default flags for Emscripten compiler's Closure operation.

@brad4d
Copy link
Contributor

brad4d commented Sep 10, 2020

I'll try to answer your questions here, then maybe use this to update the docs.

The default value for --language_in is STABLE.
The default value for --language_out is whatever --language_in is.

What STABLE means depends on whether it's used for --language_in or --language_out.
In general for input it means the highest level of the released ES spec we currently support.
For output it means the lowest level of ES spec we think it's reasonable for an application to be still trying to support.

At the moment STABLE means:

--language_in --language_out
ES_2019 ES5_STRICT

We promise not to output any language features higher than --language_out, but that doesn't mean we promise we'll never upgrade input code to use newer language features.

For historical and ease-of-maintenance reasons we rarely ever output newer language features than those that originally appeared in the input, but there are some cases where we do.

We'll likely do it more in the future, since newer language features often also allow us to output less code.

So, no, there's no combination of options that would guarantee not to add newer features without also transpiling away those features if they appear in the input.

@brad4d brad4d added the feat Feature Request label Sep 10, 2020
@brad4d
Copy link
Contributor

brad4d commented Sep 10, 2020

Logic for interpreting the command line options is here.

if (!flags.languageIn.isEmpty()) {
CompilerOptions.LanguageMode languageMode =
CompilerOptions.LanguageMode.fromString(flags.languageIn);
if (languageMode == LanguageMode.UNSUPPORTED) {
throw new FlagUsageException(
"Cannot specify the unsupported set of features for language_in.");
}
if (languageMode != null) {
options.setLanguageIn(languageMode);
} else {
throw new FlagUsageException("Unknown language `" + flags.languageIn + "' specified.");
}
}
if (flags.languageOut.isEmpty()) {
options.setLanguageOut(options.getLanguageIn());
} else {
CompilerOptions.LanguageMode languageMode =
CompilerOptions.LanguageMode.fromString(flags.languageOut);
if (languageMode == LanguageMode.UNSUPPORTED) {
throw new FlagUsageException(
"Cannot specify the unsupported set of features for language_out.");
}
if (languageMode != null) {
options.setLanguageOut(languageMode);
} else {
throw new FlagUsageException("Unknown language `" + flags.languageOut + "' specified.");
}
}

Oh, also, NO_TRANSPILE is only valid for --language_out

public void setLanguageIn(LanguageMode languageIn) {
checkState(languageIn != LanguageMode.NO_TRANSPILE);
this.languageIn = languageIn == LanguageMode.STABLE ? LanguageMode.STABLE_IN : languageIn;
}

and means the same thing as not specifying --language_out at all.

public void setLanguageOut(LanguageMode languageOut) {
if (languageOut == LanguageMode.NO_TRANSPILE) {
languageOutIsDefaultStrict = Optional.absent();
outputFeatureSet = Optional.absent();
} else {
languageOut = languageOut == LanguageMode.STABLE ? LanguageMode.STABLE_OUT : languageOut;
languageOutIsDefaultStrict = Optional.of(languageOut.isDefaultStrict());
setOutputFeatureSet(languageOut.toFeatureSet());
}
}

Which looks really suspiciously like NO_TRANSPILE, means no output features until you look at the implementation of getOutputFeatureSet()

public FeatureSet getOutputFeatureSet() {
if (outputFeatureSet.isPresent()) {
return outputFeatureSet.get();
}
// Backwards compatibility for those that predate language out.
return languageIn.toFeatureSet();
}

It seems likely that some cleanup could be done here. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat Feature Request
Projects
None yet
Development

No branches or pull requests

2 participants