/// <summary> /// Derive a new prototype from this prototype. /// </summary> public Prototype Derive() { // Create the new one: Prototype proto = new Prototype(Engine, null, null, IsStatic); // Define an internal derived property: proto.AddProperty("JS__Internal__Derived", Type, PropertyAttributes.NonEnumerable); return(proto); }
internal override void ResolveVariables(OptimizationInfo optimizationInfo) { if (ResolvedProperty != null || propertyName != null) { // Already resolved. return; } // Resolve kids: base.ResolveVariables(optimizationInfo); // Right-hand-side can be a property name (a.b) if (this.OperatorType == OperatorType.MemberAccess) { var rhs = this.GetOperand(1) as NameExpression; if (rhs == null) { throw new JavaScriptException(optimizationInfo.Engine, "SyntaxError", "Invalid member access", 1, optimizationInfo.Source.Path, optimizationInfo.FunctionName); } propertyName = rhs.Name; } // Or a constant indexer (a['b']) if (this.OperatorType == OperatorType.Index) { var rhs = this.GetOperand(1); if (rhs != null) { Type rhsType = rhs.GetResultType(optimizationInfo); if (rhsType == typeof(string)) { // Try a literal: LiteralExpression literalStr = rhs as LiteralExpression; if (literalStr != null) { propertyName = TypeConverter.ToString(literalStr.Value); // Could actually be numeric, so try that: if (propertyName != null && Nitrassic.Library.Array.ParseArrayIndex(propertyName) != uint.MaxValue) { // Yep, it is! isArrayIndex = true; } } } else if (PrimitiveTypeUtilities.IsNumeric(rhsType)) { // array index (a[0]) isArrayIndex = true; } } } if (isArrayIndex == true) { // Array indexer // ------------- // xxx = object[index] // Load the left-hand side and convert to an object instance. var lhs = this.GetOperand(0); // Get the type of the LHS (the object being read from): Type lhsType = lhs.GetResultType(optimizationInfo); // Get the proto for it: Nitrassic.Library.Prototype proto = optimizationInfo.Engine.Prototypes.Get(lhsType); // Does that type have an indexer method on it? (this[uint]) ResolvedProperty = proto.Indexer(typeof(uint)); if (ResolvedProperty == null) { // Try [int] instead: ResolvedProperty = proto.Indexer(typeof(int)); } } if (ResolvedProperty == null && propertyName != null) { // Load the left-hand side and convert to an object instance. var lhs = this.GetOperand(0); Type lhsType = lhs.GetResultType(optimizationInfo); // Get the prototype: Nitrassic.Library.Prototype proto = optimizationInfo.Engine.Prototypes.Get(lhsType); // Get the property: ResolvedProperty = proto.GetProperty(propertyName); if (ResolvedProperty == null) { // Add it now (as undefined): ResolvedProperty = proto.AddProperty(propertyName, null, Nitrassic.Library.PropertyAttributes.FullAccess); } } }