internal override void AnalyzeNode() { // we're going to look for the first FunctionScope on the stack FunctionScope functionScope = null; // get the current scope ActivationObject activationObject = ScopeStack.Peek(); do { functionScope = activationObject as FunctionScope; if (functionScope != null) { // found it -- break out of the loop break; } // otherwise go up the chain activationObject = activationObject.Parent; } while (activationObject != null); // if we found one.... if (functionScope != null) { // add this object to the list of thisliterals functionScope.AddThisLiteral(this); } }
public ModuleScope(ModuleDeclaration module, ActivationObject parent, CodeSettings settings) : base(parent, settings) { Owner = module; UseStrict = true; ScopeType = ScopeType.Module; m_knownExports = new Dictionary <string, JSVariableField>(); }
internal void AddFieldsAndProperties(ActivationObject obj) { foreach (PropertyInfo pi in GetType().GetProperties()) { obj.AddFieldOrUseExistingField(pi.Name, pi.GetValue(this, null), FieldAttributes.Public); } foreach (FieldInfo fi in GetType().GetFields()) { obj.AddFieldOrUseExistingField(fi.Name, fi.GetValue(this), FieldAttributes.Public); } }
internal FunctionScope(ActivationObject parent, bool isExpression, CodeSettings settings, FunctionObject funcObj) : base(parent, settings) { ScopeType = ScopeType.Function; m_refScopes = new HashSet <ActivationObject>(); if (isExpression) { // parent scopes automatically reference enclosed function expressions AddReference(Parent); } Owner = funcObj; }
internal void AddReference(ActivationObject scope) { // we don't want to include block scopes or with scopes -- they are really // contained within their parents while (scope != null && scope is BlockScope) { scope = scope.Parent; } if (scope != null) { // add the scope to the hash m_refScopes.Add(scope); } }
private void AddScopes(List <ActivationObject> list, ActivationObject parentScope) { // for each child scope... foreach (ActivationObject scope in parentScope.ChildScopes) { // add the scope to the list if it's not a globalscopes if (!(scope is GlobalScope)) { list.Add(scope); } // recurse... AddScopes(list, scope); } }
internal CatchScope(ActivationObject parent, CodeSettings settings) : base(parent, settings, ScopeType.Catch) { }
public WithScope(ActivationObject parent, CodeSettings settings) : base(parent, settings, ScopeType.With) { IsInWithScope = true; }
public BlockScope(Statement node, ActivationObject parent, ErrorSink errorSink) : base(node, parent, errorSink) { }
public BlockScope(ActivationObject parent, CodeSettings settings, ScopeType scopeType) : base(parent, settings) { ScopeType = scopeType; }
private void ProcessFields(ActivationObject scope) { // split fields into defined and referenced lists var definedFields = new List <JSVariableField>(); var referencedFields = new List <JSVariableField>(); foreach (var field in scope.NameTable.Values) { // if the field has no outer field reference, it is defined in this scope. // otherwise we're just referencing a field defined elsewhere if (!field.IsOuterReference) { switch (field.FieldType) { case FieldType.Global: if (scope is GlobalScope) { definedFields.Add(field); } else { referencedFields.Add(field); } break; case FieldType.Local: // defined within this scope definedFields.Add(field); break; case FieldType.Argument: // ignore the scope's arguments because we handle them separately break; case FieldType.CatchError: // ignore the catch-scope's error parameter because we handle it separately break; case FieldType.Arguments: if (field.RefCount > 0) { referencedFields.Add(field); } break; case FieldType.Super: referencedFields.Add(field); break; case FieldType.UndefinedGlobal: case FieldType.Predefined: case FieldType.WithField: referencedFields.Add(field); break; case FieldType.GhostFunction: case FieldType.GhostCatch: // ignore the ghost fields when reporting break; } } else if (!field.IsPlaceholder) { // we are an outer reference and we are not a placeholder, // so this scope actually references the outer field. referencedFields.Add(field); } } if (definedFields.Count > 0) { m_writer.WriteStartElement("defines"); foreach (var field in definedFields) { ProcessField(field, true); } m_writer.WriteEndElement(); } if (referencedFields.Count > 0) { m_writer.WriteStartElement("references"); foreach (var field in referencedFields) { ProcessField(field, false); } m_writer.WriteEndElement(); } }
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(); }
private void WriteScopeReport(ActivationObject scope) { // output the function header if (scope is GlobalScope) { WriteProgress(NUglify.GlobalObjectsHeader); } else { ModuleScope moduleScope; if (scope is FunctionScope) { WriteFunctionHeader(scope.Owner as FunctionObject, scope.IsKnownAtCompileTime, scope.UseStrict); } else if ((moduleScope = scope as ModuleScope) != null) { WriteModuleHeader(moduleScope); } else { string blockType; switch (scope.ScopeType) { case ScopeType.Catch: blockType = NUglify.BlockTypeCatch; break; case ScopeType.With: blockType = NUglify.BlockTypeWith; break; case ScopeType.Class: blockType = NUglify.BlockTypeClass.FormatInvariant(scope.ScopeName.IfNullOrWhiteSpace(NUglify.AnonymousName)); break; case ScopeType.Block: case ScopeType.Lexical: blockType = NUglify.BlockTypeLexical; break; case ScopeType.Module: case ScopeType.Function: case ScopeType.Global: case ScopeType.None: default: blockType = string.Empty; System.Diagnostics.Debug.Fail("shouldn't get here"); break; } WriteBlockHeader(scope as BlockScope, blockType); } } // get all the fields in the scope List <JSVariableField> scopeFields = new List <JSVariableField>(scope.NameTable.Values); // sort the fields scopeFields.Sort(FieldComparer.Instance); // iterate over all the fields foreach (JSVariableField variableField in scopeFields) { // don't report placeholder fields or fields with the SpecialName attribute that aren't referenced if (!variableField.IsPlaceholder && (variableField.Attributes != FieldAttributes.SpecialName || variableField.IsReferenced)) { WriteMemberReport(variableField); } } }
public WithScope(Statement node, ActivationObject parent, ErrorSink errorSink) : base(node, parent, errorSink) { IsInWithScope = true; }
internal CatchScope(Statement node, ActivationObject parent, ParameterDeclaration catchParameter, ErrorSink errorSink) : base(node, parent, errorSink) { CatchParameter = catchParameter; }