mirror of
https://github.com/github/codeql.git
synced 2026-01-07 11:40:27 +01:00
Revert "JS: Add support for Closure modules"
This commit is contained in:
@@ -306,7 +306,7 @@ public class ASTExtractor {
|
||||
public V(Platform platform, SourceType sourceType) {
|
||||
this.platform = platform;
|
||||
this.sourceType = sourceType;
|
||||
this.isStrict = sourceType.isStrictMode();
|
||||
this.isStrict = sourceType == SourceType.MODULE;
|
||||
}
|
||||
|
||||
private Label visit(INode child, Label parent, int childIndex) {
|
||||
@@ -546,27 +546,21 @@ public class ASTExtractor {
|
||||
|
||||
isStrict = hasUseStrict(nd.getBody());
|
||||
|
||||
// Add platform-specific globals.
|
||||
scopeManager.addVariables(platform.getPredefinedGlobals());
|
||||
// if we're extracting a Node.js/ES2015 module, introduce module scope
|
||||
if (platform == Platform.NODE) {
|
||||
// add node.js-specific globals
|
||||
scopeManager.addVariables("global", "process", "console", "Buffer");
|
||||
|
||||
// Introduce local scope if there is one.
|
||||
if (sourceType.hasLocalScope()) {
|
||||
Label moduleScopeKey = trapwriter.globalID("module;{" + locationManager.getFileLabel() + "}," + locationManager.getStartLine() + "," + locationManager.getStartColumn());
|
||||
scopeManager.enterScope(3, moduleScopeKey, toplevelLabel);
|
||||
scopeManager.addVariables(sourceType.getPredefinedLocals(platform, locationManager.getSourceFileExtension()));
|
||||
// special variables aren't available in `.mjs` modules
|
||||
if (!".mjs".equals(locationManager.getSourceFileExtension()))
|
||||
scopeManager.addVariables("require", "module", "exports", "__filename", "__dirname", "arguments");
|
||||
trapwriter.addTuple("isModule", toplevelLabel);
|
||||
} else if (sourceType == SourceType.MODULE) {
|
||||
Label moduleScopeKey = trapwriter.globalID("module;{" + locationManager.getFileLabel() + "}," + locationManager.getStartLine() + "," + locationManager.getStartColumn());
|
||||
scopeManager.enterScope(3, moduleScopeKey, toplevelLabel);
|
||||
trapwriter.addTuple("isModule", toplevelLabel);
|
||||
}
|
||||
|
||||
// Emit the specific source type.
|
||||
switch (sourceType) {
|
||||
case CLOSURE_MODULE:
|
||||
trapwriter.addTuple("isClosureModule", toplevelLabel);
|
||||
break;
|
||||
case MODULE:
|
||||
trapwriter.addTuple("isES2015Module", toplevelLabel);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// add all declared global (or module-scoped) names, both non-lexical and lexical
|
||||
@@ -575,8 +569,8 @@ public class ASTExtractor {
|
||||
|
||||
visitAll(nd.getBody(), toplevelLabel);
|
||||
|
||||
// Leave the local scope again.
|
||||
if (sourceType.hasLocalScope())
|
||||
// if we're extracting a Node.js/ES2015 module, leave its scope
|
||||
if (platform == Platform.NODE || sourceType == SourceType.MODULE)
|
||||
scopeManager.leaveScope();
|
||||
|
||||
contextManager.leaveContainer();
|
||||
|
||||
@@ -4,12 +4,7 @@ import java.nio.charset.Charset;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.semmle.js.parser.JcornWrapper;
|
||||
import com.semmle.util.data.StringUtil;
|
||||
import com.semmle.util.exception.UserError;
|
||||
|
||||
@@ -55,75 +50,13 @@ public class ExtractorConfig {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of a source file, which together with the {@link Platform}
|
||||
* determines how the top-level scope of the file behaves, and whether ES2015
|
||||
* module syntax should be allowed.
|
||||
* <p>
|
||||
* Note that the names of these enum members are depended on by {@link Main},
|
||||
* {@link AutoBuild}, and {@link JcornWrapper}.
|
||||
*/
|
||||
public static enum SourceType {
|
||||
/** A script executed in the global scope. */
|
||||
SCRIPT,
|
||||
|
||||
/** An ES2015 module. */
|
||||
MODULE,
|
||||
|
||||
/** A Closure-Library module, defined using `goog.module()`. */
|
||||
CLOSURE_MODULE,
|
||||
|
||||
/** A CommonJS module that is not also an ES2015 module. */
|
||||
COMMONJS_MODULE,
|
||||
|
||||
/** Automatically determined source type. */
|
||||
AUTO;
|
||||
SCRIPT, MODULE, AUTO;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtil.lc(name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this source is executed directly in the global scope,
|
||||
* or false if it has its own local scope.
|
||||
*/
|
||||
public boolean hasLocalScope() {
|
||||
return this != SCRIPT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this source is implicitly in strict mode.
|
||||
*/
|
||||
public boolean isStrictMode() {
|
||||
return this == MODULE;
|
||||
}
|
||||
|
||||
private static final Set<String> closureLocals = Collections.singleton("exports");
|
||||
private static final Set<String> commonJsLocals = new LinkedHashSet<>(Arrays.asList("require", "module", "exports", "__filename", "__dirname", "arguments"));
|
||||
|
||||
/**
|
||||
* Returns the set of local variables in scope at the top-level of this module.
|
||||
* <p/>
|
||||
* If this source type has no local scope, the empty set is returned.
|
||||
*/
|
||||
public Set<String> getPredefinedLocals(Platform platform, String extension) {
|
||||
switch (this) {
|
||||
case CLOSURE_MODULE:
|
||||
return closureLocals;
|
||||
case COMMONJS_MODULE:
|
||||
return commonJsLocals;
|
||||
case MODULE:
|
||||
if (platform == Platform.NODE && !extension.equals(".mjs")) {
|
||||
// An ES2015 module that is compiled to a Node.js module effectively has the locals
|
||||
// from Node.js even if they are not part of the ES2015 standard.
|
||||
return commonJsLocals;
|
||||
}
|
||||
return Collections.emptySet();
|
||||
default:
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static enum Platform {
|
||||
@@ -133,15 +66,6 @@ public class ExtractorConfig {
|
||||
public String toString() {
|
||||
return StringUtil.lc(name());
|
||||
}
|
||||
|
||||
private static final Set<String> nodejsGlobals = new LinkedHashSet<>(Arrays.asList("global", "process", "console", "Buffer"));
|
||||
|
||||
/**
|
||||
* Gets the set of predefined globals for this platform.
|
||||
*/
|
||||
public Set<String> getPredefinedGlobals() {
|
||||
return this == NODE ? nodejsGlobals : Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,8 +29,8 @@ public class JSExtractor {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
// heuristic: if `import`, `export`, or `goog.module` appears at the beginning of a line, it's probably a module
|
||||
private static final Pattern containsModuleIndicator = Pattern.compile("(?m)^([ \t]*)(import|export|goog\\.module)\\b");
|
||||
// heuristic: if `import` or `export` appears at the beginning of a line, it's probably a module
|
||||
private static final Pattern containsImportOrExport = Pattern.compile("(?m)^([ \t]*)(import|export)\\b");
|
||||
|
||||
public Pair<Label, LoCInfo> extract(TextualExtractor textualExtractor, String source, int toplevelKind, ScopeManager scopeManager) throws ParseError {
|
||||
// if the file starts with `{ "<string>":` it won't parse as JavaScript; try parsing as JSON instead
|
||||
@@ -69,10 +69,9 @@ public class JSExtractor {
|
||||
if (sourceType != SourceType.AUTO)
|
||||
return sourceType;
|
||||
if (config.getEcmaVersion().compareTo(ECMAVersion.ECMA2015) >= 0) {
|
||||
Matcher m = containsModuleIndicator.matcher(source);
|
||||
if (m.find() && (allowLeadingWS || m.group(1).isEmpty())) {
|
||||
return m.group(2).startsWith("goog") ? SourceType.CLOSURE_MODULE : SourceType.MODULE;
|
||||
}
|
||||
Matcher m = containsImportOrExport.matcher(source);
|
||||
if (m.find() && (allowLeadingWS || m.group(1).isEmpty()))
|
||||
return SourceType.MODULE;
|
||||
}
|
||||
return SourceType.SCRIPT;
|
||||
}
|
||||
@@ -90,9 +89,6 @@ public class JSExtractor {
|
||||
LoCInfo loc;
|
||||
if (ast != null) {
|
||||
platform = getPlatform(platform, ast);
|
||||
if (sourceType == SourceType.SCRIPT && platform == Platform.NODE) {
|
||||
sourceType = SourceType.COMMONJS_MODULE;
|
||||
}
|
||||
|
||||
lexicalExtractor = new LexicalExtractor(textualExtractor, parserRes.getTokens(), parserRes.getComments());
|
||||
ASTExtractor scriptExtractor = new ASTExtractor(lexicalExtractor, scopeManager);
|
||||
@@ -129,7 +125,7 @@ public class JSExtractor {
|
||||
|
||||
if (config.isExterns())
|
||||
textualExtractor.getTrapwriter().addTuple("isExterns", toplevelLabel);
|
||||
if (platform == Platform.NODE && sourceType == SourceType.COMMONJS_MODULE)
|
||||
if (platform == Platform.NODE && sourceType != SourceType.MODULE)
|
||||
textualExtractor.getTrapwriter().addTuple("isNodejs", toplevelLabel);
|
||||
|
||||
return Pair.make(toplevelLabel, loc);
|
||||
|
||||
@@ -41,7 +41,7 @@ public class Main {
|
||||
* such a way that it may produce different tuples for the same file under the same
|
||||
* {@link ExtractorConfig}.
|
||||
*/
|
||||
public static final String EXTRACTOR_VERSION = "2019-02-04";
|
||||
public static final String EXTRACTOR_VERSION = "2019-01-29";
|
||||
|
||||
public static final Pattern NEWLINE = Pattern.compile("\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user