Exemple #1
0
        public DefinedType(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Type_defineContext typeContext, List <IApplyBlock> applyMethods) : base(typeContext.name.Text)
        {
            this.translateInfo = parseInfo.TranslateInfo;
            if (translateInfo.IsCodeType(Name))
            {
                parseInfo.Script.Diagnostics.Error($"A type with the name '{Name}' already exists.", DocRange.GetRange(typeContext.name));
            }

            DefinedAt = new LanguageServer.Location(parseInfo.Script.Uri, DocRange.GetRange(typeContext.name));
            translateInfo.AddSymbolLink(this, DefinedAt);

            if (typeContext.CLASS() != null)
            {
                TypeKind       = TypeKind.Class;
                TypeKindString = "class";
            }
            else if (typeContext.STRUCT() != null)
            {
                TypeKind       = TypeKind.Struct;
                TypeKindString = "struct";
            }
            else
            {
                throw new NotImplementedException();
            }

            staticScope = translateInfo.GlobalScope.Child(TypeKindString + " " + Name);
            objectScope = staticScope.Child(TypeKindString + " " + Name);

            // Get the variables defined in the type.
            foreach (var definedVariable in typeContext.define())
            {
                Var newVar = Var.CreateVarFromContext(VariableDefineType.InClass, parseInfo, definedVariable);
                newVar.Finalize(UseScope(newVar.Static));
                if (!newVar.Static)
                {
                    objectVariables.Add(newVar);
                }
            }

            // Todo: Static methods/macros.
            foreach (var definedMethod in typeContext.define_method())
            {
                var newMethod = new DefinedMethod(parseInfo, UseScope(false), definedMethod);
                applyMethods.Add(newMethod);
            }

            foreach (var macroContext in typeContext.define_macro())
            {
                DeltinScript.GetMacro(parseInfo, UseScope(false), macroContext, applyMethods);
            }

            // Get the constructors.
            if (typeContext.constructor().Length > 0)
            {
                Constructors = new Constructor[typeContext.constructor().Length];
                for (int i = 0; i < Constructors.Length; i++)
                {
                    Constructors[i] = new DefinedConstructor(parseInfo, this, typeContext.constructor(i));
                    applyMethods.Add((DefinedConstructor)Constructors[i]);
                }
            }
            else
            {
                // If there are no constructors, create a default constructor.
                Constructors = new Constructor[] {
                    new Constructor(this, new Location(parseInfo.Script.Uri, DocRange.GetRange(typeContext.name)), AccessLevel.Public)
                };
            }
        }
