Ejemplo n.º 1
0
        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;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }