public AbstractType TryDeduce(DSymbol ds, IEnumerable <ISemantic> templateArguments, ref INode returnedNode) { var cls = ds as ClassType; if (cls == null || templateArguments == null) { return(null); } var en = templateArguments.GetEnumerator(); if (!en.MoveNext()) { return(null); } returnedNode = cls.Definition; var baseClass = DResolver.StripMemberSymbols(AbstractType.Get(en.Current)) as TemplateIntermediateType; if (baseClass == null) { return(ds); } return(new ClassType(cls.Definition, ds.DeclarationOrExpressionBase, baseClass as ClassType, baseClass is InterfaceType ? new[] { baseClass as InterfaceType } : null, ds.DeducedTypes)); }
private static bool DeduceParams(IEnumerable <ISemantic> givenTemplateArguments, bool isMethodCall, ResolutionContext ctxt, DSymbol overload, DNode tplNode, DeducedTypeDictionary deducedTypes) { bool isLegitOverload = true; var paramEnum = tplNode.TemplateParameters.GetEnumerator(); var args = givenTemplateArguments ?? new List <ISemantic> (); var argEnum = args.GetEnumerator(); foreach (var expectedParam in tplNode.TemplateParameters) { if (!DeduceParam(ctxt, overload, deducedTypes, argEnum, expectedParam)) { isLegitOverload = false; break; // Don't check further params if mismatch has been found } } if (!isMethodCall && argEnum.MoveNext()) { // There are too many arguments passed - discard this overload isLegitOverload = false; } return(isLegitOverload); }
public DeducedTypeDictionary(DSymbol ms) { ExpectedParameters = ms.Definition.TemplateParameters; if (ms.DeducedTypes != null) { foreach (var i in ms.DeducedTypes) { this.Add(i.NameHash, i); } } }
public DeducedTypeDictionary(DSymbol ms) : this(ms.ValidSymbol ? ms.Definition.TemplateParameters : null) { if (ms.DeducedTypes != null) { foreach (var i in ms.DeducedTypes) { if (i != null) { this [i.Parameter] = i; } } } }
public static AbstractType TryDeduce(DSymbol t, IEnumerable<ISemantic> templateArguments, out bool supersedeOtherOverloads) { var def = t.Definition; IHook hook; if (def != null && DeductionHooks.TryGetValue(AbstractNode.GetNodePath(def, true), out hook)) { supersedeOtherOverloads = hook.SupersedesMultipleOverloads; return hook.TryDeduce(t, templateArguments); } supersedeOtherOverloads = true; return null; }
public AbstractType TryDeduce (DSymbol ds, IEnumerable<ISemantic> templateArguments, ref INode returnedNode) { var cls= ds as ClassType; if (cls == null || templateArguments == null) return null; var en = templateArguments.GetEnumerator (); if (!en.MoveNext ()) return null; returnedNode = cls.Definition; var baseClass = DResolver.StripMemberSymbols(AbstractType.Get(en.Current)) as TemplateIntermediateType; if (baseClass == null) return ds; return new ClassType(cls.Definition, baseClass as ClassType, baseClass is InterfaceType ? new[] {baseClass as InterfaceType} : null, ds.DeducedTypes); }
public static AbstractType TryDeduce(DSymbol t, IEnumerable <ISemantic> templateArguments, out bool supersedeOtherOverloads) { var def = t.Definition; IHook hook; if (def != null && DeductionHooks.TryGetValue(AbstractNode.GetNodePath(def, true), out hook)) { supersedeOtherOverloads = hook.SupersedesMultipleOverloads; INode n = null; var res = hook.TryDeduce(t, templateArguments, ref n); if (n != null) { resultStore.Add(res, n); } return(res); } supersedeOtherOverloads = true; return(null); }
private static bool DeduceParam(ResolutionContext ctxt, DSymbol overload, DeducedTypeDictionary deducedTypes, IEnumerator <ISemantic> argEnum, TemplateParameter expectedParam) { if (expectedParam is TemplateThisParameter && overload.Base != null) { var ttp = (TemplateThisParameter)expectedParam; // Get the type of the type of 'this' - so of the result that is the overload's base var t = DResolver.StripMemberSymbols(overload.Base); if (t == null || t.DeclarationOrExpressionBase == null) { return(false); } //TODO: Still not sure if it's ok to pass a type result to it // - looking at things like typeof(T) that shall return e.g. const(A) instead of A only. if (!CheckAndDeduceTypeAgainstTplParameter(ttp, t, deducedTypes, ctxt)) { return(false); } return(true); } // Used when no argument but default arg given bool useDefaultType = false; if (argEnum.MoveNext() || (useDefaultType = HasDefaultType(expectedParam))) { // On tuples, take all following arguments and pass them to the check function if (expectedParam is TemplateTupleParameter) { var tupleItems = new List <ISemantic>(); // A tuple must at least contain one item! tupleItems.Add(argEnum.Current); while (argEnum.MoveNext()) { tupleItems.Add(argEnum.Current); } if (!CheckAndDeduceTypeTuple((TemplateTupleParameter)expectedParam, tupleItems, deducedTypes, ctxt)) { return(false); } } else if (argEnum.Current != null) { if (!CheckAndDeduceTypeAgainstTplParameter(expectedParam, argEnum.Current, deducedTypes, ctxt)) { return(false); } } else if (useDefaultType && CheckAndDeduceTypeAgainstTplParameter(expectedParam, null, deducedTypes, ctxt)) { // It's legit - just do nothing } else { return(false); } } else if (expectedParam is TemplateTupleParameter) { if (!CheckAndDeduceTypeTuple(expectedParam as TemplateTupleParameter, null, deducedTypes, ctxt)) { return(false); } } // There might be too few args - but that doesn't mean that it's not correct - it's only required that all parameters got satisfied with a type else if (!deducedTypes.AllParamatersSatisfied) { return(false); } return(true); }
public static ISymbolValue TryEvaluate(DSymbol t, IEnumerable<ISemantic> templateArgs) { return null; }
public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol) { DSymbol ds = null; mightBeLegalUnresolvableSymbol = false; if (string.IsNullOrWhiteSpace(symName)) { return(null); } // Try to handle a probably mangled string or C function. if (symName.StartsWith("_")) { try{ ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol; }catch {} } // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[]) if (ds == null && Lexer.IsIdentifierPart((int)symName[0])) { mightBeLegalUnresolvableSymbol = true; ITypeDeclaration q; var method = DParser.ParseMethodDeclarationHeader(symName, out q); q = Demangler.RemoveNestedTemplateRefsFromQualifier(q); method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type); var methodType = TypeDeclarationResolver.GetMethodReturnType(method, ctxt); var methodParameters = new List <AbstractType>(); if (method.Parameters != null && method.Parameters.Count != 0) { foreach (var parm in method.Parameters) { methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt)); } } ctxt.ContextIndependentOptions |= ResolutionOptions.IgnoreAllProtectionAttributes; var overloads = TypeDeclarationResolver.Resolve(q, ctxt); if (overloads == null || overloads.Length == 0) { return(null); } else if (overloads.Length == 1) { ds = overloads[0] as DSymbol; } else { foreach (var o in overloads) { ds = o as DSymbol; if (ds == null || !(ds.Definition is DMethod)) { continue; } var dm = ds.Definition as DMethod; // Compare return types if (dm.Type != null) { if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base)) { continue; } } else if (dm.Type == null && methodType != null) { return(null); } // Compare parameters if (methodParameters.Count != dm.Parameters.Count) { continue; } for (int i = 0; i < methodParameters.Count; i++) { if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt))) { continue; } } } } } if (ds != null) { return(ds.Definition); } return(null); }
/// <summary> /// Scans a block node. Not working with DMethods. /// Automatically resolves node matches so base types etc. will be specified directly after the search operation. /// </summary> public static List <AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, int nameHash, ISyntaxRegion idObject = null) { var scan = new SingleNodeNameScan(ctxt, nameHash, idObject); if (t is TemplateIntermediateType) { scan.DeepScanClass(t as UserDefinedType, MemberFilter.All); } else if (t.Definition is IBlockNode) { scan.ScanBlock(t.Definition as IBlockNode, CodeLocation.Empty, MemberFilter.All); } return(scan.matches_types); }
private static bool DeduceParam(ResolutionContext ctxt, DSymbol overload, DeducedTypeDictionary deducedTypes, IEnumerator<ISemantic> argEnum, TemplateParameter expectedParam) { if (expectedParam is TemplateThisParameter && overload.Base != null) { var ttp = (TemplateThisParameter)expectedParam; // Get the type of the type of 'this' - so of the result that is the overload's base var t = DResolver.StripMemberSymbols(overload.Base); if (t == null || t.DeclarationOrExpressionBase == null) return false; //TODO: Still not sure if it's ok to pass a type result to it // - looking at things like typeof(T) that shall return e.g. const(A) instead of A only. if (!CheckAndDeduceTypeAgainstTplParameter(ttp, t, deducedTypes, ctxt)) return false; return true; } // Used when no argument but default arg given bool useDefaultType = false; if (argEnum.MoveNext() || (useDefaultType = HasDefaultType(expectedParam))) { // On tuples, take all following arguments and pass them to the check function if (expectedParam is TemplateTupleParameter) { var tupleItems = new List<ISemantic>(); // A tuple must at least contain one item! tupleItems.Add(argEnum.Current); while (argEnum.MoveNext()) tupleItems.Add(argEnum.Current); if (!CheckAndDeduceTypeTuple((TemplateTupleParameter)expectedParam, tupleItems, deducedTypes, ctxt)) return false; } else if (argEnum.Current != null) { if (!CheckAndDeduceTypeAgainstTplParameter(expectedParam, argEnum.Current, deducedTypes, ctxt)) return false; } else if (useDefaultType && CheckAndDeduceTypeAgainstTplParameter(expectedParam, null, deducedTypes, ctxt)) { // It's legit - just do nothing } else return false; } else if(expectedParam is TemplateTupleParameter) { if(!CheckAndDeduceTypeTuple(expectedParam as TemplateTupleParameter, null, deducedTypes, ctxt)) return false; } // There might be too few args - but that doesn't mean that it's not correct - it's only required that all parameters got satisfied with a type else if (!deducedTypes.AllParamatersSatisfied) return false; return true; }
/// <summary> /// Scans a block node. Not working with DMethods. /// Automatically resolves node matches so base types etc. will be specified directly after the search operation. /// </summary> public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, int nameHash, ISyntaxRegion idObject = null) { var scan = new SingleNodeNameScan(ctxt, nameHash, idObject); if (t is TemplateIntermediateType) scan.DeepScanClass(t as UserDefinedType, MemberFilter.All); else if (t.Definition is IBlockNode) scan.ScanBlock(t.Definition as IBlockNode, CodeLocation.Empty, MemberFilter.All); return scan.matches_types; }
public AbstractType TryDeduce(DSymbol ds, IEnumerable <ISemantic> templateArguments, ref INode n) { TemplateTypeParameter tp; var t = ds as TemplateType; if (t == null) { return(null); } var orig = ds.Definition; var tupleStruct = new DClassLike(DTokens.Struct) { NameHash = ds.NameHash, Parent = orig.Parent, Location = orig.Location, EndLocation = orig.EndLocation, NameLocation = orig.NameLocation }; var ded = new Templates.DeducedTypeDictionary(tupleStruct); if (templateArguments != null) { var typeList = new List <AbstractType>(); var en = templateArguments.GetEnumerator(); if (en.MoveNext()) { var next = en.Current; int i = 0; for (; ; i++) { var fieldType = AbstractType.Get(next); if (fieldType == null) { break; } fieldType.NonStaticAccess = true; typeList.Add(fieldType); if (!en.MoveNext()) { break; } next = en.Current; if (next is ArrayValue && (next as ArrayValue).IsString) { var name = (next as ArrayValue).StringValue; var templateParamName = "_" + i.ToString(); tp = new TemplateTypeParameter(templateParamName, CodeLocation.Empty, tupleStruct); ded[tp] = new TemplateParameterSymbol(tp, fieldType); tupleStruct.Add(new DVariable { Name = name, Type = new IdentifierDeclaration(templateParamName) }); if (!en.MoveNext()) { break; } next = en.Current; } } } var tupleName = "Types"; tp = new TemplateTypeParameter(tupleName, CodeLocation.Empty, tupleStruct); ded[tp] = new TemplateParameterSymbol(tp, new DTuple(null, typeList)); tupleStruct.Add(new DVariable { NameHash = DVariable.AliasThisIdentifierHash, IsAlias = true, IsAliasThis = true, Type = new IdentifierDeclaration(tupleName) }); } n = tupleStruct; return(new StructType(tupleStruct, ds.DeclarationOrExpressionBase, ded.Count != 0 ? ded.Values : null)); //TODO: Ensure renaming and other AST-based things run properly }
public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol) { DSymbol ds = null; mightBeLegalUnresolvableSymbol = false; if (string.IsNullOrWhiteSpace(symName)) { return(null); } // Try to handle a probably mangled string or C function. if (symName.StartsWith("_")) { try{ ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol; }catch {} } // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[]) if (ds == null && Lexer.IsIdentifierPart((int)symName[0])) { mightBeLegalUnresolvableSymbol = true; ITypeDeclaration q; var method = DParser.ParseMethodDeclarationHeader(symName, out q); q = Demangler.RemoveNestedTemplateRefsFromQualifier(q); AbstractType[] overloads = null; D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => { try { overloads = AmbiguousType.TryDissolve(LooseResolution.LookupIdRawly(ctxt.ParseCache, q, ctxt.ScopedBlock.NodeRoot as DModule)).ToArray(); } catch (Exception ex) { MonoDevelop.Core.LoggingService.LogWarning("Error during trace.log symbol resolution of " + q.ToString(), ex); } }); if (overloads == null || overloads.Length == 0) { return(null); } else if (overloads.Length == 1) { ds = overloads[0] as DSymbol; } else { method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type); var methodType = TypeDeclarationResolver.GetMethodReturnType(method, ctxt); var methodParameters = new List <AbstractType>(); D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => { if (method.Parameters != null && method.Parameters.Count != 0) { foreach (var parm in method.Parameters) { methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt)); } } }); foreach (var o in overloads) { ds = o as DSymbol; if (ds == null || !(ds.Definition is DMethod)) { continue; } var dm = ds.Definition as DMethod; // Compare return types if (dm.Type != null) { if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base)) { continue; } } else if (dm.Type == null && methodType != null) { return(null); } // Compare parameters if (methodParameters.Count != dm.Parameters.Count) { continue; } for (int i = 0; i < methodParameters.Count; i++) { if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt))) { continue; } } } } } return(ds != null ? ds.Definition : null); }
public AbstractType TryDeduce(DSymbol ds, IEnumerable<ISemantic> templateArguments, ref INode n) { TemplateTypeParameter tp; var t = ds as TemplateType; if (t == null) return null; var orig = ds.Definition; var tupleStruct = new DClassLike(DTokens.Struct) { NameHash = ds.NameHash, Parent = orig.Parent, Location = orig.Location, EndLocation = orig.EndLocation, NameLocation = orig.NameLocation }; var ded = new Templates.DeducedTypeDictionary(tupleStruct); var sb = new StringBuilder(); if (templateArguments != null) { var en = templateArguments.GetEnumerator(); if (en.MoveNext()) { var next = en.Current; int i = 0; for (; ; i++) { var fieldType = AbstractType.Get(next); if (fieldType == null) break; fieldType.NonStaticAccess = true; if (!en.MoveNext()) break; next = en.Current; if (next is ArrayValue && (next as ArrayValue).IsString) { var name = (next as ArrayValue).StringValue; if (!string.IsNullOrWhiteSpace(name)) { var templateParamName = "_" + i.ToString(); tp = new TemplateTypeParameter(templateParamName, CodeLocation.Empty, tupleStruct); ded[tp] = new TemplateParameterSymbol(tp, fieldType); // getter sb.Append("@property @safe ").Append(templateParamName).Append(' ').Append(name).AppendLine("() pure nothrow const {}"); // setter sb.Append("@property @safe void ").Append(name).AppendLine("(").Append(templateParamName).AppendLine(" v) pure nothrow {}"); // constants sb.Append("enum ").Append(templateParamName).Append(" ").Append(name).Append("_min = cast(").Append(templateParamName).AppendLine(") 0;"); sb.Append("enum ").Append(templateParamName).Append(" ").Append(name).Append("_max = cast(").Append(templateParamName).AppendLine(") 0;"); } if (!en.MoveNext()) break; } else break; if (!en.MoveNext()) // Skip offset break; next = en.Current; } } tupleStruct.Add(new DVariable { NameHash = tupleStruct.NameHash, Attributes = new List<DAttribute> { new Modifier(DTokens.Enum) }, Initializer = new IdentifierExpression(sb.ToString(), LiteralFormat.StringLiteral, LiteralSubformat.Utf8) }); } n = tupleStruct; return new TemplateType(tupleStruct, ded.Count != 0 ? ded.Values : null); }
protected void Handle(ISyntaxRegion o, DSymbol resolvedSymbol) { if (o is IdentifierDeclaration) { var id = (IdentifierDeclaration)o; if (id.Id != searchId) { return; } if (resolvedSymbol == null) { resolvedSymbol = TypeDeclarationResolver.ResolveSingle(id, ctxt) as DSymbol; } } else if (o is TemplateInstanceExpression) { var tix = (TemplateInstanceExpression)o; if (tix.TemplateIdentifier.Id != searchId) { return; } if (resolvedSymbol == null) { resolvedSymbol = Evaluation.EvaluateType(tix, ctxt) as DSymbol; } } else if (o is IdentifierExpression) { var id = (IdentifierExpression)o; if ((string)id.Value != searchId) { return; } if (resolvedSymbol == null) { resolvedSymbol = Evaluation.EvaluateType(id, ctxt) as DSymbol; } } else if (o is PostfixExpression_Access) { var acc = (PostfixExpression_Access)o; if ((acc.AccessExpression is IdentifierExpression && (string)((IdentifierExpression)acc.AccessExpression).Value != searchId) || (acc.AccessExpression is TemplateInstanceExpression && (string)((TemplateInstanceExpression)acc.AccessExpression).TemplateIdentifier.Id != searchId)) { Handle(acc.PostfixForeExpression, null); return; } else if (acc.AccessExpression is NewExpression) { var nex = (NewExpression)acc.AccessExpression; if ((nex.Type is IdentifierDeclaration && ((IdentifierDeclaration)nex.Type).Id != searchId) || (nex.Type is TemplateInstanceExpression && (string)((TemplateInstanceExpression)acc.AccessExpression).TemplateIdentifier.Id != searchId)) { Handle(acc.PostfixForeExpression, null); return; } // Are there other types to test for? } var s = resolvedSymbol ?? Evaluation.EvaluateType(acc, ctxt) as DerivedDataType; if (s is DSymbol) { if (((DSymbol)s).Definition == symbol) { l.Add(acc.AccessExpression); } } else if (s == null || !(s.Base is DSymbol)) { return; } // Scan down for other possible symbols Handle(acc.PostfixForeExpression, s.Base as DSymbol); return; } // The resolved node must be equal to the symbol definition that is looked for. if (resolvedSymbol == null || resolvedSymbol.Definition != symbol) { return; } l.Add(o); }
/* public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, string name, ISyntaxRegion idObject = null) { return SearchChildrenAndResolve (ctxt, block, name.GetHashCode(), idObject); } /// <summary> /// Scans a block node. Not working with DMethods. /// Automatically resolves node matches so base types etc. will be specified directly after the search operation. /// </summary> public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, int nameHash, ISyntaxRegion idObject = null) { var scan = new SingleNodeNameScan(ctxt, nameHash, idObject); scan.ScanBlock(block, CodeLocation.Empty, MemberFilter.All); return scan.matches_types; }*/ public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, string name, ISyntaxRegion idObject = null) { return SearchChildrenAndResolve(ctxt, t, name.GetHashCode(), idObject); }
public AbstractType TryDeduce(DSymbol ds, IEnumerable<ISemantic> templateArguments) { TemplateTypeParameter tp; var t = ds as TemplateType; if (t == null) return null; var orig = ds.Definition; var tupleStruct = new DClassLike(DTokens.Struct) { NameHash = ds.NameHash, Parent = orig.Parent, Location = orig.Location, EndLocation = orig.EndLocation, NameLocation = orig.NameLocation }; var ded = new Templates.DeducedTypeDictionary(tupleStruct); if (templateArguments != null) { var typeList = new List<AbstractType>(); var en = templateArguments.GetEnumerator(); if(en.MoveNext()) { var next = en.Current; int i = 0; for (; ; i++) { var fieldType = AbstractType.Get(next); if (fieldType == null) break; fieldType.NonStaticAccess = true; typeList.Add(fieldType); if (!en.MoveNext()) break; next = en.Current; if (next is ArrayValue && (next as ArrayValue).IsString) { var name = (next as ArrayValue).StringValue; var templateParamName = "_" + i.ToString(); tp = new TemplateTypeParameter(templateParamName, CodeLocation.Empty, tupleStruct); ded[tp] = new TemplateParameterSymbol(tp, fieldType); tupleStruct.Add(new DVariable { Name = name, Type = new IdentifierDeclaration(templateParamName) }); if (!en.MoveNext()) break; next = en.Current; } } } var tupleName = "Types"; tp = new TemplateTypeParameter(tupleName, CodeLocation.Empty, tupleStruct); ded[tp] = new TemplateParameterSymbol(tp, new DTuple(null, typeList)); tupleStruct.Add(new DVariable { NameHash = DVariable.AliasThisIdentifierHash, IsAlias = true, IsAliasThis = true, Type = new IdentifierDeclaration(tupleName) }); } var res = new StructType(tupleStruct, ds.DeclarationOrExpressionBase, ded.Count != 0 ? ded.Values : null); resultStore.Add(res, tupleStruct); //TODO: Ensure renaming and other AST-based things run properly return res; }
public AbstractType TryDeduce(DSymbol ds, IEnumerable <ISemantic> templateArguments, ref INode n) { TemplateTypeParameter tp; var t = ds as TemplateType; if (t == null) { return(null); } var orig = ds.Definition; var tupleStruct = new DClassLike(DTokens.Struct) { NameHash = ds.NameHash, Parent = orig.Parent, Location = orig.Location, EndLocation = orig.EndLocation, NameLocation = orig.NameLocation }; var ded = new Templates.DeducedTypeDictionary(tupleStruct); var sb = new StringBuilder(); if (templateArguments != null) { var en = templateArguments.GetEnumerator(); if (en.MoveNext()) { var next = en.Current; int i = 0; for (; ; i++) { var fieldType = AbstractType.Get(next); if (fieldType == null) { break; } fieldType.NonStaticAccess = true; if (!en.MoveNext()) { break; } next = en.Current; if (next is ArrayValue && (next as ArrayValue).IsString) { var name = (next as ArrayValue).StringValue; if (!string.IsNullOrWhiteSpace(name)) { var templateParamName = "_" + i.ToString(); tp = new TemplateTypeParameter(templateParamName, CodeLocation.Empty, tupleStruct); ded[tp] = new TemplateParameterSymbol(tp, fieldType); // getter sb.Append("@property @safe ").Append(templateParamName).Append(' ').Append(name).AppendLine("() pure nothrow const {}"); // setter sb.Append("@property @safe void ").Append(name).AppendLine("(").Append(templateParamName).AppendLine(" v) pure nothrow {}"); // constants sb.Append("enum ").Append(templateParamName).Append(" ").Append(name).Append("_min = cast(").Append(templateParamName).AppendLine(") 0;"); sb.Append("enum ").Append(templateParamName).Append(" ").Append(name).Append("_max = cast(").Append(templateParamName).AppendLine(") 0;"); } if (!en.MoveNext()) { break; } } else { break; } if (!en.MoveNext()) // Skip offset { break; } next = en.Current; } } tupleStruct.Add(new DVariable { NameHash = tupleStruct.NameHash, Attributes = new List <DAttribute> { new Modifier(DTokens.Enum) }, Initializer = new IdentifierExpression(sb.ToString(), LiteralFormat.StringLiteral, LiteralSubformat.Utf8) }); } n = tupleStruct; return(new TemplateType(tupleStruct, ds.DeclarationOrExpressionBase, ded.Count != 0 ? ded.Values : null)); }
/* * public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, string name, ISyntaxRegion idObject = null) * { * return SearchChildrenAndResolve (ctxt, block, name.GetHashCode(), idObject); * } * * /// <summary> * /// Scans a block node. Not working with DMethods. * /// Automatically resolves node matches so base types etc. will be specified directly after the search operation. * /// </summary> * public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, int nameHash, ISyntaxRegion idObject = null) * { * var scan = new SingleNodeNameScan(ctxt, nameHash, idObject); * * scan.ScanBlock(block, CodeLocation.Empty, MemberFilter.All); * * return scan.matches_types; * }*/ public static List <AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, string name, ISyntaxRegion idObject = null) { return(SearchChildrenAndResolve(ctxt, t, name.GetHashCode(), idObject)); }
private static bool DeduceParams(IEnumerable<ISemantic> givenTemplateArguments, bool isMethodCall, ResolutionContext ctxt, DSymbol overload, DNode tplNode, DeducedTypeDictionary deducedTypes) { bool isLegitOverload = true; var paramEnum = tplNode.TemplateParameters.GetEnumerator(); var args = givenTemplateArguments ?? new List<ISemantic> (); var argEnum = args.GetEnumerator(); foreach (var expectedParam in tplNode.TemplateParameters) if (!DeduceParam(ctxt, overload, deducedTypes, argEnum, expectedParam)) { isLegitOverload = false; break; // Don't check further params if mismatch has been found } if (!isMethodCall && argEnum.MoveNext()) { // There are too many arguments passed - discard this overload isLegitOverload = false; } return isLegitOverload; }
private static bool DeduceParams(IEnumerable<ISemantic> givenTemplateArguments, bool isMethodCall, ResolverContextStack ctxt, DSymbol overload, DNode tplNode, DeducedTypeDictionary deducedTypes) { bool isLegitOverload = true; var paramEnum = tplNode.TemplateParameters.GetEnumerator(); var args= givenTemplateArguments == null ? new List<ISemantic>() : givenTemplateArguments; if (overload is MemberSymbol && ((MemberSymbol)overload).IsUFCSResult){ var l = new List<ISemantic>(); l.Add(overload.Base); // The base stores the first argument('s type) l.AddRange(args); args = l; } var argEnum = args.GetEnumerator(); foreach (var expectedParam in tplNode.TemplateParameters) if (!DeduceParam(ctxt, overload, deducedTypes, argEnum, expectedParam)) { isLegitOverload = false; break; // Don't check further params if mismatch has been found } if (!isMethodCall && argEnum.MoveNext()) { // There are too many arguments passed - discard this overload isLegitOverload = false; } return isLegitOverload; }