/// <summary> /// Returns false if the item has already been set before and if the already set item is not equal to 'r'. /// Inserts 'r' into the target dictionary and returns true otherwise. /// </summary> bool Set(ITemplateParameter p, ISemantic r, string name = null) { if (string.IsNullOrEmpty(name)) { name = p.Name; } TemplateParameterSymbol rl = null; if (!TargetDictionary.TryGetValue(name, out rl) || rl == null) { TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner); return(true); } else { if (rl != null) { if (ResultComparer.IsEqual(rl.Base, r)) { return(true); } else { // Error: Ambiguous assignment } } TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner); return(false); } }
static bool CheckAndDeduceTypeAgainstTplParameter(ITemplateParameter handledParameter, ISemantic argumentToCheck, DeducedTypeDictionary deducedTypes, ResolverContextStack ctxt) { return(new Templates.TemplateParameterDeduction(deducedTypes, ctxt).Handle(handledParameter, argumentToCheck)); }
// Checks if the input parameter value is a valid choice for the parameter, and returns the canonical value, or defaultValue if there is no appropriate canonical value. // If the parameter or value is null, return defaultValue. // For this to return other than the defaultValue, one of these must occur: // - the input value must either exactly match one of the choices (case-insensitive) // - there must be exactly one choice value starting with the input value (case-insensitive). public static string GetCanonicalValueForChoiceParamOrDefault(ITemplateInfo template, string paramName, string inputParamValue, string defaultValue = null) { if (string.IsNullOrEmpty(paramName) || string.IsNullOrEmpty(inputParamValue)) { return(defaultValue); } ITemplateParameter parameter = template.Parameters.FirstOrDefault(x => string.Equals(x.Name, paramName, StringComparison.Ordinal)); if (parameter == null || parameter.Choices == null || parameter.Choices.Count == 0) { return(defaultValue); } // This is a case-insensitive key lookup, because that is how Choices is initialized. if (parameter.Choices.ContainsKey(inputParamValue)) { return(inputParamValue); } IReadOnlyList <string> startsWithChoices = parameter.Choices.Where(x => x.Key.StartsWith(inputParamValue, StringComparison.OrdinalIgnoreCase)).Select(x => x.Key).ToList(); if (startsWithChoices.Count == 1) { return(startsWithChoices[0]); } return(defaultValue); }
bool IsMoreSpecialized(ITemplateParameter t1, ITemplateParameter t2, Dictionary <string, ISemantic> t1_dummyParameterList) { if (t1 is TemplateTypeParameter && t2 is TemplateTypeParameter && !IsMoreSpecialized((TemplateTypeParameter)t1, (TemplateTypeParameter)t2, t1_dummyParameterList)) { return(false); } else if (t1 is TemplateValueParameter && t2 is TemplateValueParameter && !IsMoreSpecialized((TemplateValueParameter)t1, (TemplateValueParameter)t2)) { return(false); } else if (t1 is TemplateAliasParameter && t2 is TemplateAliasParameter && !IsMoreSpecialized((TemplateAliasParameter)t1, (TemplateAliasParameter)t2, t1_dummyParameterList)) { return(false); } else if (t1 is TemplateThisParameter && t2 is TemplateThisParameter && ! IsMoreSpecialized(((TemplateThisParameter)t1).FollowParameter, ((TemplateThisParameter)t2).FollowParameter, t1_dummyParameterList)) { return(false); } return(false); }
public void ReparseForTemplate(ITemplateInfo templateInfo, HostSpecificTemplateData hostSpecificTemplateData) { Dictionary <string, string> templateParamValues = new Dictionary <string, string>(); Dictionary <string, IList <string> > remainingParams = new Dictionary <string, IList <string> >(); foreach (KeyValuePair <string, string> inputParam in _rawParameterInputs) { ITemplateParameter matchedParam = default(ITemplateParameter); if (templateInfo.Parameters != null) { matchedParam = templateInfo.Parameters?.FirstOrDefault(x => string.Equals(x.Name, inputParam.Key)); } if (matchedParam != default(ITemplateParameter)) { templateParamValues.Add(inputParam.Key, inputParam.Value); } else { remainingParams.Add(inputParam.Key, new List <string>()); } } InputTemplateParams = templateParamValues; RemainingParameters = remainingParams; RemainingArguments = remainingParams.Keys.ToList(); _allParametersForTemplate = templateInfo.Parameters.Select(x => x.Name).ToList(); }
bool IsMoreSpecialized(ITypeDeclaration Spec, ITemplateParameter t2, Dictionary <string, ISemantic> t1_DummyParamList) { // Make a type out of t1's specialization var frame = ctxt.PushNewScope(ctxt.ScopedBlock.Parent as IBlockNode); // Make the T in e.g. T[] a virtual type so T will be replaced by it // T** will be X** then - so a theoretically valid type instead of a template param var dummyType = new ClassType(new DClassLike { Name = "X" }, null, null); foreach (var kv in t1_DummyParamList) { frame.DeducedTemplateParameters[kv.Key] = new TemplateParameterSymbol(t2, dummyType); } var t1_TypeResults = Resolver.TypeResolution.TypeDeclarationResolver.Resolve(Spec, ctxt); if (t1_TypeResults == null || t1_TypeResults.Length == 0) { return(true); } ctxt.Pop(); // Now try to fit the virtual Type t2 into t1 - and return true if it's possible return(new TemplateParameterDeduction(new DeducedTypeDictionary(), ctxt).Handle(t2, t1_TypeResults[0])); }
internal CliTemplateParameter(ITemplateParameter parameter, HostSpecificTemplateData data) { Name = parameter.Name; Description = parameter.Description ?? string.Empty; Type = ParseType(parameter.DataType); DefaultValue = parameter.DefaultValue; DataType = parameter.DataType; if (Type == ParameterType.Boolean && string.Equals(parameter.DefaultIfOptionWithoutValue, "true", StringComparison.OrdinalIgnoreCase)) { //ignore, parser is doing this behavior by default } else { DefaultIfOptionWithoutValue = parameter.DefaultIfOptionWithoutValue; } IsRequired = parameter.Priority == TemplateParameterPriority.Required && parameter.DefaultValue == null; IsHidden = parameter.Priority == TemplateParameterPriority.Implicit || data.HiddenParameterNames.Contains(parameter.Name); AlwaysShow = data.ParametersToAlwaysShow.Contains(parameter.Name); AllowMultipleValues = parameter.AllowMultipleValues; if (data.ShortNameOverrides.ContainsKey(parameter.Name)) { _shortNameOverrides.Add(data.ShortNameOverrides[parameter.Name]); } if (data.LongNameOverrides.ContainsKey(parameter.Name)) { _longNameOverrides.Add(data.LongNameOverrides[parameter.Name]); } }
internal BlobTemplateParameter(ITemplateParameter parameter) { if (parameter is null) { throw new ArgumentNullException(nameof(parameter)); } if (string.IsNullOrWhiteSpace(parameter.Name)) { throw new ArgumentException($"{nameof(Name)} property should not be null or whitespace", nameof(parameter)); } Name = parameter.Name; DataType = !string.IsNullOrWhiteSpace(parameter.DataType) ? parameter.DataType : "string"; Choices = parameter.Choices; if (DataType.Equals("choice", StringComparison.OrdinalIgnoreCase) && Choices == null) { Choices = new Dictionary <string, ParameterChoice>(); } Priority = parameter.Priority; DefaultIfOptionWithoutValue = parameter.DefaultIfOptionWithoutValue; Description = parameter.Description; AllowMultipleValues = parameter.AllowMultipleValues; }
private static bool TryResolveChoiceValue(string literal, ITemplateParameter param, out string match) { if (literal == null) { match = null; return(false); } string partialMatch = null; foreach (string choiceValue in param.Choices.Keys) { if (string.Equals(choiceValue, literal, StringComparison.OrdinalIgnoreCase)) { // exact match is good, regardless of partial matches match = choiceValue; return(true); } else if (choiceValue.StartsWith(literal, StringComparison.OrdinalIgnoreCase)) { if (partialMatch == null) { partialMatch = choiceValue; } else { // multiple partial matches, can't take one. match = null; return(false); } } } match = partialMatch; return(match != null); }
public void TestLocalizedSymbolDescription(string locale, string expectedDescription) { _ = LoadHostWithLocalizationTemplates(locale, out _, out ITemplateInfo localizationTemplate); ITemplateParameter symbol = localizationTemplate.Parameters?.FirstOrDefault(p => p.Name == "someSymbol"); Assert.NotNull(symbol); Assert.Equal(expectedDescription, symbol.Description); }
public TemplateParameterNode(ITemplateParameter param) { TemplateParameter = param; Name = param.Name; Location = NameLocation = param.Location; EndLocation = param.EndLocation; }
public void TestLocalizedSymbolChoiceDisplayName(string locale, string symbolName, string expectedDisplayName) { _ = LoadHostWithLocalizationTemplates(locale, out _, out ITemplateInfo localizationTemplate); ITemplateParameter symbol = localizationTemplate.Parameters?.FirstOrDefault(p => p.Name == symbolName); Assert.NotNull(symbol); Assert.Equal(expectedDisplayName, symbol.DisplayName); }
public bool OnParameterError(ITemplateParameter parameter, string receivedValue, string message, out string newValue) { Console.WriteLine("DotNetNew3TemplateEngineHost::OnParameterError() called"); Console.WriteLine("\tError message: {0}", message); Console.WriteLine("Parameter name = {0}", parameter.Name); Console.WriteLine("Parameter value = {0}", receivedValue); Console.WriteLine("Enter a new value for the param, or:"); newValue = Console.ReadLine(); return(!string.IsNullOrEmpty(newValue)); }
public bool TryGetParameter(string name, out ITemplateParameter parameter) { if (_parameters.TryGetValue(name, out parameter)) { return(true); } parameter = new Parameter(name, TemplateParameterPriority.Optional, "string"); return(true); }
public TemplateParameterSymbol(ITemplateParameter tp, ISemantic representedTypeOrValue, ISyntaxRegion originalParameterIdentifier = null, DNode parentNode = null) : base(new TemplateParameterNode(tp) { Parent = parentNode }, AbstractType.Get(representedTypeOrValue), originalParameterIdentifier ?? tp) { this.Parameter = tp; this.ParameterValue = representedTypeOrValue as ISymbolValue; }
/// <summary> /// Updates the setting. /// </summary> /// <param name="code">The code.</param> /// <param name="value">The value.</param> public void UpdateSetting(string code, string value) { if (_parameters.ContainsKey(code)) { ITemplateParameter parameter = _parameters[code]; if (parameter != null && !string.IsNullOrWhiteSpace(value)) { parameter.UpdateValue(value); } } }
internal ChoiceTemplateParameter(ITemplateParameter parameter, HostSpecificTemplateData data) : base(parameter, data) { if (!parameter.IsChoice()) { throw new ArgumentException($"{nameof(parameter)} should have {nameof(parameter.Type)} {nameof(ParameterType.Choice)}"); } if (parameter.Choices == null) { throw new ArgumentException($"{nameof(parameter)} should have {nameof(parameter.Choices)}"); } _choices = parameter.Choices.ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.OrdinalIgnoreCase); }
public TemplateParameterViewModel(ITemplate parent, ITemplateParameter parameter) { _inner = parameter; if (parameter.Name == "name" && string.IsNullOrEmpty(parameter.DefaultValue)) { _value = parent.DefaultName; } else { _value = parameter.DefaultValue; } }
// Construct with name public TemplateInstance(Template template) { this.Template = template; this.Parameters = new List <string>(); if (Template.ParameterTypes is object) { foreach (string parameter in Template.ParameterTypes) { ITemplateParameter panel = TemplatePanel.CreateTemplateParameterPanel(parameter); Parameters.AddRange(panel.GetDefaultParameters()); } } }
public static bool HasDefaultType(ITemplateParameter p) { if (p is TemplateTypeParameter) return ((TemplateTypeParameter)p).Default != null; else if (p is TemplateAliasParameter) { var ap = (TemplateAliasParameter)p; return ap.DefaultExpression != null || ap.DefaultType != null; } else if (p is TemplateThisParameter) return HasDefaultType(((TemplateThisParameter)p).FollowParameter); else if (p is TemplateValueParameter) return ((TemplateValueParameter)p).DefaultExpression != null; return false; }
public bool Handle(ITemplateParameter parameter, ISemantic argumentToAnalyze) { // Packages aren't allowed at all if (argumentToAnalyze is PackageSymbol) return false; // Module symbols can be used as alias only if (argumentToAnalyze is ModuleSymbol && !(parameter is TemplateAliasParameter)) return false; //TODO: Handle __FILE__ and __LINE__ correctly - so don't evaluate them at the template declaration but at the point of instantiation /* * Introduce previously deduced parameters into current resolution context * to allow value parameter to be of e.g. type T whereas T is already set somewhere before */ DeducedTypeDictionary _prefLocalsBackup = null; if (ctxt != null && ctxt.CurrentContext != null) { _prefLocalsBackup = ctxt.CurrentContext.DeducedTemplateParameters; var d = new DeducedTypeDictionary(); foreach (var kv in TargetDictionary) if (kv.Value != null) d[kv.Key] = kv.Value; ctxt.CurrentContext.DeducedTemplateParameters = d; } bool res = false; if (parameter is TemplateAliasParameter) res = Handle((TemplateAliasParameter)parameter, argumentToAnalyze); else if (parameter is TemplateThisParameter) res = Handle((TemplateThisParameter)parameter, argumentToAnalyze); else if (parameter is TemplateTypeParameter) res = Handle((TemplateTypeParameter)parameter, argumentToAnalyze); else if (parameter is TemplateValueParameter) res = Handle((TemplateValueParameter)parameter, argumentToAnalyze); else if (parameter is TemplateTupleParameter) res = Handle((TemplateTupleParameter)parameter, new[] { argumentToAnalyze }); if (ctxt != null && ctxt.CurrentContext != null) ctxt.CurrentContext.DeducedTemplateParameters = _prefLocalsBackup; return res; }
public bool TryGetParameterDefinition(string name, out ITemplateParameter parameter) { if (_parameters.TryGetValue(name, out parameter)) { return(true); } parameter = new Parameter { Name = name, Requirement = TemplateParameterPriority.Optional, IsVariable = true, Type = "string" }; return(true); }
public void ReparseForTemplate(ITemplateInfo templateInfo, HostSpecificTemplateData hostSpecificTemplateData) { Dictionary <string, string> templateParamValues = new Dictionary <string, string>(); Dictionary <string, IList <string> > remainingParams = new Dictionary <string, IList <string> >(); Dictionary <string, string> overrideToCanonicalMap = hostSpecificTemplateData.LongNameOverrides.ToDictionary(o => o.Value, o => o.Key); foreach (KeyValuePair <string, string> shortNameOverride in hostSpecificTemplateData.ShortNameOverrides) { overrideToCanonicalMap[shortNameOverride.Value] = shortNameOverride.Key; } foreach (KeyValuePair <string, string> inputParam in _templateOptions) { ITemplateParameter matchedParam = default(ITemplateParameter); if (templateInfo.Parameters != null) { matchedParam = templateInfo.Parameters?.FirstOrDefault(x => string.Equals(x.Name, inputParam.Key)); } if (matchedParam != default(ITemplateParameter)) { templateParamValues.Add(inputParam.Key, inputParam.Value); } else if (overrideToCanonicalMap.TryGetValue(inputParam.Key, out string canonical)) { templateParamValues.Add(canonical, inputParam.Value); } else { remainingParams.Add(inputParam.Key, new List <string>()); } } InputTemplateParams = templateParamValues; RemainingParameters = remainingParams; RemainingArguments = remainingParams.Keys.ToList(); _allParametersForTemplate = templateInfo.Parameters.Select(x => x.Name).ToList(); }
public static bool HasDefaultType(ITemplateParameter p) { if (p is TemplateTypeParameter) { return(((TemplateTypeParameter)p).Default != null); } else if (p is TemplateAliasParameter) { var ap = (TemplateAliasParameter)p; return(ap.DefaultExpression != null || ap.DefaultType != null); } else if (p is TemplateThisParameter) { return(HasDefaultType(((TemplateThisParameter)p).FollowParameter)); } else if (p is TemplateValueParameter) { return(((TemplateValueParameter)p).DefaultExpression != null); } return(false); }
public TemplatePanel(EntityDefinition entDef, TemplateInstance template) { InitializeComponent(); Title.Content = template.Template.Name.Replace("_", "__").Substring(0, MAX_NAME_LENGTH); if (template.Template.ParameterNames is null) { return; } int templateIndex = 0; for (int i = 0; i < template.Template.ParameterNames.Count; i++) { ITemplateParameter templateParameterPanel = CreateTemplateParameterPanel(template.Template.ParameterTypes[i]); templateParameterPanel.InitialiseTemplate(template.Template.ParameterNames[i], entDef, template, templateIndex); TemplateStackPanel.Children.Add((UserControl)templateParameterPanel); templateIndex += templateParameterPanel.GetParameterCount(); } }
public bool TryGetParameterDefinition(string name, out ITemplateParameter parameter) { parameter = ParameterDefinitions.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); if (parameter != null) { return(true); } parameter = new TemplateParameter { Documentation = string.Empty, Name = name, Priority = TemplateParameterPriority.Optional, Type = "string", IsName = false, DefaultValue = string.Empty, DataType = "string", Choices = null }; return(true); }
internal static object InternalConvertParameterValueToType(ITemplateParameter parameter, string untypedValue) { if (untypedValue == null) { throw new TemplateParamException("Parameter value is null", parameter.Name, null, parameter.DataType); } if (!string.IsNullOrEmpty(parameter.DataType)) { object convertedValue = DataTypeSpecifiedConvertLiteral(parameter, untypedValue); if (convertedValue == null) { throw new TemplateParamException("Parameter value could not be converted", parameter.Name, untypedValue, parameter.DataType); } return(convertedValue); } else { return(InferTypeAndConvertLiteral(untypedValue)); } }
public void TestLocalizedSymbolChoices( string locale, string symbolDesc, string choice0Desc, string choice1Desc, string choice2Desc) { _ = LoadHostWithLocalizationTemplates(locale, out _, out ITemplateInfo localizationTemplate); ITemplateParameter symbol = localizationTemplate.Parameters?.FirstOrDefault(p => p.Name == "someChoice"); Assert.NotNull(symbol); Assert.Equal(symbolDesc, symbol.Description); var choices = symbol.Choices; Assert.NotNull(choices); Assert.True(choices.TryGetValue("choice0", out ParameterChoice choice0), "Template symbol should contain a choice with name 'choice0'."); Assert.Equal(choice0Desc, choice0.Description); Assert.True(choices.TryGetValue("choice1", out ParameterChoice choice1), "Template symbol should contain a choice with name 'choice1'."); Assert.Equal(choice1Desc, choice1.Description); Assert.True(choices.TryGetValue("choice2", out ParameterChoice choice2), "Template symbol should contain a choice with name 'choice2'."); Assert.Equal(choice2Desc, choice2.Description); }
/// <summary> /// Returns false if the item has already been set before and if the already set item is not equal to 'r'. /// Inserts 'r' into the target dictionary and returns true otherwise. /// </summary> bool Set(ITemplateParameter p, ISemantic r, string name=null) { if (string.IsNullOrEmpty(name)) name = p.Name; TemplateParameterSymbol rl=null; if (!TargetDictionary.TryGetValue(name, out rl) || rl == null) { TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner); return true; } else { if (rl!=null) if (ResultComparer.IsEqual(rl.Base, r)) return true; else { // Error: Ambiguous assignment } TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner); return false; } }
bool IsMoreSpecialized(ITemplateParameter t1, ITemplateParameter t2, Dictionary<string, ISemantic> t1_dummyParameterList) { if (t1 is TemplateTypeParameter && t2 is TemplateTypeParameter && !IsMoreSpecialized((TemplateTypeParameter)t1, (TemplateTypeParameter)t2, t1_dummyParameterList)) return false; else if (t1 is TemplateValueParameter && t2 is TemplateValueParameter && !IsMoreSpecialized((TemplateValueParameter)t1, (TemplateValueParameter)t2)) return false; else if (t1 is TemplateAliasParameter && t2 is TemplateAliasParameter && !IsMoreSpecialized((TemplateAliasParameter)t1, (TemplateAliasParameter)t2, t1_dummyParameterList)) return false; else if (t1 is TemplateThisParameter && t2 is TemplateThisParameter && ! IsMoreSpecialized(((TemplateThisParameter)t1).FollowParameter, ((TemplateThisParameter)t2).FollowParameter, t1_dummyParameterList)) return false; return false; }
public virtual bool OnParameterError(ITemplateParameter parameter, string receivedValue, string message, out string newValue) { return(_baseHost.OnParameterError(parameter, receivedValue, message, out newValue)); }
bool IsMoreSpecialized(ITypeDeclaration Spec, ITemplateParameter t2, Dictionary<string, ISemantic> t1_DummyParamList) { // Make a type out of t1's specialization var frame = ctxt.PushNewScope(ctxt.ScopedBlock.Parent as IBlockNode); // Make the T in e.g. T[] a virtual type so T will be replaced by it // T** will be X** then - so a theoretically valid type instead of a template param var dummyType = new ClassType(new DClassLike { Name = "X" }, null, null); foreach (var kv in t1_DummyParamList) frame.DeducedTemplateParameters[kv.Key] = new TemplateParameterSymbol(t2,dummyType); var t1_TypeResults = Resolver.TypeResolution.TypeDeclarationResolver.Resolve(Spec, ctxt); if (t1_TypeResults == null || t1_TypeResults.Length == 0) return true; ctxt.Pop(); // Now try to fit the virtual Type t2 into t1 - and return true if it's possible return new TemplateParameterDeduction(new DeducedTypeDictionary(), ctxt).Handle(t2, t1_TypeResults[0]); }
public void AddParameter(ITemplateParameter param) { _parameters[param.Name] = param; }
public TemplateParameterDeductionError(ITemplateParameter parameter, ISemantic argument, string msg) : base(parameter, msg) { this.Argument = argument; }
// For explicitly data-typed variables, attempt to convert the variable value to the specified type. // Data type names: // - choice // - bool // - float // - int // - hex // - text // The data type names are case insensitive. // // Returns the converted value if it can be converted, throw otherwise internal static object DataTypeSpecifiedConvertLiteral(IEngineEnvironmentSettings environmentSettings, ITemplateParameter param, string literal, out bool valueResolutionError) { valueResolutionError = false; if (string.Equals(param.DataType, "bool", StringComparison.OrdinalIgnoreCase)) { if (string.Equals(literal, "true", StringComparison.OrdinalIgnoreCase)) { return(true); } else if (string.Equals(literal, "false", StringComparison.OrdinalIgnoreCase)) { return(false); } else { bool boolVal = false; // Note: if the literal is ever null, it is probably due to a problem in TemplateCreator.Instantiate() // which takes care of making null bool -> true as appropriate. // This else can also happen if there is a value but it can't be converted. string val; while (environmentSettings.Host.OnParameterError(param, null, "ParameterValueNotSpecified", out val) && !bool.TryParse(val, out boolVal)) { } valueResolutionError = !bool.TryParse(val, out boolVal); return(boolVal); } } else if (string.Equals(param.DataType, "choice", StringComparison.OrdinalIgnoreCase)) { if (TryResolveChoiceValue(literal, param, out string match)) { return(match); } if (literal == null && param.Priority != TemplateParameterPriority.Required) { return(param.DefaultValue); } string val; while (environmentSettings.Host.OnParameterError(param, null, "ValueNotValid:" + string.Join(",", param.Choices.Keys), out val) && !TryResolveChoiceValue(literal, param, out val)) { } valueResolutionError = val == null; return(val); } else if (string.Equals(param.DataType, "float", StringComparison.OrdinalIgnoreCase)) { if (ParserExtensions.DoubleTryParseСurrentOrInvariant(literal, out double convertedFloat)) { return(convertedFloat); } else { string val; while (environmentSettings.Host.OnParameterError(param, null, "ValueNotValidMustBeFloat", out val) && (val == null || !ParserExtensions.DoubleTryParseСurrentOrInvariant(val, out convertedFloat))) { } valueResolutionError = !ParserExtensions.DoubleTryParseСurrentOrInvariant(val, out convertedFloat); return(convertedFloat); } } else if (string.Equals(param.DataType, "int", StringComparison.OrdinalIgnoreCase) || string.Equals(param.DataType, "integer", StringComparison.OrdinalIgnoreCase)) { if (long.TryParse(literal, out long convertedInt)) { return(convertedInt); } else { string val; while (environmentSettings.Host.OnParameterError(param, null, "ValueNotValidMustBeInteger", out val) && (val == null || !long.TryParse(val, out convertedInt))) { } valueResolutionError = !long.TryParse(val, out convertedInt); return(convertedInt); } } else if (string.Equals(param.DataType, "hex", StringComparison.OrdinalIgnoreCase)) { if (long.TryParse(literal.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out long convertedHex)) { return(convertedHex); } else { string val; while (environmentSettings.Host.OnParameterError(param, null, "ValueNotValidMustBeHex", out val) && (val == null || val.Length < 3 || !long.TryParse(val.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out convertedHex))) { } valueResolutionError = !long.TryParse(val.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out convertedHex); return(convertedHex); } } else if (string.Equals(param.DataType, "text", StringComparison.OrdinalIgnoreCase) || string.Equals(param.DataType, "string", StringComparison.OrdinalIgnoreCase)) { // "text" is a valid data type, but doesn't need any special handling. return(literal); } else { return(literal); } }
private static bool DeduceParam(ResolverContextStack ctxt, DSymbol overload, DeducedTypeDictionary deducedTypes, IEnumerator<ISemantic> argEnum, ITemplateParameter 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; } // 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 (!AllParamatersSatisfied(deducedTypes)) return false; return true; }
/// <summary> /// Note: /// http://www.digitalmars.com/d/2.0/declaration.html#DeclaratorSuffix /// The definition of a sequence of declarator suffixes is buggy here! Theoretically template parameters can be declared without a surrounding ( and )! /// Also, more than one parameter sequences are possible! /// /// TemplateParameterList[opt] Parameters MemberFunctionAttributes[opt] /// </summary> ITypeDeclaration DeclaratorSuffixes(out ITemplateParameter[] TemplateParameters, out List<INode> _Parameters, List<DAttribute> _Attributes) { ITypeDeclaration td = null; TemplateParameters = null; _Parameters = null; while (MemberFunctionAttribute[laKind]) { _Attributes.Add(new DAttribute(laKind, la.Value)); Step(); } while (laKind == (OpenSquareBracket)) { Step(); var ad = new ArrayDecl() { Location=t.Location }; LastParsedObject = ad; ad.InnerDeclaration = td; if (laKind != (CloseSquareBracket)) { ITypeDeclaration keyType=null; if (!IsAssignExpression()) { AllowWeakTypeParsing = true; keyType= ad.KeyType = Type(); AllowWeakTypeParsing = false; } if (keyType==null) ad.KeyExpression = AssignExpression(); } Expect(CloseSquareBracket); ad.EndLocation = t.EndLocation; td = ad; } if (laKind == (OpenParenthesis)) { if (IsTemplateParameterList()) { TemplateParameters = TemplateParameterList(); } _Parameters = Parameters(null); //TODO: MemberFunctionAttributes -- add them to the declaration while (StorageClass[laKind] || laKind==PropertyAttribute) { Step(); } } while (MemberFunctionAttribute[laKind]) { _Attributes.Add(new DAttribute(laKind,la.Value)); Step(); } return td; }
/// <summary> /// Note: /// http://www.digitalmars.com/d/2.0/declaration.html#DeclaratorSuffix /// The definition of a sequence of declarator suffixes is buggy here! Theoretically template parameters can be declared without a surrounding ( and )! /// Also, more than one parameter sequences are possible! /// /// TemplateParameterList[opt] Parameters MemberFunctionAttributes[opt] /// </summary> ITypeDeclaration DeclaratorSuffixes(out ITemplateParameter[] TemplateParameters, out List<INode> _Parameters, List<DAttribute> _Attributes) { DAttribute attr = null; ITypeDeclaration td = null; TemplateParameters = null; _Parameters = null; while (MemberFunctionAttribute[laKind]) { _Attributes.Add(attr=new DAttribute(laKind, la.Value)); LastParsedObject = attr; Step(); } while (laKind == (OpenSquareBracket)) { Step(); var ad = new ArrayDecl() { Location=t.Location }; LastParsedObject = ad; ad.InnerDeclaration = td; if (laKind != (CloseSquareBracket)) { ad.ClampsEmpty = false; ITypeDeclaration keyType=null; var la_backup = la; if (!IsAssignExpression()) { var weakType = AllowWeakTypeParsing; AllowWeakTypeParsing = true; keyType= ad.KeyType = Type(); AllowWeakTypeParsing = weakType; } if (keyType == null || laKind != CloseSquareBracket) { keyType = ad.KeyType = null; la = la_backup; ad.KeyExpression = AssignExpression(); } } Expect(CloseSquareBracket); ad.EndLocation = t.EndLocation; td = ad; } if (laKind == (OpenParenthesis)) { if (IsTemplateParameterList()) { TemplateParameters = TemplateParameterList(); } _Parameters = Parameters(null); while (StorageClass[laKind] || laKind==PropertyAttribute) { _Attributes.Add(attr=new DAttribute(laKind, la.Value)); LastParsedObject = attr; Step(); } } while (MemberFunctionAttribute[laKind]) { _Attributes.Add(attr=new DAttribute(laKind,la.Value)); LastParsedObject = attr; Step(); } return td; }
// TODO: rework this method... it's a bit of a god-method, for very specific purposes. // Number of times I've deferred on reworking this method: 4 internal static TemplateUsageInformation GetTemplateUsageInformation(ITemplateInfo templateInfo, IEngineEnvironmentSettings environmentSettings, INewCommandInput commandInput, IHostSpecificDataLoader hostDataLoader, TemplateCreator templateCreator) { IParameterSet allParams; IReadOnlyList <string> userParamsWithInvalidValues; HashSet <string> userParamsWithDefaultValues; bool hasPostActionScriptRunner; ITemplate template = environmentSettings.SettingsLoader.LoadTemplate(templateInfo, commandInput.BaselineName); TemplateListResolver.ParseTemplateArgs(templateInfo, hostDataLoader, commandInput); allParams = templateCreator.SetupDefaultParamValuesFromTemplateAndHost(template, template.DefaultName ?? "testName", out IReadOnlyList <string> defaultParamsWithInvalidValues); templateCreator.ResolveUserParameters(template, allParams, commandInput.InputTemplateParams, out userParamsWithInvalidValues); hasPostActionScriptRunner = CheckIfTemplateHasScriptRunningPostActions(template, environmentSettings, commandInput, templateCreator); templateCreator.ReleaseMountPoints(template); List <InvalidParameterInfo> invalidParameters = new List <InvalidParameterInfo>(); if (userParamsWithInvalidValues.Any()) { // Lookup the input param formats - userParamsWithInvalidValues has canonical. foreach (string canonical in userParamsWithInvalidValues) { commandInput.InputTemplateParams.TryGetValue(canonical, out string specifiedValue); string inputFormat = commandInput.TemplateParamInputFormat(canonical); InvalidParameterInfo invalidParam = new InvalidParameterInfo(inputFormat, specifiedValue, canonical); invalidParameters.Add(invalidParam); } } if (templateCreator.AnyParametersWithInvalidDefaultsUnresolved(defaultParamsWithInvalidValues, userParamsWithInvalidValues, commandInput.InputTemplateParams, out IReadOnlyList <string> defaultsWithUnresolvedInvalidValues)) { IParameterSet templateParams = template.Generator.GetParametersForTemplate(environmentSettings, template); foreach (string defaultParamName in defaultsWithUnresolvedInvalidValues) { ITemplateParameter param = templateParams.ParameterDefinitions.FirstOrDefault(x => string.Equals(x.Name, defaultParamName, StringComparison.Ordinal)); if (param != null) { // Get the best input format available. IReadOnlyList <string> inputVariants = commandInput.VariantsForCanonical(param.Name); string displayName = inputVariants.FirstOrDefault(x => x.Contains(param.Name)) ?? inputVariants.Aggregate("", (max, cur) => max.Length > cur.Length ? max : cur) ?? param.Name; InvalidParameterInfo invalidParam = new InvalidParameterInfo(displayName, param.DefaultValue, displayName, true); invalidParameters.Add(invalidParam); } } } // get all the flags // get all the user input params that have the default value Dictionary <string, IReadOnlyList <string> > inputFlagVariants = new Dictionary <string, IReadOnlyList <string> >(); userParamsWithDefaultValues = new HashSet <string>(); foreach (string paramName in allParams.ParameterDefinitions.Select(x => x.Name)) { inputFlagVariants[paramName] = commandInput.VariantsForCanonical(paramName); if (commandInput.TemplateParamHasValue(paramName) && string.IsNullOrEmpty(commandInput.TemplateParamValue(paramName))) { userParamsWithDefaultValues.Add(paramName); } } IReadOnlyDictionary <string, IReadOnlyList <string> > variantsForCanonicals = inputFlagVariants; return(new TemplateUsageInformation { InvalidParameters = invalidParameters, AllParameters = allParams, UserParametersWithInvalidValues = userParamsWithInvalidValues, UserParametersWithDefaultValues = userParamsWithDefaultValues, VariantsForCanonicals = variantsForCanonicals, HasPostActionScriptRunner = hasPostActionScriptRunner }); }
static bool CheckAndDeduceTypeAgainstTplParameter(ITemplateParameter handledParameter, ISemantic argumentToCheck, DeducedTypeDictionary deducedTypes, ResolverContextStack ctxt) { return new Templates.TemplateParameterDeduction(deducedTypes, ctxt).Handle(handledParameter, argumentToCheck); }