diff --git a/src/agent/mod.rs b/src/agent/mod.rs index 9dcd1402..235b7c1f 100644 --- a/src/agent/mod.rs +++ b/src/agent/mod.rs @@ -5608,20 +5608,26 @@ pub(crate) fn global_declaration_instantiation( let lex_names = script.lexically_declared_names(); let var_names = script.var_declared_names(); for name in lex_names { - if env.has_var_declaration(&name) { - return Err(create_syntax_error(format!("{name}: already defined"), None)); - } if env.has_lexical_declaration(&name) { - return Err(create_syntax_error(format!("{name}: already defined"), None)); + return Err(create_syntax_error( + format!("lexical {name}: already defined in existing lexical declarations"), + None, + )); } let has_restricted_global = env.has_restricted_global_property(&name)?; if has_restricted_global { - return Err(create_syntax_error(format!("{name} is restricted and may not be used"), None)); + return Err(create_syntax_error( + format!("{name} is a restricted global property and may not be used as a lexical declaration"), + None, + )); } } for name in var_names { if env.has_lexical_declaration(&name) { - return Err(create_syntax_error(format!("{name}: already defined"), None)); + return Err(create_syntax_error( + format!("var {name}: already defined in existing lexical declarations"), + None, + )); } } let var_declarations = script.var_scoped_declarations(); diff --git a/src/agent/tests.rs b/src/agent/tests.rs index 8baaaef5..6c5e1ff3 100644 --- a/src/agent/tests.rs +++ b/src/agent/tests.rs @@ -1168,10 +1168,10 @@ mod global_declaration_instantiation { use test_case::test_case; #[test_case("var a" => Ok((sset(&["a"]), sset(&[]))); "one simple var-declared variable")] - #[test_case("let already_var_declared;" => serr("SyntaxError: already_var_declared: already defined"); "existing var decl")] - #[test_case("let existing_mutable;" => serr("SyntaxError: existing_mutable: already defined"); "existing lex decl")] - #[test_case("let undefined;" => serr("SyntaxError: undefined is restricted and may not be used"); "restricted global")] - #[test_case("var existing_mutable;" => serr("SyntaxError: existing_mutable: already defined"); "var dups lex")] + #[test_case("let already_var_declared;" => serr("SyntaxError: already_var_declared is a restricted global property and may not be used as a lexical declaration"); "existing var decl")] + #[test_case("let existing_mutable;" => serr("SyntaxError: lexical existing_mutable: already defined in existing lexical declarations"); "existing lex decl")] + #[test_case("let undefined;" => serr("SyntaxError: undefined is a restricted global property and may not be used as a lexical declaration"); "restricted global")] + #[test_case("var existing_mutable;" => serr("SyntaxError: var existing_mutable: already defined in existing lexical declarations"); "var dups lex")] #[test_case("function undefined(){}" => serr("TypeError: Cannot create global function undefined"); "function named undefined")] #[test_case("var a; let b; const c=0; for (var item in object) {}" => Ok((sset(&["a", "item"]), sset(&["b", "c"]))); "many")] #[test_case("class bob{}" => Ok((sset(&[]), sset(&["bob"]))); "a class")] diff --git a/src/environment_record/mod.rs b/src/environment_record/mod.rs index 3d22caaf..c0d7fe39 100644 --- a/src/environment_record/mod.rs +++ b/src/environment_record/mod.rs @@ -1360,19 +1360,6 @@ impl EnvironmentRecord for GlobalEnvironmentRecord { } impl GlobalEnvironmentRecord { - // HasVarDeclaration ( N ) - // - // The HasVarDeclaration concrete method of a global Environment Record envRec takes argument N (a String). It - // determines if the argument identifier has a binding in this record that was created using a VariableStatement or - // a FunctionDeclaration. It performs the following steps when called: - // - // 1. Let varDeclaredNames be envRec.[[VarNames]]. - // 2. If varDeclaredNames contains N, return true. - // 3. Return false. - pub(crate) fn has_var_declaration(&self, name: &JSString) -> bool { - self.var_names.borrow().contains(name) - } - // HasLexicalDeclaration ( N ) // // The HasLexicalDeclaration concrete method of a global Environment Record envRec takes argument N (a String). It diff --git a/src/environment_record/tests.rs b/src/environment_record/tests.rs index 149d1bd3..2bd4a714 100644 --- a/src/environment_record/tests.rs +++ b/src/environment_record/tests.rs @@ -1810,24 +1810,6 @@ mod global_environment_record { assert_eq!(result, ECMAScriptValue::from(this_object)); } - #[test_case("varstyle" => true; "var")] - #[test_case("lexical" => false; "lex")] - fn has_var_declaration(prop_name: &str) -> bool { - // Setup - setup_test_agent(); - let object_prototype = intrinsic(IntrinsicId::ObjectPrototype); - let global_object = ordinary_object_create(Some(object_prototype.clone())); - let this_object = ordinary_object_create(Some(object_prototype)); - let ger = GlobalEnvironmentRecord::new(global_object, this_object, "test"); - let var_name = JSString::from("varstyle"); - ger.create_global_var_binding(var_name, true).unwrap(); - let lex_name = JSString::from("lexical"); - ger.create_mutable_binding(lex_name.clone(), true).unwrap(); - ger.initialize_binding(&lex_name, ECMAScriptValue::Undefined).unwrap(); - - // Exercise - ger.has_var_declaration(&JSString::from(prop_name)) - } #[test_case("varstyle" => false; "var")] #[test_case("lexical" => true; "lex")] fn has_lexical_declaration(prop_name: &str) -> bool {