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)); }
void Translate() { // Get the reserved variables and IDs foreach (ScriptFile script in Importer.ScriptFiles) { if (script.Context.reserved_global()?.reserved_list() != null) { foreach (var name in script.Context.reserved_global().reserved_list().PART()) { VarCollection.Reserve(name.GetText(), true); } foreach (var id in script.Context.reserved_global().reserved_list().NUMBER()) { VarCollection.Reserve(int.Parse(id.GetText()), true, null, null); } } if (script.Context.reserved_player()?.reserved_list() != null) { foreach (var name in script.Context.reserved_player().reserved_list().PART()) { VarCollection.Reserve(name.GetText(), false); } foreach (var id in script.Context.reserved_player().reserved_list().NUMBER()) { VarCollection.Reserve(int.Parse(id.GetText()), false, null, null); } } } // Get the enums foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var enumContext in script.Context.enum_define()) { var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext); Types.AllTypes.Add(newEnum); Types.DefinedTypes.Add(newEnum); Types.CalledTypes.Add(newEnum); } } // Get the types foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var typeContext in script.Context.type_define()) { var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext); Types.AllTypes.Add(newType); Types.DefinedTypes.Add(newType); Types.CalledTypes.Add(newType); } } // Get the methods and macros foreach (ScriptFile script in Importer.ScriptFiles) { ParseInfo parseInfo = new ParseInfo(script, this); // Get the methods. foreach (var methodContext in script.Context.define_method()) { new DefinedMethod(parseInfo, RulesetScope, RulesetScope, methodContext, null); } // Get the macros. foreach (var macroContext in script.Context.define_macro()) { parseInfo.GetMacro(RulesetScope, RulesetScope, macroContext); } } // Get the defined variables. foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var varContext in script.Context.define()) { Var newVar = new RuleLevelVariable(RulesetScope, new DefineContextHandler(new ParseInfo(script, this), varContext)); rulesetVariables.Add(newVar); // Add the variable to the player variables scope if it is a player variable. if (newVar.VariableType == VariableType.Player) { PlayerVariableScope.CopyVariable(newVar); } } } foreach (var applyType in Types.AllTypes) { if (applyType is ClassType classType) { classType.ResolveElements(); } } foreach (var apply in _applyBlocks) { apply.SetupParameters(); } foreach (var apply in _applyBlocks) { apply.SetupBlock(); } foreach (var callInfo in _recursionCheck) { callInfo.CheckRecursion(); } // Get hooks foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var hookContext in script.Context.hook()) { HookVar.GetHook(new ParseInfo(script, this), RulesetScope, hookContext); } } // Get the rules foreach (ScriptFile script in Importer.ScriptFiles) { foreach (var ruleContext in script.Context.ow_rule()) { rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext)); } } }
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)); }