/// <summary> /// Returns all constructors from the given class or struct. /// If no explicit constructor given, an artificial implicit constructor method stub will be created. /// </summary> public static IEnumerable<DMethod> GetConstructors(TemplateIntermediateType ct, bool canCreateExplicitStructCtor = true) { bool foundExplicitCtor = false; // Simply get all constructors that have the ctor id assigned. Makin' it faster ;) var ch = ct.Definition[DMethod.ConstructorIdentifier]; if(ch!=null) foreach (var m in ch) { // Not to forget: 'this' aliases are also possible - so keep checking for m being a genuine ctor var dm = m as DMethod; if (dm!=null && dm.SpecialType == DMethod.MethodType.Constructor) { yield return dm; foundExplicitCtor = true; } } var isStruct = ct is StructType; if (!foundExplicitCtor || isStruct) { // Check if there is an opCall that has no parameters. // Only if no exists, it's allowed to make a default parameter. bool canMakeDefaultCtor = true; foreach(var opCall in GetOpCalls(ct, true)) if(opCall.Parameters == null || opCall.Parameters.Count == 0) { canMakeDefaultCtor = false; break; } if(canMakeDefaultCtor) yield return new DMethod(DMethod.MethodType.Constructor) { Name = DMethod.ConstructorIdentifier, Parent = ct.Definition, Description = "Default constructor for " + ct.Name }; // If struct, there's also a ctor that has all struct members as parameters. // Only, if there are no explicit ctors nor opCalls if (isStruct && !foundExplicitCtor && canCreateExplicitStructCtor) { var l = new List<INode>(); foreach (var member in ct.Definition) { var dv = member as DVariable; if (dv!=null && !dv.IsStatic && !dv.IsAlias && !dv.IsConst) //TODO dunno if public-ness of items is required.. l.Add(dv); } yield return new DMethod(DMethod.MethodType.Constructor) { Name = DMethod.ConstructorIdentifier, Parent = ct.Definition, Description = "Default constructor for struct "+ct.Name, Parameters = l }; } } }
public static TooltipInformation Generate(TemplateIntermediateType tit, int currentParam = -1) { var sb = new StringBuilder("("); if (tit is ClassType) { sb.Append("Class"); } else if (tit is InterfaceType) { sb.Append("Interface"); } else if (tit is TemplateType) { sb.Append("Template"); } else if (tit is StructType) { sb.Append("Struct"); } else if (tit is UnionType) { sb.Append("Union"); } sb.Append(") ").Append(tit.Name); var dc = tit.Definition; if (dc.TemplateParameters != null && dc.TemplateParameters.Length != 0) { sb.Append('('); for (int i = 0; i < dc.TemplateParameters.Length; i++) { if (i == currentParam) { sb.Append("<i>"); } sb.Append(dc.TemplateParameters[i].ToString()); if (i == currentParam) { sb.Append("</i>"); } sb.Append(','); } sb.Remove(sb.Length - 1, 1).Append(')'); } var tti = new TooltipInformation { SignatureMarkup = sb.ToString(), SummaryMarkup = dc.Description, FooterMarkup = dc.ToString(false) }; return(tti); }
public static IEnumerable<DMethod> GetOpCalls(TemplateIntermediateType t, bool staticOnly) { var opCall = t.Definition["opCall"]; if(opCall!=null) foreach(var call in opCall) { var dm = call as DMethod; if(dm != null && (!staticOnly || dm.IsStatic)) yield return dm; } }
void VisitTemplateIntermediateType(TemplateIntermediateType tr) { // Cases: // myVar. (located in basetype definition) <-- Show everything // this. <-- Show everything // myVar. (not located in basetype definition) <-- Show public and public static members // super. <-- Show all base type members // myClass. (not located in myClass) <-- Show all static members // myClass. (located in myClass) <-- Show all static members MemberCompletionEnumeration.EnumChildren(CompletionDataGenerator, ctxt, tr, MemberFilter); GenUfcsAndStaticProperties(tr); }
public StructVis(TemplateIntermediateType structType, List <int> tkn, ICompletionDataGenerator gen, ResolutionContext ctxt) : base(ctxt) { this.alreadyTakenNames = tkn; this.gen = gen; if (CompletionOptions.Instance.ShowStructMembersInStructInitOnly) { this.DeepScanClass(structType, MemberFilter.Variables, false); } else { IterateThroughScopeLayers(CodeLocation.Empty, MemberFilter.All); } }
public static IEnumerable <DMethod> GetOpCalls(TemplateIntermediateType t, bool staticOnly) { var opCall = t.Definition["opCall"]; if (opCall != null) { foreach (var call in opCall) { var dm = call as DMethod; if (dm != null && (!staticOnly || dm.IsStatic)) { yield return(dm); } } } }
public static string GeneratePrototype(TemplateIntermediateType tit, int currentParam = -1) { var sb = new StringBuilder(""); if (tit is ClassType) { sb.Append("Class"); } else if (tit is InterfaceType) { sb.Append("Interface"); } else if (tit is TemplateType) { sb.Append("Template"); } else if (tit is StructType) { sb.Append("Struct"); } else if (tit is UnionType) { sb.Append("Union"); } var dc = tit.Definition; sb.Append(" in "); sb.Append(AbstractNode.GetNodePath(dc, false)); sb.Append(": ").Append(tit.Name); if (dc.TemplateParameters != null && dc.TemplateParameters.Length != 0) { sb.Append('('); for (int i = 0; i < dc.TemplateParameters.Length; i++) { sb.Append(dc.TemplateParameters[i].ToString()); sb.Append(','); } sb.Remove(sb.Length - 1, 1).Append(')'); } return(sb.ToString()); }
/// <summary> /// Returns all constructors from the given class or struct. /// If no explicit constructor given, an artificial implicit constructor method stub will be created. /// </summary> public static IEnumerable<DMethod> GetConstructors(TemplateIntermediateType ct) { bool foundExplicitCtor = false; // Simply get all constructors that have the ctor id assigned. Makin' it faster ;) var ch = ct.Definition[DMethod.ConstructorIdentifier]; if(ch!=null) foreach (var m in ch) { // Not to forget: 'this' aliases are also possible - so keep checking for m being a genuine ctor var dm = m as DMethod; if (m!=null && dm.SpecialType == DMethod.MethodType.Constructor) { yield return dm; foundExplicitCtor = true; } } if (!foundExplicitCtor) yield return new DMethod(DMethod.MethodType.Constructor) { Name = DMethod.ConstructorIdentifier, Parent = ct.Definition, Description = "Default constructor for " + ct.Name }; }
void VisitTemplateIntermediateType(TemplateIntermediateType tr) { if (tr.DeclarationOrExpressionBase is TokenExpression) { var token = ((TokenExpression)tr.DeclarationOrExpressionBase).Token; isVariableInstance = token == DTokens.This || token == DTokens.Super; } // Cases: // myVar. (located in basetype definition) <-- Show everything // this. <-- Show everything // myVar. (not located in basetype definition) <-- Show public and public static members // super. <-- Show all base type members // myClass. (not located in myClass) <-- Show all static members // myClass. (located in myClass) <-- Show all static members MemberCompletionEnumeration.EnumChildren(CompletionDataGenerator, ctxt, tr, isVariableInstance, MemberFilter); GenUfcsAndStaticProperties(tr); }
public static IEnumerable <TemplateIntermediateType> SearchForClassDerivatives(TemplateIntermediateType t, ResolutionContext ctxt) { if (!(t is ClassType || t is InterfaceType)) { throw new ArgumentException("t должно быть классом или интерфейсом, но не " + (t != null ? t.ToString() : "null")); } var f = new ClassInterfaceDerivativeFinder(ctxt); f.typeNodeToFind = t.Definition; var bt = t; while (bt != null) { f.alreadyResolvedClasses.Add(bt.Definition); bt = DResolver.StripMemberSymbols(bt.Base) as TemplateIntermediateType; } var filter = MemberFilter.Classes; if (t is InterfaceType) // -> Only interfaces can inherit interfaces. Interfaces cannot be subclasses of classes. { filter |= MemberFilter.Interfaces; } f.IterateThroughScopeLayers(t.Definition.Location, filter); return(f.results); // return them. }
/// <summary> /// Returns all constructors from the given class or struct. /// If no explicit constructor given, an artificial implicit constructor method stub will be created. /// </summary> public static IEnumerable <DMethod> GetConstructors(TemplateIntermediateType ct) { bool foundExplicitCtor = false; // Simply get all constructors that have the ctor id assigned. Makin' it faster ;) var ch = ct.Definition[DMethod.ConstructorIdentifier]; if (ch != null) { foreach (var m in ch) { // Not to forget: 'this' aliases are also possible - so keep checking for m being a genuine ctor var dm = m as DMethod; if (m != null && dm.SpecialType == DMethod.MethodType.Constructor) { yield return(dm); foundExplicitCtor = true; } } } if (!foundExplicitCtor) { yield return new DMethod(DMethod.MethodType.Constructor) { Name = DMethod.ConstructorIdentifier, Parent = ct.Definition, Description = "Default constructor for " + ct.Name } } ; } ISemantic E(CastExpression ce) { AbstractType castedType = null; if (ce.Type != null) { var castedTypes = TypeDeclarationResolver.Resolve(ce.Type, ctxt); ctxt.CheckForSingleResult(castedTypes, ce.Type); if (castedTypes != null && castedTypes.Length != 0) { castedType = castedTypes[0]; } } else { castedType = AbstractType.Get(E(ce.UnaryExpression)); if (castedType != null && ce.CastParamTokens != null && ce.CastParamTokens.Length > 0) { //TODO: Wrap resolved type with member function attributes } } return(castedType); } ISemantic E(UnaryExpression_Cat x) // a = ~b; { return(E(x.UnaryExpression)); } ISemantic E(UnaryExpression_Increment x) { return(E(x.UnaryExpression)); } ISemantic E(UnaryExpression_Decrement x) { return(E(x.UnaryExpression)); } ISemantic E(UnaryExpression_Add x) { return(E(x.UnaryExpression)); } ISemantic E(UnaryExpression_Sub x) { var v = E(x.UnaryExpression); if (eval) { if (v is AbstractType) { v = DResolver.StripMemberSymbols((AbstractType)v); } if (v is PrimitiveValue) { var pv = (PrimitiveValue)v; return(new PrimitiveValue(pv.BaseTypeToken, -pv.Value, x, -pv.ImaginaryPart)); } } return(v); } ISemantic E(UnaryExpression_Not x) { return(E(x.UnaryExpression)); } ISemantic E(UnaryExpression_Mul x) { return(E(x.UnaryExpression)); } ISemantic E(UnaryExpression_And x) { var ptrBase = E(x.UnaryExpression); if (eval) { // Create a new pointer // } // &i -- makes an int* out of an int return(new PointerType(AbstractType.Get(ptrBase), x)); } ISemantic E(DeleteExpression x) { if (eval) { // Reset the content of the variable } return(null); } ISemantic E(UnaryExpression_Type x) { var uat = x as UnaryExpression_Type; if (uat.Type == null) { return(null); } var types = TypeDeclarationResolver.Resolve(uat.Type, ctxt); ctxt.CheckForSingleResult(types, uat.Type); if (types != null && types.Length != 0) { var id = new IdentifierDeclaration(uat.AccessIdentifier) { EndLocation = uat.EndLocation }; // First off, try to resolve static properties var statProp = StaticPropertyResolver.TryResolveStaticProperties(types[0], uat.AccessIdentifier, ctxt, eval, id); if (statProp != null) { return(statProp); } // If it's not the case, try the conservative way var res = TypeDeclarationResolver.Resolve(id, ctxt, types); ctxt.CheckForSingleResult(res, x); if (res != null && res.Length != 0) { return(res[0]); } } return(null); } }
/// <summary> /// Returns all constructors from the given class or struct. /// If no explicit constructor given, an artificial implicit constructor method stub will be created. /// </summary> public static IEnumerable <DMethod> GetConstructors(TemplateIntermediateType ct, bool canCreateExplicitStructCtor = true) { bool foundExplicitCtor = false; // Simply get all constructors that have the ctor id assigned. Makin' it faster ;) var ch = ct.Definition[DMethod.ConstructorIdentifier]; if (ch != null) { foreach (var m in ch) { // Not to forget: 'this' aliases are also possible - so keep checking for m being a genuine ctor var dm = m as DMethod; if (dm != null && dm.SpecialType == DMethod.MethodType.Constructor) { yield return(dm); foundExplicitCtor = true; } } } var isStruct = ct is StructType; if (!foundExplicitCtor || isStruct) { // Check if there is an opCall that has no parameters. // Only if no exists, it's allowed to make a default parameter. bool canMakeDefaultCtor = true; foreach (var opCall in GetOpCalls(ct, true)) { if (opCall.Parameters == null || opCall.Parameters.Count == 0) { canMakeDefaultCtor = false; break; } } if (canMakeDefaultCtor) { yield return new DMethod(DMethod.MethodType.Constructor) { Name = DMethod.ConstructorIdentifier, Parent = ct.Definition, Description = "Default constructor for " + ct.Name } } ; // If struct, there's also a ctor that has all struct members as parameters. // Only, if there are no explicit ctors nor opCalls if (isStruct && !foundExplicitCtor && canCreateExplicitStructCtor) { var l = new List <INode>(); foreach (var member in ct.Definition) { var dv = member as DVariable; if (dv != null && !dv.IsStatic && !dv.IsAlias && !dv.IsConst) //TODO dunno if public-ness of items is required.. { l.Add(dv); } } yield return(new DMethod(DMethod.MethodType.Constructor) { Name = DMethod.ConstructorIdentifier, Parent = ct.Definition, Description = "Default constructor for struct " + ct.Name, Parameters = l }); } } }
bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r) { /* * TODO: Scan down r for having at least one templateinstanceexpression as declaration base. * If a tix was found, check if the definition of the respective result base level * and the un-aliased identifier of the 'tix' parameter match. * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes), * it is only important that the definition is inside this bundle. * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t! * * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME */ var paramTix_TemplateMatchPossibilities = ResolveTemplateInstanceId(tix); TemplateIntermediateType tixBasedArgumentType = null; var r_ = r as DSymbol; while (r_ != null) { if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression) { var tit = r_ as TemplateIntermediateType; if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition)) { tixBasedArgumentType = tit; break; } } r_ = r_.Base as DSymbol; } /* * This part is very tricky: * I still dunno what is allowed over here-- * * class Foo(T:Bar!E[],E) {} * ... * Foo!(Bar!string[]) f; -- E will be 'string' then * * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar * obviously is not a template instance expression - it's a normal identifier only. */ if (tixBasedArgumentType != null) { var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator(); foreach (var p in tix.Arguments) { if (!argEnum_given.MoveNext() || argEnum_given.Current == null) { return(false); } // Convert p to type declaration var param_Expected = ConvertToTypeDeclarationRoughly(p); if (param_Expected == null) { return(false); } var result_Given = ExpressionTypeEvaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt); if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given)) { return(false); } } // Too many params passed.. if (argEnum_given.MoveNext()) { return(false); } return(true); } return(false); }
static void IterateThroughBaseClassesInterfaces(List <TemplateIntermediateType> l, TemplateIntermediateType tit) { if (tit == null) { return; } var @base = tit.Base as TemplateIntermediateType; if (@base != null) { if (!l.Contains(@base)) { l.Add(@base); } IterateThroughBaseClassesInterfaces(l, @base); } if (tit.BaseInterfaces != null) { foreach (var I in tit.BaseInterfaces) { if (!l.Contains(I)) { l.Add(I); } IterateThroughBaseClassesInterfaces(l, I); } } }
/// <summary> /// Takes the class passed via the tr, and resolves its base class and/or implemented interfaces. /// Also usable for enums. /// /// Never returns null. Instead, the original 'tr' object will be returned if no base class was resolved. /// Will clone 'tr', whereas the new object will contain the base class. /// </summary> public static UserDefinedType ResolveBaseClasses(UserDefinedType tr, ResolverContextStack ctxt, bool ResolveFirstBaseIdOnly = false) { if (bcStack > 8) { bcStack--; return(tr); } if (tr is EnumType) { var et = tr as EnumType; AbstractType bt = null; if (et.Definition.Type == null) { bt = new PrimitiveType(DTokens.Int); } else { if (tr.Definition.Parent is IBlockNode) { ctxt.PushNewScope((IBlockNode)tr.Definition.Parent); } var bts = TypeDeclarationResolver.Resolve(et.Definition.Type, ctxt); if (tr.Definition.Parent is IBlockNode) { ctxt.Pop(); } ctxt.CheckForSingleResult(bts, et.Definition.Type); if (bts != null && bts.Length != 0) { bt = bts[0]; } } return(new EnumType(et.Definition, bt, et.DeclarationOrExpressionBase)); } var dc = tr.Definition as DClassLike; // Return immediately if searching base classes of the Object class if (dc == null || ((dc.BaseClasses == null || dc.BaseClasses.Count < 1) && dc.Name == "Object")) { return(tr); } // If no base class(es) specified, and if it's no interface that is handled, return the global Object reference // -- and do not throw any error message, it's ok if (dc.BaseClasses == null || dc.BaseClasses.Count < 1) { if (tr is ClassType) // Only Classes can inherit from non-interfaces { return(new ClassType(dc, tr.DeclarationOrExpressionBase, ctxt.ParseCache.ObjectClassResult)); } return(tr); } #region Base class & interface resolution TemplateIntermediateType baseClass = null; var interfaces = new List <InterfaceType>(); if (!(tr is ClassType || tr is InterfaceType)) { if (dc.BaseClasses.Count != 0) { ctxt.LogError(dc, "Only classes and interfaces may inherit from other classes/interfaces"); } return(tr); } for (int i = 0; i < (ResolveFirstBaseIdOnly ? 1 : dc.BaseClasses.Count); i++) { var type = dc.BaseClasses[i]; // If there's an explicit 'Object' inheritance, also return the pre-resolved object class if (type is IdentifierDeclaration && ((IdentifierDeclaration)type).Id == "Object") { if (baseClass != null) { ctxt.LogError(new ResolutionError(dc, "Class must not have two base classes")); continue; } else if (i != 0) { ctxt.LogError(new ResolutionError(dc, "The base class name must preceed base interfaces")); continue; } baseClass = ctxt.ParseCache.ObjectClassResult; continue; } if (type == null || type.ToString(false) == dc.Name || dc.NodeRoot == dc) { ctxt.LogError(new ResolutionError(dc, "A class cannot inherit from itself")); continue; } ctxt.PushNewScope(dc.Parent as IBlockNode); bcStack++; var res = TypeDeclarationResolver.Resolve(type, ctxt); ctxt.CheckForSingleResult(res, type); if (res != null && res.Length != 0) { var r = res[0]; if (r is ClassType || r is TemplateType) { if (tr is InterfaceType) { ctxt.LogError(new ResolutionError(type, "An interface cannot inherit from non-interfaces")); } else if (i == 0) { baseClass = (TemplateIntermediateType)r; } else { ctxt.LogError(new ResolutionError(dc, "The base " + (r is ClassType ? "class" : "template") + " name must preceed base interfaces")); } } else if (r is InterfaceType) { interfaces.Add((InterfaceType)r); } else { ctxt.LogError(new ResolutionError(type, "Resolved class is neither a class nor an interface")); continue; } } bcStack--; ctxt.Pop(); } #endregion if (baseClass == null && interfaces.Count == 0) { return(tr); } if (tr is ClassType) { return(new ClassType(dc, tr.DeclarationOrExpressionBase, baseClass, interfaces.Count == 0 ? null : interfaces.ToArray(), tr.DeducedTypes)); } else if (tr is InterfaceType) { return(new InterfaceType(dc, tr.DeclarationOrExpressionBase, interfaces.Count == 0 ? null : interfaces.ToArray(), tr.DeducedTypes)); } // Method should end here return(tr); }
/// <summary> /// Takes the class passed via the tr, and resolves its base class and/or implemented interfaces. /// Also usable for enums. /// /// Never returns null. Instead, the original 'tr' object will be returned if no base class was resolved. /// Will clone 'tr', whereas the new object will contain the base class. /// </summary> public static TemplateIntermediateType ResolveClassOrInterface(DClassLike dc, ResolutionContext ctxt, ISyntaxRegion instanceDeclaration, bool ResolveFirstBaseIdOnly = false, IEnumerable <TemplateParameterSymbol> extraDeducedTemplateParams = null) { if (parsedClassInstanceDecls == null) { parsedClassInstanceDecls = new List <ISyntaxRegion> (); } switch (dc.ClassType) { case DTokens.Class: case DTokens.Interface: break; default: if (dc.BaseClasses.Count != 0) { ctxt.LogError(dc, "Only classes and interfaces may inherit from other classes/interfaces"); } return(null); } bool isClass = dc.ClassType == DTokens.Class; if (bcStack > 6 || (instanceDeclaration != null && parsedClassInstanceDecls.Contains(instanceDeclaration))) { return(isClass ? new ClassType(dc, instanceDeclaration, null) as TemplateIntermediateType : new InterfaceType(dc, instanceDeclaration)); } if (instanceDeclaration != null) { parsedClassInstanceDecls.Add(instanceDeclaration); } bcStack++; var deducedTypes = new DeducedTypeDictionary(dc); var tix = instanceDeclaration as TemplateInstanceExpression; if (tix != null && (ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0) { bool hasUndeterminedArgs; var givenTemplateArguments = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt, out hasUndeterminedArgs); if (!TemplateInstanceHandler.DeduceParams(givenTemplateArguments, false, ctxt, null, dc, deducedTypes)) { parsedClassInstanceDecls.Remove(instanceDeclaration); bcStack--; return(null); } } if (extraDeducedTemplateParams != null) { foreach (var tps in extraDeducedTemplateParams) { deducedTypes[tps.Parameter] = tps; } } if (dc.BaseClasses == null || dc.BaseClasses.Count < 1) { parsedClassInstanceDecls.Remove(instanceDeclaration); bcStack--; // The Object class has no further base class; // Normal class instances have the object as base class; // Interfaces must not have any default base class/interface return(isClass ? new ClassType(dc, instanceDeclaration, dc.NameHash != ObjectNameHash ? ctxt.ParseCache.ObjectClassResult : null, null, deducedTypes.Count != 0 ? deducedTypes.ToReadonly() : null) : new InterfaceType(dc, instanceDeclaration, null, deducedTypes.Count != 0 ? deducedTypes.ToReadonly() : null) as TemplateIntermediateType); } #region Base class & interface resolution AbstractType[] res; var pop = ctxt.ScopedBlock != dc.Parent; if (pop) { ctxt.PushNewScope(dc.Parent as IBlockNode); } foreach (var kv in deducedTypes) { ctxt.CurrentContext.DeducedTemplateParameters[kv.Key] = kv.Value; } TemplateIntermediateType baseClass = null; var interfaces = new List <InterfaceType>(); try { for (int i = 0; i < (ResolveFirstBaseIdOnly ? 1 : dc.BaseClasses.Count); i++) { var type = dc.BaseClasses[i]; // If there's an explicit 'Object' inheritance, also return the pre-resolved object class if (type is IdentifierDeclaration && (type as IdentifierDeclaration).IdHash == ObjectNameHash) { if (baseClass != null) { ctxt.LogError(new ResolutionError(dc, "Class must not have two base classes")); continue; } else if (i != 0) { ctxt.LogError(new ResolutionError(dc, "The base class name must preceed base interfaces")); continue; } baseClass = ctxt.ParseCache.ObjectClassResult; continue; } if (type == null || (type is IdentifierDeclaration && (type as IdentifierDeclaration).IdHash == dc.NameHash) || dc.NodeRoot == dc) { ctxt.LogError(new ResolutionError(dc, "A class cannot inherit from itself")); continue; } res = DResolver.StripAliasSymbols(TypeDeclarationResolver.Resolve(type, ctxt)); ctxt.CheckForSingleResult(res, type); if (res != null && res.Length != 0) { var r = res[0]; if (r is ClassType || r is TemplateType) { if (!isClass) { ctxt.LogError(new ResolutionError(type, "An interface cannot inherit from non-interfaces")); } else if (i == 0) { baseClass = r as TemplateIntermediateType; } else { ctxt.LogError(new ResolutionError(dc, "The base " + (r is ClassType ? "class" : "template") + " name must preceed base interfaces")); } } else if (r is InterfaceType) { interfaces.Add(r as InterfaceType); if (isClass && dc.NameHash != ObjectNameHash && baseClass == null) { baseClass = ctxt.ParseCache.ObjectClassResult; } } else { ctxt.LogError(new ResolutionError(type, "Resolved class is neither a class nor an interface")); continue; } } } } finally { bcStack--; parsedClassInstanceDecls.Remove(instanceDeclaration); } if (pop) { ctxt.Pop(); } else { foreach (var kv in deducedTypes) // May be backup old tps? { ctxt.CurrentContext.DeducedTemplateParameters.Remove(kv.Key); } } #endregion if (isClass) { return(new ClassType(dc, instanceDeclaration, baseClass, interfaces.Count == 0 ? null : interfaces.ToArray(), deducedTypes.Count != 0 ? deducedTypes.ToReadonly() : null)); } return(new InterfaceType(dc, instanceDeclaration, interfaces.Count == 0 ? null : interfaces.ToArray(), deducedTypes.Count != 0 ? deducedTypes.ToReadonly() : null)); }
bool HandleAliasThisDeclarations(TemplateIntermediateType tit, MemberFilter vis) { bool pop; var ch = tit.Definition [DVariable.AliasThisIdentifierHash]; if(ch != null){ foreach (DVariable aliasDef in ch) { if (MatchesCompilationConditions(aliasDef) || aliasDef.Type == null) continue; pop = ctxt.ScopedBlock != tit.Definition; if (pop) ctxt.PushNewScope (tit.Definition); // Resolve the aliased symbol and expect it to be a member symbol(?). //TODO: Check if other cases are allowed as well! var aliasedSymbol = DResolver.StripAliasSymbol(TypeDeclarationResolver.ResolveSingle (aliasDef.Type, ctxt)); var aliasedMember = aliasedSymbol as MemberSymbol; if (pop) ctxt.Pop (); if (aliasedMember == null) { if (aliasedSymbol != null) ctxt.LogError (aliasDef, "Aliased type from 'alias this' definition is expected to be a type instance, not "+aliasedSymbol.ToString()+"!"); continue; } /* * The aliased member's type can be everything! */ aliasedSymbol = aliasedMember.Base; foreach (var statProp in StaticProperties.ListProperties (aliasedSymbol)) if (HandleItem (statProp)) return true; /** TODO: Visit ufcs recommendations and other things that * become added in e.g. MemberCompletionProvider */ var tit_ = aliasedSymbol as TemplateIntermediateType; if(tit_ != null) { pop = !ctxt.ScopedBlockIsInNodeHierarchy(tit_.Definition); if(pop) ctxt.PushNewScope(tit_.Definition); ctxt.CurrentContext.IntroduceTemplateParameterTypes(tit_); var r = DeepScanClass(tit_, vis, true); if(pop) ctxt.Pop(); else ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(tit_); if(r) return true; } } } return false; }
bool HandleAliasThisDeclarations(TemplateIntermediateType tit, MemberFilter vis) { bool pop; var ch = tit.Definition [DVariable.AliasThisIdentifierHash]; if (ch != null) { foreach (DVariable aliasDef in ch) { if (MatchesCompilationConditions(aliasDef) || aliasDef.Type == null) { continue; } pop = ctxt.ScopedBlock != tit.Definition; if (pop) { ctxt.PushNewScope(tit.Definition); } // Resolve the aliased symbol and expect it to be a member symbol(?). //TODO: Check if other cases are allowed as well! var aliasedSymbol = DResolver.StripAliasSymbol(TypeDeclarationResolver.ResolveSingle(aliasDef.Type, ctxt)); var aliasedMember = aliasedSymbol as MemberSymbol; if (pop) { ctxt.Pop(); } if (aliasedMember == null) { if (aliasedSymbol != null) { ctxt.LogError(aliasDef, "Aliased type from 'alias this' definition is expected to be a type instance, not " + aliasedSymbol.ToString() + "!"); } continue; } /* * The aliased member's type can be everything! */ aliasedSymbol = aliasedMember.Base; foreach (var statProp in StaticProperties.ListProperties(aliasedSymbol)) { if (HandleItem(statProp)) { return(true); } } /** TODO: Visit ufcs recommendations and other things that * become added in e.g. MemberCompletionProvider */ var tit_ = aliasedSymbol as TemplateIntermediateType; if (tit_ != null) { pop = !ctxt.ScopedBlockIsInNodeHierarchy(tit_.Definition); if (pop) { ctxt.PushNewScope(tit_.Definition); } ctxt.CurrentContext.IntroduceTemplateParameterTypes(tit_); var r = DeepScanClass(tit_, vis, true); if (pop) { ctxt.Pop(); } else { ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(tit_); } if (r) { return(true); } } } } return(false); }