/** * 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.runtime; import static com.github.anba.es6draft.runtime.types.Undefined.UNDEFINED; import com.github.anba.es6draft.runtime.modules.ModuleRecord; import com.github.anba.es6draft.runtime.modules.SourceTextModuleRecord; /** * <h1>8 Executable Code and Execution Contexts</h1><br> * <h2>8.1 Lexical Environments</h2><br> * <h3>8.1.1 Environment Records</h3> * <ul> * <li>8.1.1.5 Module Environment Records * </ul> */ public final class ModuleEnvironmentRecord extends DeclarativeEnvironmentRecord { private static final class IndirectBinding extends Binding { private final ModuleRecord module; private final String otherName; IndirectBinding(ModuleRecord module, String otherName) { super(false, false, false); this.module = module; this.otherName = otherName; } @Override public Binding clone() { throw new AssertionError(); } @Override public boolean isInitialized() { /* 8.1.1.5.1 GetBindingValue(N,S), steps 3.a-c */ return module.getEnvironment() != null; } @Override public void initialize(Object value) { throw new AssertionError(); } @Override public void setValue(Object value) { throw new AssertionError(); } @Override public Object getValue() { /* 8.1.1.5.1 GetBindingValue(N,S), steps 3.d-e */ return module.getEnvironment().getEnvRec().getBindingValue(otherName, true); } } public ModuleEnvironmentRecord(ExecutionContext cx) { super(cx, false); } // Implicitly defined methods: // 8.1.1.5.1 GetBindingValue(N,S) // 8.1.1.5.2 DeleteBinding (N) /** * 8.1.1.5.3 HasThisBinding () */ @Override public boolean hasThisBinding() { return true; } /** * 8.1.1.5.4 GetThisBinding () */ @Override public Object getThisBinding(ExecutionContext cx) { return UNDEFINED; } /** * 8.1.1.5.5 CreateImportBinding (N, M, N2) * * @param name * the binding name * @param module * the module record * @param otherName * the binding name in the module */ public void createImportBinding(String name, ModuleRecord module, String otherName) { /* step 1 (omitted) */ /* step 2 */ assert !hasBinding(name) : "binding redeclaration: " + name; /* step 3 (not applicable) */ /* step 4 */ assert !module.isInstantiated() || hasDirectBinding(module, otherName); /* step 5 */ createBinding(name, new IndirectBinding(module, otherName)); /* step 6 (return) */ } private static boolean hasDirectBinding(ModuleRecord module, String name) { if (module instanceof SourceTextModuleRecord) { Binding binding = ((SourceTextModuleRecord) module).getEnvironment().getEnvRec().getBinding(name); return binding != null && !(binding instanceof IndirectBinding); } return true; } }