public override bool IsEquivalentTo(AstNode otherNode) { // EVERYTHING referenced in the other node needs to be represented // in the bindings of this node. This node can have MORE, though; that's okay. var everythingRepresented = true; var theseBindings = BindingsVisitor.Bindings(this.Binding); foreach (var reference in BindingsVisitor.References(otherNode)) { var foundOne = false; foreach (var bindingIdentifier in theseBindings) { if (bindingIdentifier.IsEquivalentTo(reference)) { foundOne = true; break; } } if (!foundOne) { everythingRepresented = false; break; } } return(everythingRepresented); }
void DefineParameters() { var functionObject = (FunctionObject)Owner; if (functionObject.ParameterDeclarations != null) { // for each parameter... foreach (ParameterDeclaration parameter in functionObject.ParameterDeclarations) { foreach (var nameDeclaration in BindingsVisitor.Bindings(parameter.Binding)) { // see if it's already defined var argumentField = this[nameDeclaration.Name]; if (argumentField == null) { // not already defined -- create a field now argumentField = new JSVariableField(FieldType.Argument, nameDeclaration.Name, 0, null) { Position = parameter.Position, OriginalContext = parameter.Context, CanCrunch = !nameDeclaration.RenameNotAllowed }; this.AddField(argumentField); } // make the parameter reference the field and the field reference // the parameter as its declaration nameDeclaration.VariableField = argumentField; argumentField.Declarations.Add(nameDeclaration); } } } }
public bool Contains(string name) { if (!name.IsNullOrWhiteSpace()) { // look at each vardecl in our list foreach (var varDecl in m_list) { foreach (var nameDeclaration in BindingsVisitor.Bindings(varDecl)) { // if it matches the target name exactly... if (string.CompareOrdinal(name, nameDeclaration.Name) == 0) { // ...we found a match return(true); } } } } // if we get here, we didn't find any matches return(false); }
private void ProcessScope(ActivationObject scope) { switch (scope.ScopeType) { case ScopeType.Block: case ScopeType.Lexical: case ScopeType.None: // must be generic block scope m_writer.WriteStartElement("block"); if (scope.UseStrict) { m_writer.WriteAttributeString("strict", "true"); } break; case ScopeType.Class: m_writer.WriteStartElement("class"); if (!scope.ScopeName.IsNullOrWhiteSpace()) { m_writer.WriteAttributeString("src", scope.ScopeName); } if (scope.UseStrict) { m_writer.WriteAttributeString("strict", "true"); } break; case ScopeType.Catch: var catchScope = (CatchScope)scope; m_writer.WriteStartElement("catch"); if (scope.UseStrict) { m_writer.WriteAttributeString("strict", "true"); } foreach (var bindingIdentifier in BindingsVisitor.Bindings(catchScope.CatchParameter)) { m_writer.WriteStartElement("catchvar"); m_writer.WriteAttributeString("src", bindingIdentifier.Name); OutputContextPosition(bindingIdentifier.Context); var catchVariable = bindingIdentifier.VariableField; if (catchVariable != null) { if (catchVariable.CrunchedName != null) { m_writer.WriteAttributeString("min", catchVariable.CrunchedName); } if (m_useReferenceCounts) { m_writer.WriteAttributeString("refcount", catchVariable.RefCount.ToStringInvariant()); } } m_writer.WriteEndElement(); } break; case ScopeType.Module: m_writer.WriteStartElement("module"); if (!scope.ScopeName.IsNullOrWhiteSpace()) { m_writer.WriteAttributeString("name", scope.ScopeName); } if (scope.UseStrict) { m_writer.WriteAttributeString("strict", "true"); } (scope as ModuleScope).IfNotNull(m => { m_writer.WriteAttributeString("default", m.HasDefaultExport ? "true" : "false"); if (m.IsNotComplete) { m_writer.WriteAttributeString("incomplete", "true"); } }); break; case ScopeType.Function: var functionScope = (FunctionScope)scope; m_writer.WriteStartElement("function"); // for source name, use the scope name if (!scope.ScopeName.IsNullOrWhiteSpace()) { m_writer.WriteAttributeString("src", scope.ScopeName); } var functionObject = functionScope.Owner as FunctionObject; if (functionObject != null) { if (functionObject.Binding == null || functionObject.Binding.Name.IsNullOrWhiteSpace()) { if (!functionObject.NameGuess.IsNullOrWhiteSpace()) { // strip enclosing quotes m_writer.WriteAttributeString("guess", functionObject.NameGuess.Trim('\"')); } } else { if (functionObject.Binding.VariableField != null && functionObject.Binding.VariableField.CrunchedName != null) { m_writer.WriteAttributeString("min", functionObject.Binding.VariableField.CrunchedName); } } m_writer.WriteAttributeString("type", functionObject.FunctionType.ToString().ToLowerInvariant()); OutputContextPosition(functionObject.Context); if (m_useReferenceCounts && functionObject.Binding != null && functionObject.Binding.VariableField != null) { var refCount = functionObject.Binding.VariableField.RefCount; m_writer.WriteAttributeString("refcount", refCount.ToStringInvariant()); if (refCount == 0 && functionObject.FunctionType == FunctionType.Declaration && functionObject.Binding.VariableField.FieldType == FieldType.Local) { // local function declaration with zero references? unreachable code! m_writer.WriteAttributeString("unreachable", "true"); } } if (scope.UseStrict) { m_writer.WriteAttributeString("strict", "true"); } // add the arguments m_writer.WriteStartElement("arguments"); if (functionObject.ParameterDeclarations != null) { foreach (var bindingIdentifier in BindingsVisitor.Bindings(functionObject.ParameterDeclarations)) { m_writer.WriteStartElement("argument"); m_writer.WriteAttributeString("src", bindingIdentifier.Name); if (bindingIdentifier.VariableField.IfNotNull(v => v.CrunchedName != null)) { m_writer.WriteAttributeString("min", bindingIdentifier.VariableField.CrunchedName); } OutputContextPosition(bindingIdentifier.Context); if (m_useReferenceCounts) { bindingIdentifier.VariableField.IfNotNull(v => m_writer.WriteAttributeString("refcount", v.RefCount.ToStringInvariant())); } m_writer.WriteEndElement(); } } m_writer.WriteEndElement(); } break; case ScopeType.Global: Debug.Assert(scope is GlobalScope); Debug.Fail("shouldn't get here!"); m_writer.WriteStartElement("global"); break; case ScopeType.With: Debug.Assert(scope is WithScope); m_writer.WriteStartElement("with"); // with-scopes should never be strict because the with-statement is not allowed in strict code if (scope.UseStrict) { m_writer.WriteAttributeString("strict", "true"); } break; } // process the defined and referenced fields ProcessFields(scope); // recursively process each child scope foreach (var childScope in scope.ChildScopes) { ProcessScope(childScope); } // close the element m_writer.WriteEndElement(); }