/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.repl.loader; import java.io.IOException; import java.util.Map; import java.util.Set; import com.github.anba.es6draft.ast.scope.ModuleScope; import com.github.anba.es6draft.ast.scope.Name; import com.github.anba.es6draft.compiler.CompilationException; import com.github.anba.es6draft.parser.ParserException; import com.github.anba.es6draft.runtime.LexicalEnvironment; import com.github.anba.es6draft.runtime.ModuleEnvironmentRecord; import com.github.anba.es6draft.runtime.Realm; import com.github.anba.es6draft.runtime.internal.ScriptLoader; import com.github.anba.es6draft.runtime.modules.MalformedNameException; import com.github.anba.es6draft.runtime.modules.ModuleExport; import com.github.anba.es6draft.runtime.modules.ModuleRecord; import com.github.anba.es6draft.runtime.modules.ModuleSource; import com.github.anba.es6draft.runtime.modules.ResolutionException; import com.github.anba.es6draft.runtime.modules.SourceIdentifier; import com.github.anba.es6draft.runtime.modules.SourceTextModuleRecord; import com.github.anba.es6draft.runtime.types.ScriptObject; /** * Wraps a source text module record to provide an implicit "require" binding. */ public final class NodeSourceTextModuleRecord implements ModuleRecord, Cloneable { private final SourceTextModuleRecord module; public NodeSourceTextModuleRecord(SourceTextModuleRecord module) { this.module = module; } @Override public NodeSourceTextModuleRecord clone() { return new NodeSourceTextModuleRecord(module.clone()); } public void setRealm(Realm realm) { module.setRealm(realm); } public Set<String> getRequestedModules() { return module.getRequestedModules(); } @Override public SourceIdentifier getSourceCodeId() { return module.getSourceCodeId(); } @Override public Realm getRealm() { return module.getRealm(); } @Override public LexicalEnvironment<ModuleEnvironmentRecord> getEnvironment() { return module.getEnvironment(); } @Override public ScriptObject getNamespace() { return module.getNamespace(); } @Override public void setNamespace(ScriptObject namespace) { module.setNamespace(namespace); } @Override public boolean isEvaluated() { return module.isEvaluated(); } @Override public boolean isInstantiated() { return module.isInstantiated(); } @Override public Set<String> getExportedNames(Set<ModuleRecord> exportStarSet) throws IOException, MalformedNameException, ResolutionException { return module.getExportedNames(exportStarSet); } @Override public ModuleExport resolveExport(String exportName, Map<ModuleRecord, Set<String>> resolveSet, Set<ModuleRecord> exportStarSet) throws IOException, MalformedNameException, ResolutionException { return module.resolveExport(exportName, resolveSet, exportStarSet); } @Override public void instantiate() throws IOException, MalformedNameException, ResolutionException { boolean isInstantiated = module.isInstantiated(); module.instantiate(); // Add "require" function when module is instantiated. if (!isInstantiated && module.isInstantiated()) { ModuleEnvironmentRecord envRec = module.getEnvironment().getEnvRec(); if (!envRec.hasBinding("require")) { envRec.createImmutableBinding("require", true); envRec.initializeBinding("require", NodeFunctions.createRequireFunction(this)); } } } @Override public Object evaluate() throws IOException, MalformedNameException, ResolutionException { return module.evaluate(); } /** * ParseModule ( sourceText ) * * @param scriptLoader * the script loader * @param sourceCodeId * the source code identifier * @param source * the module source code * @return the parsed module record * @throws IOException * if there was any I/O error * @throws ParserException * if the module source contains any syntax errors * @throws CompilationException * if the parsed module source cannot be compiled */ public static NodeSourceTextModuleRecord ParseModule(ScriptLoader scriptLoader, SourceIdentifier sourceCodeId, ModuleSource source) throws IOException, ParserException, CompilationException { // Add an implicit "require" binding to the lexical environment of the module. com.github.anba.es6draft.ast.Module parsedBody = scriptLoader.parseModule(source.toSource(), source.sourceCode()); ModuleScope moduleScope = parsedBody.getScope(); if (!moduleScope.isDeclared(new Name("require"))) { moduleScope.addImplicitBinding(new Name("require")); } SourceTextModuleRecord sourceText = SourceTextModuleRecord.ParseModule(scriptLoader, sourceCodeId, parsedBody); return new NodeSourceTextModuleRecord(sourceText); } }