private ClrChangeSignatureParameter FindBestMatch(ParameterSignature requiredParameter, ClrChangeSignatureModel model, int i) { var parameters = model.ChangeSignatureParameters.Cast <ClrChangeSignatureParameter>().ToList(); // Try and match type and name first for (var j = i; j < parameters.Count; j++) { if (parameters[j].ParameterName == requiredParameter.Name && Equals(parameters[j].ParameterType, requiredParameter.Type)) { return(parameters[j]); } } // Now just match type - we'll update name after for (var j = i; j < parameters.Count; j++) { if (Equals(parameters[j].ParameterType, requiredParameter.Type)) { return(parameters[j]); } } return(null); }
public string GetString(ParameterSignature signature, ParameterEmitOptions option) { var temp = new StringWriter(); Write(temp, signature, option); return(temp.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="ParameterSignatureBuilder"/> class. /// </summary> /// <param name="parameterSignature">The signature.</param> public ParameterSignatureBuilder([NotNull] ParameterSignature parameterSignature) { _newName = parameterSignature.Name; _newType = parameterSignature.Type; _newFlow = parameterSignature.Flow; _newCount = parameterSignature.Count; }
public override ParameterSignature GetReturnParameterSignature(ScriptParserGenerator generator) { ParameterSignature inner = _innerExpression.GetReturnParameterSignature(generator); string name = string.Format("{0}_opt", inner.ParamName); return(new ParameterSignature(name, SignatureType.Optional, inner)); }
public ParameterSignature GetReturnParameterSignature(ScriptParserGenerator generator, out bool oneClassType) { Debug.Assert(_candidates.Count >= 1); List <ParameterSignature> sigList = new List <ParameterSignature>(); HashSet <ParameterSignature> exists = new HashSet <ParameterSignature>(new ParameterSignatureComparer()); foreach (ElementsElement elems in _candidates) { ParameterSignature sig = elems.GetReturnParameterSignature(generator); if (!exists.Contains(sig)) { sigList.Add(sig); exists.Add(sig); } } Debug.Assert(sigList.Count >= 1); if (sigList.Count == 1) { oneClassType = true; return(sigList.First()); } oneClassType = false; ParameterSignature ret = new ParameterSignature("selection", SignatureType.Selection, sigList); return(ret); }
private ClrChangeSignatureParameter FindBestMatch(ParameterSignature requiredParameter, ClrChangeSignatureModel model, int i) { var parameters = model.ChangeSignatureParameters; // Look through all parameters for an exact match for (var j = i; j < parameters.Length; j++) { if (parameters[j].ParameterName == requiredParameter.Name && Equals(parameters[j].ParameterType, requiredParameter.Type)) { return(parameters[j]); } } // Now just match type - we'll update name after for (var j = i; j < parameters.Length; j++) { if (Equals(parameters[j].ParameterType, requiredParameter.Type)) { return(parameters[j]); } } return(null); }
public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator) { IList <string> firsts = _innerExpression.GetFirstTerminals(generator); IList <string> followings = this.GetFollowingTerminals(generator); HashSet <string> firstSet = new HashSet <string>(firsts); foreach (string following in followings) { if (firstSet.Contains(following)) { string context = string.Format("'{0}' の定義", this.RootDefinition.DefinitionName); string message = string.Format("省略可能な <{1}> の直後に <{0}> がありますが <{1}> の方が優先されます", following, this.ToString()); generator.Warn(context, message); } } ParameterSignature returnParam = this.GetReturnParameterSignature(generator); string returnType = returnParam.GetTypeName(); string returnVar; writer.WriteLine(generator.GetCodeOfDeclareDefault(returnType, out returnVar)); string peekVar; writer.WriteLine(generator.GetCodeOfPeek(out peekVar)); writer.WriteLine(generator.GetCodeOfIfOptionalLexisIn(peekVar, firsts)); string innerVar = _innerExpression.WriteParseCode(writer, generator); writer.WriteLine(generator.GetCodeOfSubstitution(returnVar, innerVar)); writer.WriteLine(generator.GetCodeOfCloseBlock()); return(returnVar); }
public void OperandTypeArgument() { var methodBody = CreateDummyMethodBody(); var image = methodBody.Method.Image; var instructions = methodBody.Instructions; var param1 = new ParameterSignature(image.TypeSystem.Boolean); var param2 = new ParameterSignature(image.TypeSystem.Int32); methodBody.Method.Signature = new MethodSignature(new[] { param1, param2 }, image.TypeSystem.Void); instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldarg, param1), CilInstruction.Create(CilOpCodes.Starg, param1), CilInstruction.Create(CilOpCodes.Ldarg, param2), CilInstruction.Create(CilOpCodes.Starg, param2), CilInstruction.Create(CilOpCodes.Ret), }); var mapping = image.Header.UnlockMetadata(); image = image.Header.LockMetadata(); var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]); instructions = newMethod.CilMethodBody.Instructions; Assert.Equal(param1.ParameterType, ((ParameterSignature)instructions[0].Operand).ParameterType, _comparer); Assert.Equal(param1.ParameterType, ((ParameterSignature)instructions[1].Operand).ParameterType, _comparer); Assert.Equal(param2.ParameterType, ((ParameterSignature)instructions[2].Operand).ParameterType, _comparer); Assert.Equal(param2.ParameterType, ((ParameterSignature)instructions[3].Operand).ParameterType, _comparer); }
public static MsilInstruction Create(MsilOpCode code, ParameterSignature operand) { if (code.OperandType != MsilOperandType.InlineArgument && code.OperandType != MsilOperandType.ShortInlineArgument) { throw new ArgumentException("Opcode does not accept a parameter operand.", "code"); } return(new MsilInstruction(0, code, operand)); }
public ParamDef Resolve(ModuleDef module, ParameterSignature signature) { if (!TryResolve(module, signature, out ParamDef definition)) { throw new PatchException("missing parameter " + signature); } return(definition); }
private static void AppendParameter(StringBuilder builder, ParameterSignature signature) { if (signature.IsByRef) { builder.Append("ref "); } AppendType(builder, signature.Type); }
public int GetParameterIndex(ParameterSignature parameter) { int parameterIndex = _methodBody.Method.Signature.Parameters.IndexOf(parameter); if (parameterIndex == -1) { return(0); } return(parameterIndex + (_methodBody.Method.Signature.HasThis ? 1 : 0)); }
private void ToParameterDefinition_StringsReturnedCorrectly <T>(string name, string expectedOutput) { var testParameterSig = new ParameterSignature(); var ns = testParameterSig.RequiredNamespaces; testParameterSig.Type = TypeHelper.DetermineType(typeof(T), ref ns, new GrassOptions()); testParameterSig.Name = name; var output = testParameterSig.ToParameterDefinition(); Assert.AreEqual(expectedOutput, output); }
public bool TryResolve(ModuleDef module, ParameterSignature signature, out ParamDef def) { def = null; if (!TryResolve(module, signature.DeclaringMethod, out MethodDef method) || !method.TryGetDefinition(signature, out Parameter definition)) { return(false); } if (!definition.HasParamDef) { definition.CreateParamDef(); } def = definition.ParamDef; return(true); }
private string GetDeclarationString([NotNull] ParameterSignature parameter) { var sb = new StringBuilder(); var attributes = new List <string>(); if (parameter.Flow == FlowDirection.Out) { attributes.Add("Out"); } else if (parameter.Flow == FlowDirection.Undefined) { attributes.Add("In"); attributes.Add("Out"); } if (!(parameter.Count is null)) { if (parameter.Count.IsStatic) { attributes.Add($"Count(Count = {parameter.Count.Count})"); } else if (parameter.Count.IsComputed) { var parameterList = string.Join(", ", parameter.Count.ComputedFrom.Select(p => p.Name)); attributes.Add($"Count(Computed = \"{parameterList}\")"); } else if (parameter.Count.IsReference) { // ReSharper disable once PossibleNullReferenceException attributes.Add($"CountAttribute(Parameter = \"{parameter.Count.ValueReference.Name}\")"); } } if (attributes.Count != 0) { sb.Append("["); sb.Append(string.Join(", ", attributes)); sb.Append("] "); } sb.Append(GetDeclarationString(parameter.Type)); sb.Append(" "); sb.Append(parameter.Name); return(sb.ToString()); }
private IEnumerable <string> GetParameterTokens(ParameterSignature parameter, ParameterEmitOptions options) { if (parameter.IsOutParameter) { if (options.HasFlag(ParameterEmitOptions.Keywords)) { yield return("out"); } } else if (parameter.IsRefParameter) { if (options.HasFlag(ParameterEmitOptions.Keywords)) { yield return("ref"); } } if (!options.HasFlag(ParameterEmitOptions.Invocation)) { if (parameter.IsParams) { yield return("params"); } yield return(_typeEmitter.GetString(parameter.ParameterType)); } if (options.HasFlag(ParameterEmitOptions.Name)) { yield return(_keywords.Contains(parameter.Name) ? $"@{parameter.Name}" : parameter.Name); } if (parameter.IsOptional) { if (!options.HasFlag(ParameterEmitOptions.Invocation) && options.HasFlag(ParameterEmitOptions.Optional)) { yield return("="); yield return(GetDefaultValue(parameter, _typeEmitter)); } } }
private static CodeExpression GenParameterExpression(ParameterSignature p) { FieldDirection direction = FieldDirection.In; var paramSnippet = new CodeSnippetExpression(p.Name); if (p.Info.IsOut || p.Info.ParameterType.IsByRef && p.Info.IsOut) { direction = FieldDirection.Out; } else if (p.Info.ParameterType.IsByRef) { direction = FieldDirection.Ref; } if (direction != FieldDirection.In) { return(new CodeDirectionExpression(direction, paramSnippet)); } return(paramSnippet); }
public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator) { Debug.Assert(_elements.Count >= 1); if (_elements.Count == 1) { return(_elements.First().WriteParseCode(writer, generator)); } else { List <string> innerVars = new List <string>(); foreach (ElementElement elem in _elements) { string var = elem.WriteParseCode(writer, generator); innerVars.Add(var); } ParameterSignature returnParam = this.GetReturnParameterSignature(generator); string returnType = returnParam.GetTypeName(); string returnVar; writer.WriteLine(generator.GetCodeOfDeclareNew(returnType, innerVars, out returnVar)); return(returnVar); } }
private ChangeSignatureParameter FindBestMatch(ParameterSignature requiredParameter, ChangeSignatureModel model, int i) { // Try and match type and name first for (var j = i; j < model.ChangeSignatureParameters.Length; j++) { if (model.ChangeSignatureParameters[j].ParameterName == requiredParameter.Name && Equals(model.ChangeSignatureParameters[j].ParameterType, requiredParameter.Type)) { return(model.ChangeSignatureParameters[j]); } } // Now just match type - we'll update name after for (var j = i; j < model.ChangeSignatureParameters.Length; j++) { if (Equals(model.ChangeSignatureParameters[j].ParameterType, requiredParameter.Type)) { return(model.ChangeSignatureParameters[j]); } } return(null); }
private string GetDefaultValue(ParameterSignature parameter, TypeEmitter writer) { if (!parameter.IsOptional) { return(string.Empty); } if (parameter.DefaultValue == null) { return("null"); } var type = parameter.DefaultValue.GetType(); var value = parameter.DefaultValue; // Nullable? if (parameter.ParameterType.Namespace.Name == "System" && parameter.ParameterType.Name == "Nullable") { // This is really only needing to account for char? and bool? // Unwrap the type and use the same logic as non-nullable by calling the BuildParameterValueToken method. var innerType = parameter.ParameterType.GenericParameters[0]; return($"({writer.GetString(innerType)}){BuildParameterValueToken(type, value)}"); } // Enum or numeric? if (parameter.ParameterType.IsEnum || _numericTypes.Contains(type)) { // Nullable numerics are handled in the previous block, so just cast it and use the value. return(string.Format(CultureInfo.InvariantCulture, "({0}){1}", writer.GetString(parameter.ParameterType), value)); } return(BuildParameterValueToken(type, value)); }
public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator) { IList <string> firsts = _innerExpression.GetFirstTerminals(generator); IList <string> followings = this.GetFollowingTerminals(generator); HashSet <string> firstSet = new HashSet <string>(firsts); foreach (string following in followings) { if (firstSet.Contains(following)) { string context = string.Format("'{0}' の定義", this.RootDefinition.DefinitionName); string message = string.Format("<{1}> の直後の <{0}> は <{1}> によって隠されます", following, this.ToString()); generator.Warn(context, message); } } ParameterSignature returnParam = this.GetReturnParameterSignature(generator); ParameterSignature innerParam = _innerExpression.GetReturnParameterSignature(generator); string innerType = innerParam.GetTypeName(); string innerListType = string.Format("List<{0}>", innerType); string innerListVar; writer.WriteLine(generator.GetCodeOfDeclareNew(innerListType, out innerListVar)); string peek; writer.WriteLine(generator.GetCodeOfForPeekLexisIn(firsts, out peek)); string innerVar = _innerExpression.WriteParseCode(writer, generator); writer.WriteLine(generator.GetCodeOfInvoke(innerListVar, "Add", innerVar)); writer.WriteLine(generator.GetCodeOfCloseBlock()); string returnType = returnParam.GetTypeName(); string returnVar; writer.WriteLine(generator.GetCodeOfDeclare(returnType, out returnVar)); writer.WriteLine(generator.GetCodeOfInvokeSubstitute(returnVar, innerListVar, "ToArray")); return(returnVar); }
private static ParameterSignature CreateOverriddenParameter ( [NotNull] ParameterSignature baseParameter, [NotNull] ParameterOverride parameterOverride, out bool hasComputedCount, [CanBeNull] out IReadOnlyList <string> computedCountParameterNames, out bool hasValueReference, [CanBeNull] out string valueReferenceName, [CanBeNull] out string valueReferenceExpression ) { computedCountParameterNames = null; valueReferenceName = null; valueReferenceExpression = null; hasComputedCount = false; hasValueReference = false; var newName = parameterOverride.NewName ?? baseParameter.Name; var newType = parameterOverride.NewType ?? baseParameter.Type; var newFlow = parameterOverride.NewFlow ?? baseParameter.Flow; var newCount = parameterOverride.NewCount is null ? baseParameter.Count : ParsingHelpers.ParseCountSignature ( parameterOverride.NewCount, out hasComputedCount, out computedCountParameterNames, out hasValueReference, out valueReferenceName, out valueReferenceExpression ); return(new ParameterSignature(newName, newType, newFlow, newCount)); }
public void Write(TextWriter writer, ParameterSignature parameter, ParameterEmitOptions options) { writer.Write(string.Join(" ", GetParameterTokens(parameter, options))); }
public int GetParameterIndex(ParameterSignature parameter) { return(_methodBody.Method.Signature.Parameters.IndexOf(parameter) + (_methodBody.Method.Signature.HasThis ? 1 : 0)); }
public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator) { if (false) { // 普通のコード Debug.Assert(_candidates.Count >= 1); if (_candidates.Count == 1) { return(_candidates.First().WriteParseCode(writer, generator)); } else { IList <string> firsts = this.GetFirstTerminals(generator); string peekVar; writer.WriteLine(generator.GetCodeOfPeekOrThrow(this.RootDefinition.DefinitionName, firsts, out peekVar)); bool oneClassType; ParameterSignature returnParam = GetReturnParameterSignature(generator, out oneClassType); string returnType = returnParam.GetTypeName(); string returnVar; writer.WriteLine(generator.GetCodeOfDeclareDefault(returnType, out returnVar)); Dictionary <string, string> usedFirsts = new Dictionary <string, string>(); foreach (ElementsElement elems in _candidates) { IList <string> innerFirsts = elems.GetFirstTerminals(generator); foreach (string first in innerFirsts) { string usingPoint; if (usedFirsts.TryGetValue(first, out usingPoint)) { string context = string.Format("'{0}' の定義", this.RootDefinition.DefinitionName); string message = string.Format("<{1}> 内の <{0}> は <{2}> によって隠されます", first, this.ToString(), usingPoint); generator.Warn(context, message); } else { usedFirsts[first] = elems.ToString(); } } writer.WriteLine(generator.GetCodeOfIfLexisIn(peekVar, innerFirsts)); string candidateVar = elems.WriteParseCode(writer, generator); if (oneClassType) { writer.WriteLine(generator.GetCodeOfSubstitution(returnVar, candidateVar)); } else { string selectVar; writer.WriteLine(generator.GetCodeOfDeclareNew(returnType, new[] { candidateVar }, out selectVar)); writer.WriteLine(generator.GetCodeOfSubstitution(returnVar, selectVar)); } writer.Write(generator.GetCodeOfCloseBlock()); writer.Write(generator.GetCodeOfSingleElse()); } writer.Write(generator.GetCodeOfOpenBlock()); writer.WriteLine(generator.GetCodeOfCloseBlock()); return(returnVar); } } else { // 前半部分が同じSelectionをツリー状に探索するようにするために // SelectionSubCandidateを作る List <SelectionSubCandidate> subCandidates = new List <SelectionSubCandidate>(); foreach (ElementsElement candidate in _candidates) { subCandidates.Add(new SelectionSubCandidate(candidate)); } bool oneClassType; ParameterSignature returnParam = this.GetReturnParameterSignature(generator, out oneClassType); string returnVariableName; writer.WriteLine(generator.GetCodeOfDeclareDefault(returnParam.GetTypeName(), out returnVariableName)); SelectionSubCandidate.writeParseCodeAux(writer, generator, subCandidates, (candidateAtEmpty, writer2, generator2) => { // 候補の要素が単一要素の場合はFixedListをnewしなくてよいので分ける string resultVar; if (candidateAtEmpty.OriginalElements.Elements.Count == 1) { resultVar = candidateAtEmpty.TemporaryVariables.First(); } else { ParameterSignature returnParam2 = candidateAtEmpty.OriginalElements.GetReturnParameterSignature(generator2); string typename = returnParam2.GetTypeName(); writer2.WriteLine(generator2.GetCodeOfDeclareNew(typename, candidateAtEmpty.TemporaryVariables, out resultVar)); } bool oneClassReturn; ParameterSignature tmpReturnParam = this.GetReturnParameterSignature(generator2, out oneClassReturn); if (!oneClassReturn) { // 一回Selection<>を作成しないといけない string tmpTypename = tmpReturnParam.GetTypeName(); string tmpResultVar; writer.WriteLine(generator2.GetCodeOfDeclareNew(tmpTypename, new[] { resultVar }, out tmpResultVar)); resultVar = tmpResultVar; } writer2.WriteLine(generator.GetCodeOfSubstitution(returnVariableName, resultVar)); }); return(returnVariableName); } }
public override ParameterSignature GetReturnParameterSignature(ScriptParserGenerator generator) { ParameterSignature inner = _innerExpression.GetReturnParameterSignature(generator); return(inner); }
public override ParameterSignature GetReturnParameterSignature(ScriptParserGenerator generator) { ParameterSignature inner = _innerExpression.GetReturnParameterSignature(generator); return(new ParameterSignature("repetition", SignatureType.Array, inner)); }
public ColorDescriptor() { _signature = new ParameterSignature( new ParameterSpecification("Curve", typeof(Curve)), new ParameterSpecification("Color", typeof(ColorGradient))); }
public RampDescriptor() { _signature = new ParameterSignature( new ParameterSpecification("Start level", typeof(float)), new ParameterSpecification("End level", typeof(float))); }
public string GetString(ParameterSignature signature) { return(GetString(signature, ParameterEmitOptions.Default)); }
/// <summary> /// 各ルールから生成される結果用メソッドのシグネチャを,ルールの要素から牽けるようにしてを返します /// </summary> /// <param name="generator"></param> /// <returns></returns> public IDictionary <ElementsElement, MethodSignature> GetReturnParameterSignaturesAndElements(ScriptParserGenerator generator) { Dictionary <ElementsElement, MethodSignature> methodList = new Dictionary <ElementsElement, MethodSignature>(); foreach (ElementsElement elems in this.Expression.Selection.Candidates) { // ひとつのルールに対してメソッドを一個生成する MethodSignature method = new MethodSignature(); foreach (ElementElement elem in elems.Elements) { ParameterSignature sig = elem.GetReturnParameterSignature(generator); sig.ParamName = sig.ParamName.TrimStart('_'); sig.ParamName = sig.ParamName.TrimEnd('_'); if (sig.ParamName.Length >= 1) { if (char.IsUpper(sig.ParamName[0])) { sig.ParamName = sig.ParamName[0].ToString().ToLower() + sig.ParamName.Substring(1); } } method.Parameters.Add(sig); method.AddEbnfString(elem.ToString()); } // おなじParamNameを持つものを探す HashSet <string> duplicativeNames = new HashSet <string>(from sig in method.Parameters group sig.ParamName by sig.ParamName into nameSet where nameSet.Count() >= 2 select nameSet.Key); Dictionary <string, int> countUpPerName = duplicativeNames.ToDictionary(n => n, n => 1); foreach (ParameterSignature sig in method.Parameters) { if (duplicativeNames.Contains(sig.ParamName)) { string name = sig.ParamName; sig.ParamName = string.Format("{0}_{1}", name, countUpPerName[name]); countUpPerName[name]++; } } method.MethodName = generator.GetReturnMethodIdentifier(this.DefinitionName); methodList[elems] = method; } // 引数の重複性を確認する var groupBy = methodList.Values.GroupBy(method => method, new MethodSignatureParametersComparer()); Dictionary <MethodSignature, List <MethodSignature> > duplicativeMethods = groupBy.ToDictionary(m => m.Key, m => m.ToList()); // 同じ引数のメソッドがある場合にはそれぞれにパラメータから作成される識別子を後置する. foreach (List <MethodSignature> dupMethods in duplicativeMethods.Values) { if (dupMethods.Count >= 2) { foreach (MethodSignature dupMethod in dupMethods) { dupMethod.MethodName += "_" + dupMethod.GetMangledName(); } } } // C#のキーワードが識別子になる場合には頭に@を付ける foreach (MethodSignature method in methodList.Values) { foreach (ParameterSignature sig in method.Parameters) { if (_keywords.Contains(sig.ParamName)) { sig.ParamName = "@" + sig.ParamName; } } } return(methodList); }
public int GetParameterIndex(ParameterSignature parameter) { return(_owner.Method.Signature.Parameters.IndexOf(parameter)); }