public static void ValidateTypeArg(ParseInfo parseInfo, AnonymousType typeArg, CodeType type, DocRange errorRange) { // 'single' attribute, type-arg is not parallelable. if (typeArg.AnonymousTypeAttributes.Single) { // Bad struct if (type.Attributes.IsStruct) { parseInfo.Script.Diagnostics.Error("Struct types cannot be used with 'single' type args", errorRange); return; } // Extract anonymous types. var subtypes = type.ExtractAnonymousTypes(); foreach (var subtype in subtypes) { if (!subtype.AnonymousTypeAttributes.Single) { parseInfo.Script.Diagnostics.Error("The anonymous type used here as a type arg needs to be marked as 'single'", errorRange); return; } } } }
public SelfContainedClassProvider(DeltinScript deltinScript, ISelfContainedClass selfContainedClass) : base(selfContainedClass.Name) { _selfContainedClass = selfContainedClass; _deltinScript = deltinScript; GenericTypes = new AnonymousType[0]; Instance = new SelfContainedClassInstance(deltinScript, selfContainedClass, this); }
public DefinedClassInitializer(ParseInfo parseInfo, Scope scope, ClassContext typeContext) : base(typeContext.Identifier.GetText()) { _parseInfo = parseInfo; _typeContext = typeContext; _scope = scope; _conflictScope = new Scope(Name); MetaGetter = this; OnReady = _onReady; DefinedAt = parseInfo.Script.GetLocation(typeContext.Identifier.GetRange(typeContext.Range)); parseInfo.TranslateInfo.StagedInitiation.On(this); // Get the generics. GenericTypes = AnonymousType.GetGenerics(parseInfo, _typeContext.Generics, this); if (typeContext.Identifier) { parseInfo.Script.AddHover( range: typeContext.Identifier.Range, content: IDefinedTypeInitializer.Hover("class", this)); parseInfo.Script.Elements.AddDeclarationCall(this, new DeclarationCall(typeContext.Identifier.Range, true)); } }
public DefinedStructInitializer(ParseInfo parseInfo, Scope scope, ClassContext typeContext) : base(typeContext.Identifier.GetText()) { _parseInfo = parseInfo; _context = typeContext; _scope = scope; DefinedAt = parseInfo.Script.GetLocation(typeContext.Identifier.GetRange(typeContext.Range)); parseInfo.TranslateInfo.StagedInitiation.Meta.Execute(this); parseInfo.TranslateInfo.StagedInitiation.Content.Execute(this); // Get the type args. GenericTypes = AnonymousType.GetGenerics(parseInfo, typeContext.Generics, this); GenericAssigns = new bool[GenericTypes.Length]; // Add the declaration link. if (typeContext.Identifier) { parseInfo.Script.AddHover( range: typeContext.Identifier.Range, content: IDefinedTypeInitializer.Hover("struct", this)); parseInfo.Script.Elements.AddDeclarationCall(this, new DeclarationCall(typeContext.Identifier.Range, true)); } WorkingInstance = GetInstance(); }
// Adds a link between a type-arg and a type-value. public void Add(AnonymousType typeArg, CodeType typeValue) => Links.Add(typeArg, typeValue);
private DefinedMethodProvider(ParseInfo parseInfo, IScopeHandler scopeProvider, FunctionContext context, IDefinedTypeInitializer containingType) { _parseInfo = parseInfo; Context = context; ContainingType = containingType; CallInfo = new CallInfo(new RecursiveCallHandler(this, context.Subroutine || context.Attributes.Recursive), parseInfo.Script, ContentReady); DocRange nameRange = context.Identifier.Range; // Get the attributes. var attributes = new GenericAttributeAppender(AttributeType.Ref, AttributeType.In, AttributeType.GlobalVar, AttributeType.PlayerVar); AttributesGetter.GetAttributes(parseInfo.Script.Diagnostics, context.Attributes, attributes); // Set the attributes. Static = attributes.IsStatic; Recursive = attributes.IsRecursive; Virtual = attributes.IsVirtual; AccessLevel = attributes.Accessor; Recursive = attributes.IsRecursive; // Get subroutine info. if (context.Subroutine) { IsSubroutine = true; SubroutineName = context.Subroutine.Text.RemoveQuotes(); SubroutineDefaultGlobal = !context.PlayerVar; } // Setup the scope. var containingScope = scopeProvider.GetScope(Static); containingScope.MethodContainer = true; _methodScope = containingScope.Child(true); // Get the generics. GenericTypes = AnonymousType.GetGenerics(parseInfo, context.TypeArguments, this); foreach (var type in GenericTypes) { _methodScope.AddType(new GenericCodeTypeInitializer(type)); } // Get the type. if (!context.Type.IsVoid) { ReturnType = TypeFromContext.GetCodeTypeFromContext(parseInfo, _methodScope, context.Type); } // Setup the parameters. ParameterProviders = ParameterProvider.GetParameterProviders(parseInfo, _methodScope, context.Parameters, IsSubroutine); ParameterTypes = ParameterProviders.Select(p => p.Type).ToArray(); // Override if (attributes.IsOverride) { OverridingFunction = (DefinedMethodInstance)scopeProvider.GetOverridenFunction(parseInfo.TranslateInfo, new FunctionOverrideInfo(Name, ParameterTypes)); if (OverridingFunction == null) { SemanticsHelper.CouldNotOverride(parseInfo, nameRange, "method"); } } // Check conflicts and add to scope. scopeProvider.CheckConflict(parseInfo, new(Name, ParameterTypes), nameRange); scopeProvider.Add(GetDefaultInstance(scopeProvider.DefinedIn()), Static); // Add LSP elements // Hover parseInfo.Script.AddHover(nameRange, GetLabel(parseInfo.TranslateInfo, LabelInfo.Hover)); // 'references' code lens parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, parseInfo, CodeLensSourceType.Function, DefinedAt.range)); // Rename & go-to-definition parseInfo.Script.Elements.AddDeclarationCall(this, new DeclarationCall(nameRange, true)); // todo: 'override' code lens // if (Attributes.IsOverrideable) // parseInfo.Script.AddCodeLensRange(new ImplementsCodeLensRange(this, parseInfo.Script, CodeLensSourceType.Function, nameRange)); // Add the CallInfo to the recursion check. parseInfo.TranslateInfo.GetComponent <RecursionCheckComponent>().AddCheck(CallInfo); // Queue content for staged initiation. parseInfo.TranslateInfo.StagedInitiation.On(this); }
void SetupScope() { if (_scopeInstance != null) { return; } _scopeInstance = new Scope(); _operationsInstance = new TypeOperatorInfo(this); Scope.AddNativeVariable(_length); Scope.AddNativeVariable(_last); Scope.AddNativeVariable(_first); var pipeType = new PipeType(ArrayOfType, this); var functionHandler = ArrayOfType.ArrayHandler.GetFunctionHandler(); // Filtered Array new GenericSortFunction() { Name = "FilteredArray", Documentation = "A copy of the specified array with any values that do not match the specified condition removed.", ReturnType = this, ArrayOfType = ArrayOfType, FuncType = _supplier.Boolean(), ParameterDocumentation = "The condition that is evaluated for each element of the copied array. If the condition is true, the element is kept in the copied array.", Function = "Filtered Array", Executor = functionHandler.FilteredArray() }.Add(Scope, _supplier); // Sorted Array new GenericSortFunction() { Name = "SortedArray", Documentation = "A copy of the specified array with the values sorted according to the value rank that is evaluated for each element.", ReturnType = this, ArrayOfType = ArrayOfType, FuncType = _supplier.Boolean(), ParameterDocumentation = "The value that is evaluated for each element of the copied array. The array is sorted by this rank in ascending order.", Function = "Sorted Array", Executor = functionHandler.SortedArray() }.Add(Scope, _supplier); // Is True For Any new GenericSortFunction() { Name = "IsTrueForAny", Documentation = "Whether the specified condition evaluates to true for any value in the specified array.", ReturnType = _supplier.Boolean(), ArrayOfType = ArrayOfType, FuncType = _supplier.Boolean(), ParameterDocumentation = "The condition that is evaluated for each element of the specified array.", Function = "Is True For Any", Executor = functionHandler.Any() }.Add(Scope, _supplier); // Is True For All new GenericSortFunction() { Name = "IsTrueForAll", Documentation = "Whether the specified condition evaluates to true for every value in the specified array.", ReturnType = _supplier.Boolean(), ArrayOfType = ArrayOfType, FuncType = _supplier.Boolean(), ParameterDocumentation = "The condition that is evaluated for each element of the specified array.", Function = "Is True For All", Executor = functionHandler.All() }.Add(Scope, _supplier); // Mapped var mapGenericParameter = new AnonymousType("T", new AnonymousTypeAttributes(false)); var mapmethodInfo = new MethodInfo(new[] { mapGenericParameter }); mapGenericParameter.Context = mapmethodInfo.Tracker; new GenericSortFunction() { Name = "Map", Documentation = "Whether the specified condition evaluates to true for every value in the specified array.", ReturnType = new ArrayType(_supplier, mapGenericParameter), ArrayOfType = ArrayOfType, FuncType = mapGenericParameter, ParameterDocumentation = "The condition that is evaluated for each element of the specified array.", Function = "Mapped Array", Executor = functionHandler.Map(), MethodInfo = mapmethodInfo }.Add(Scope, _supplier); // Contains Func(new FuncMethodBuilder() { Name = "Contains", Documentation = "Whether the array contains the specified value.", ReturnType = _supplier.Boolean(), Parameters = new CodeParameter[] { new CodeParameter("value", "The value that is being looked for in the array.", ArrayOfType) }, Action = (actionSet, methodCall) => functionHandler.Contains(actionSet.CurrentObject, methodCall.ParameterValues[0]) }); // Random if (functionHandler.AllowUnhandled) { Func(new FuncMethodBuilder() { Name = "Random", Documentation = "Gets a random value from the array.", ReturnType = ArrayOfType, Action = (actionSet, methodCall) => Element.Part("Random Value In Array", actionSet.CurrentObject) }); } // Randomize if (functionHandler.AllowUnhandled) { Func(new FuncMethodBuilder() { Name = "Randomize", Documentation = "Returns a copy of the array that is randomized.", ReturnType = this, Action = (actionSet, methodCall) => Element.Part("Randomized Array", actionSet.CurrentObject) }); } // Append if (functionHandler.AllowUnhandled) { Func(new FuncMethodBuilder() { Name = "Append", Documentation = "A copy of the array with the specified value appended to it.", ReturnType = this, Parameters = new CodeParameter[] { new CodeParameter("value", "The value that is appended to the array. If the value is an array, it will be flattened.", pipeType) }, Action = (actionSet, methodCall) => Element.Append(actionSet.CurrentObject, methodCall.ParameterValues[0]) }); } // Remove if (functionHandler.AllowUnhandled) { Func(new FuncMethodBuilder() { Name = "Remove", Documentation = "A copy of the array with the specified value removed from it.", ReturnType = this, Parameters = new CodeParameter[] { new CodeParameter("value", "The value that is removed from the array.", pipeType) }, Action = (actionSet, methodCall) => Element.Part("Remove From Array", actionSet.CurrentObject, methodCall.ParameterValues[0]) }); } // Slice if (functionHandler.AllowUnhandled) { Func(new FuncMethodBuilder() { Name = "Slice", Documentation = "A copy of the array containing only values from a specified index range.", ReturnType = this, Parameters = new CodeParameter[] { new CodeParameter("startIndex", "The first index of the range.", _supplier.Number()), new CodeParameter("count", "The number of elements in the resulting array. The resulting array will contain fewer elements if the specified range exceeds the bounds of the array.", _supplier.Number()) }, Action = (actionSet, methodCall) => Element.Part("Array Slice", actionSet.CurrentObject, methodCall.ParameterValues[0], methodCall.ParameterValues[1]) }); } // Index Of if (functionHandler.AllowUnhandled) { Func(new FuncMethodBuilder() { Name = "IndexOf", Documentation = "The index of a value within an array or -1 if no such value can be found.", ReturnType = _supplier.Number(), Parameters = new CodeParameter[] { new CodeParameter("value", "The value for which to search.", ArrayOfType) }, Action = (actionSet, methodCall) => Element.IndexOfArrayValue(actionSet.CurrentObject, methodCall.ParameterValues[0]) }); } // Modify Append Func(new FuncMethodBuilder() { Name = "ModAppend", Documentation = "Appends a value to the array. This will modify the array directly rather than returning a copy of the array. The source expression must be a variable.", Parameters = new CodeParameter[] { new CodeParameter("value", "The value that is pushed to the array.", pipeType) }, OnCall = SourceVariableResolver.GetSourceVariable, ReturnType = _supplier.Number(), Action = (actionSet, methodCall) => SourceVariableResolver.Modify(actionSet, methodCall, Operation.AppendToArray) }); // Modify Remove By Value Func(new FuncMethodBuilder() { Name = "ModRemoveByValue", Documentation = "Removes an element from the array by a value. This will modify the array directly rather than returning a copy of the array. The source expression must be a variable.", Parameters = new CodeParameter[] { new CodeParameter("value", "The value that is removed from the array.", ArrayOfType) }, OnCall = SourceVariableResolver.GetSourceVariable, ReturnType = _supplier.Number(), Action = (actionSet, methodCall) => SourceVariableResolver.Modify(actionSet, methodCall, Operation.RemoveFromArrayByValue) }); // Modify Remove By Index Func(new FuncMethodBuilder() { Name = "ModRemoveByIndex", Documentation = "Removes an element from the array by the index. This will modify the array directly rather than returning a copy of the array. The source expression must be a variable.", Parameters = new CodeParameter[] { new CodeParameter("index", "The index of the element that is removed from the array.", _supplier.Number()) }, OnCall = SourceVariableResolver.GetSourceVariable, ReturnType = _supplier.Number(), Action = (actionSet, methodCall) => SourceVariableResolver.Modify(actionSet, methodCall, Operation.RemoveFromArrayByIndex) }); // Add type operations. Operations.AddTypeOperation(new[] { // + append new TypeOperation(TypeOperator.Add, pipeType, this, (l, r) => Element.Append(l, r)), // - remove new TypeOperation(TypeOperator.Subtract, pipeType, this, (l, r) => Element.Remove(l, r)) }); Operations.AddTypeOperation(new[] { // += mod append new AssignmentOperation(AssignmentOperator.AddEqual, pipeType, info => info.Modify(Operation.AppendToArray)), // -= mod remove new AssignmentOperation(AssignmentOperator.SubtractEqual, pipeType, info => info.Modify(Operation.RemoveFromArrayByValue)) }); ArrayOfType.ArrayHandler.OverrideArray(this); }