public override void Set(AbstractSymbolValueProvider vp, ISymbolValue value) { var oldV = vp[Variable]; if (oldV is ArrayValue) { var av = (ArrayValue)oldV; //TODO: Immutability checks if (av.IsString) { } else { var at = av.RepresentedType as ArrayType; var newElements = new ISymbolValue[av.Elements.Length + (ItemNumber<0 ? 1:0)]; av.Elements.CopyTo(newElements, 0); if (!ResultComparer.IsImplicitlyConvertible(value.RepresentedType, at.ValueType)) throw new EvaluationException(BaseExpression, value.ToCode() + " must be implicitly convertible to the array's value type!", value); // Add.. if (ItemNumber < 0) av.Elements[av.Elements.Length - 1] = value; else // or set the new value av.Elements[ItemNumber] = value; vp[Variable] = new ArrayValue(at, newElements); } } else throw new EvaluationException(BaseExpression, "Type of accessed item must be an array", oldV); }
/// <summary> /// http://dlang.org/operatoroverloading.html#Dispatch /// Check for the existence of an opDispatch overload. /// Important: Because static opDispatches are allowed as well, do check whether we can access non-static overloads from non-instance expressions or such /// </summary> public static IEnumerable<AbstractType> TryResolveFurtherIdViaOpDispatch (ResolutionContext ctxt, int nextIdentifierHash, UserDefinedType b, ISyntaxRegion typeBase = null) { // The usual SO prevention if (nextIdentifierHash == opDispatchId || b == null) yield break; AbstractType[] overloads; var opt = ctxt.CurrentContext.ContextDependentOptions; // Look for opDispatch-Members inside b's Definition using (ctxt.Push(b)) { ctxt.CurrentContext.ContextDependentOptions = opt; // Mainly required for not resolving opDispatch's return type, as this will be performed later on in higher levels overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(opDispatchId, b, ctxt, typeBase, false); } if (overloads == null || overloads.Length < 0) yield break; var av = new ArrayValue (Evaluation.GetStringType(ctxt), Strings.TryGet(nextIdentifierHash)); foreach (DSymbol o in overloads) { var dn = o.Definition; if (dn.TemplateParameters != null && dn.TemplateParameters.Length > 0 && dn.TemplateParameters[0] is TemplateValueParameter) { //TODO: Test parameter types for being a string value o.SetDeducedTypes(new[]{ new TemplateParameterSymbol(dn.TemplateParameters[0], av) }); yield return o; } } }
/// <summary> /// http://dlang.org/operatoroverloading.html#Dispatch /// Check for the existence of an opDispatch overload. /// Important: Because static opDispatches are allowed as well, do check whether we can access non-static overloads from non-instance expressions or such /// </summary> public static IEnumerable<AbstractType> TryResolveFurtherIdViaOpDispatch(ResolutionContext ctxt, int nextIdentifierHash, UserDefinedType b) { // The usual SO prevention if (nextIdentifierHash == opDispatchId || b == null) yield break; var pop = ctxt.ScopedBlock != b.Definition; if (pop) { // Mainly required for not resolving opDispatch's return type, as this will be performed later on in higher levels var opt = ctxt.CurrentContext.ContextDependentOptions; ctxt.PushNewScope (b.Definition as IBlockNode); ctxt.CurrentContext.IntroduceTemplateParameterTypes (b); ctxt.CurrentContext.ContextDependentOptions = opt; } // Look for opDispatch-Members inside b's Definition var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier (opDispatchId, new[]{b}, ctxt); if(pop) ctxt.Pop (); if (overloads == null || overloads.Length < 0) yield break; var av = new ArrayValue (Evaluation.GetStringType(ctxt), Strings.TryGet(nextIdentifierHash)); foreach (DSymbol o in overloads) { var dn = o.Definition; if (dn.TemplateParameters != null && dn.TemplateParameters.Length > 0 && dn.TemplateParameters[0] is TemplateValueParameter) { //TODO: Test parameter types for being a string value o.DeducedTypes = new System.Collections.ObjectModel.ReadOnlyCollection<TemplateParameterSymbol> ( new[]{ new TemplateParameterSymbol(dn.TemplateParameters[0], av) } ); yield return o; } } }