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) }; } }
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.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.Script, 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) { staticScope.CopyMethod(newMethod); } else { serveObjectScope.CopyMethod(newMethod); } } // Get the macros. foreach (var macroContext in typeContext.define_macro()) { var newMacro = DeltinScript.GetMacro(parseInfo, operationalScope, staticScope, macroContext); // Copy to serving scopes. if (newMacro is IMethod asMethod) { if (newMacro.Static) { staticScope.CopyMethod(asMethod); } else { serveObjectScope.CopyMethod(asMethod); } } else { if (newMacro.Static) { staticScope.CopyVariable(newMacro); } else { serveObjectScope.CopyVariable(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 .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)); }