Exemple #2
0
        public override void ResolveElements()
        {
            if (elementsResolved)
            {
                return;
            }

            // Get the type being extended.
            // This is an array for future interface support.
            if (_typeContext.Inheriting.Count > 0 && _typeContext.Inheriting[0])
            {
                var inheritToken = _typeContext.Inheriting[0];

                // Get the type being inherited.
                CodeType inheriting = _parseInfo.TranslateInfo.Types.GetCodeType(inheritToken.Text, _parseInfo.Script.Diagnostics, inheritToken.Range);

                // GetCodeType will return null if the type is not found.
                if (inheriting != null)
                {
                    inheriting.Call(_parseInfo, inheritToken.Range);

                    Inherit(inheriting, _parseInfo.Script.Diagnostics, inheritToken.Range);
                    (Extends as ClassType)?.ResolveElements();
                }
            }

            base.ResolveElements();

            // Get the declarations.
            foreach (var declaration in _typeContext.Declarations)
            {
                IScopeable scopeable;

                // Function
                if (declaration is FunctionContext function)
                {
                    scopeable = new DefinedMethod(_parseInfo, operationalScope, staticScope, function, this);
                }
                // Macro function
                else if (declaration is MacroFunctionContext macroFunction)
                {
                    scopeable = _parseInfo.GetMacro(operationalScope, staticScope, macroFunction);
                }
                // Variable
                else if (declaration is VariableDeclaration variable)
                {
                    scopeable = new ClassVariable(operationalScope, staticScope, new DefineContextHandler(_parseInfo, variable)).GetVar();
                }
                // Macro variable
                else if (declaration is MacroVarDeclaration macroVar)
                {
                    scopeable = _parseInfo.GetMacro(operationalScope, staticScope, macroVar);
                }
                // Unknown
                else
                {
                    throw new NotImplementedException(declaration.GetType().ToString());
                }

                // Add the object variable if it is an IIndexReferencer.
                if (scopeable is IIndexReferencer referencer)
                {
                    AddObjectVariable(referencer);
                }

                // Copy to scopes.
                // Method copy
                if (scopeable is IMethod method)
                {
                    if (method.Static)
                    {
                        operationalScope.CopyMethod(method);
                    }
                    else
                    {
                        serveObjectScope.CopyMethod(method);
                    }
                }
                // Variable copy
                else if (scopeable is IVariable variable)
                {
                    if (scopeable.Static)
                    {
                        operationalScope.CopyVariable(variable);
                    }
                    else
                    {
                        serveObjectScope.CopyVariable(variable);
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            // Get the constructors.
            if (_typeContext.Constructors.Count > 0)
            {
                Constructors = new Constructor[_typeContext.Constructors.Count];
                for (int i = 0; i < Constructors.Length; i++)
                {
                    Constructors[i] = new DefinedConstructor(_parseInfo, operationalScope, this, _typeContext.Constructors[i]);
                }
            }
            else
            {
                // If there are no constructors, create a default constructor.
                Constructors = new Constructor[] {
                    new Constructor(this, new Location(_parseInfo.Script.Uri, DefinedAt.range), AccessLevel.Public)
                };
            }

            // If the extend token exists, add completion that only contains all extendable classes.
            if (_typeContext.InheritToken != null && !_parseInfo.Script.IsTokenLast(_typeContext.InheritToken))
            {
                _parseInfo.Script.AddCompletionRange(new CompletionRange(
                                                         // Get the completion items of all types.
                                                         _parseInfo.TranslateInfo.Types.AllTypes
                                                         .Where(t => t is ClassType ct && ct.CanBeExtended)
                                                         .Select(t => t.GetCompletion())
                                                         .ToArray(),
                                                         // Get the completion range.
                                                         _typeContext.InheritToken.Range.End + _parseInfo.Script.NextToken(_typeContext.InheritToken).Range.Start,
                                                         // This completion takes priority.
                                                         CompletionRangeKind.ClearRest
                                                         ));
            }
            _parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, _parseInfo, CodeLensSourceType.Type, DefinedAt.range));
        }
 public DefinedConstructorHandler(DefinedConstructor constructor)
 {
     _constructor = constructor;
 }
        public override void ResolveElements()
        {
            if (elementsResolved)
            {
                return;
            }

            // Get the type being extended.
            if (typeContext.TERNARY_ELSE() != null)
            {
                // If there is no type name, error.
                if (typeContext.extends == null)
                {
                    parseInfo.Script.Diagnostics.Error("Expected type name.", DocRange.GetRange(typeContext.TERNARY_ELSE()));
                }
                else
                {
                    // Get the type being inherited.
                    CodeType inheriting = parseInfo.TranslateInfo.Types.GetCodeType(typeContext.extends.Text, parseInfo.Script.Diagnostics, DocRange.GetRange(typeContext.extends));

                    // GetCodeType will return null if the type is not found.
                    if (inheriting != null)
                    {
                        inheriting.Call(parseInfo, DocRange.GetRange(typeContext.extends));

                        Inherit(inheriting, parseInfo.Script.Diagnostics, DocRange.GetRange(typeContext.extends));
                        (Extends as ClassType)?.ResolveElements();
                    }
                }
            }

            base.ResolveElements();

            // Give DefinedMethod and GetMacro a scope to use in case of the static attribute.
            foreach (var definedMethod in typeContext.define_method())
            {
                var newMethod = new DefinedMethod(parseInfo, operationalScope, staticScope, definedMethod, this);

                // Copy to serving scopes.
                if (newMethod.Static)
                {
                    operationalScope.CopyMethod(newMethod);
                }
                else
                {
                    serveObjectScope.CopyMethod(newMethod);
                }
            }

            // Get the macros.
            foreach (var macroContext in typeContext.define_macro())
            {
                var newMacro = parseInfo.GetMacro(operationalScope, staticScope, macroContext);

                // Copy to serving scopes.
                if (newMacro is IMethod asMethod)
                {
                    if (newMacro.Static)
                    {
                        operationalScope.CopyMethod(asMethod);
                    }
                    else
                    {
                        serveObjectScope.CopyMethod(asMethod);
                    }
                }
                else
                {
                    if (newMacro.Static)
                    {
                        operationalScope.CopyVariable((IVariable)newMacro);
                    }
                    else
                    {
                        serveObjectScope.CopyVariable((IVariable)newMacro);
                    }
                }
            }

            // Get the variables defined in the type.
            foreach (var definedVariable in typeContext.define())
            {
                Var newVar = new ClassVariable(operationalScope, staticScope, new DefineContextHandler(parseInfo, definedVariable));

                // Copy to serving scopes.
                if (!newVar.Static)
                {
                    ObjectVariables.Add(new ObjectVariable(newVar));
                    serveObjectScope.CopyVariable(newVar);
                }
                // Add to static scope.
                else
                {
                    staticVariables.Add(newVar);
                    staticScope.CopyVariable(newVar);
                    operationalScope.CopyVariable(newVar);
                }
            }

            // Get the constructors.
            if (typeContext.constructor().Length > 0)
            {
                Constructors = new Constructor[typeContext.constructor().Length];
                for (int i = 0; i < Constructors.Length; i++)
                {
                    Constructors[i] = new DefinedConstructor(parseInfo, operationalScope, this, typeContext.constructor(i));
                }
            }
            else
            {
                // If there are no constructors, create a default constructor.
                Constructors = new Constructor[] {
                    new Constructor(this, new Location(parseInfo.Script.Uri, DocRange.GetRange(typeContext.name)), AccessLevel.Public)
                };
            }

            // If the extend token exists, add completion that only contains all extendable classes.
            if (typeContext.TERNARY_ELSE() != null)
            {
                parseInfo.Script.AddCompletionRange(new CompletionRange(
                                                        // Get the completion items of all types.
                                                        parseInfo.TranslateInfo.Types.AllTypes
                                                        .Where(t => t is ClassType ct && ct.CanBeExtended)
                                                        .Select(t => t.GetCompletion())
                                                        .ToArray(),
                                                        // Get the completion range.
                                                        DocRange.GetRange(typeContext.TERNARY_ELSE(), parseInfo.Script.NextToken(typeContext.TERNARY_ELSE())),
                                                        // This completion takes priority.
                                                        CompletionRangeKind.ClearRest
                                                        ));
            }
            parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, parseInfo, CodeLensSourceType.Type, DefinedAt.range));
        }
 public ConstructorDeterminer(DefinedConstructor constructor) : this(new DefinedConstructorHandler(constructor))
 {
 }