/*--------------------------------------------------------------------------------------------*/ private IWeaverPathPipeEnd MakePropertyKey <T>(string pElement, Expression <Func <T, object> > pProp, IWeaverVarAlias pGroupVar = null) where T : IWeaverElement { WeaverPropPair wpp = WeaverUtil.GetPropertyAttribute(pProp); WeaverTitanPropertyAttribute att = WeaverTitanUtil.GetAndVerifyTitanPropertyAttribute(wpp); Type pt = wpp.Info.PropertyType; AddCustom("makeType()"); AddCustom("dataType(" + WeaverTitanPropertyAttribute.GetTitanTypeName(pt) + ".class)"); AddCustom("name(" + Path.Query.AddParam(new WeaverQueryVal(att.DbName)) + ")"); AddCustom("unique(OUT)"); //WeaverConfig enforces unique property DbNames if (pGroupVar != null) { AddCustom("group(" + pGroupVar.Name + ")"); } if (att.TitanIndex) { AddCustom("indexed(" + pElement + ".class)"); } if (att.TitanElasticIndex) { AddCustom("indexed('search'," + pElement + ".class)"); } return(AddCustom("makePropertyKey()")); }
/*--------------------------------------------------------------------------------------------*/ private static void ConfirmVciState <TEdge, TVert> (TEdge pEdge, Expression <Func <TVert, object> > pProperty) where TEdge : IWeaverEdge where TVert : IWeaverVertex { Type et = typeof(TEdge); Type vt = typeof(TVert); WeaverTitanUtil.GetAndVerifyElementAttribute <WeaverTitanEdgeAttribute> (et); WeaverTitanUtil.GetAndVerifyElementAttribute <WeaverTitanVertexAttribute> (vt); if (pEdge.OutVertexType != vt && pEdge.InVertexType != vt) { throw new WeaverException("Vertex type '" + vt.Name + "' is not valid for edge type '" + et.Name + "'."); } WeaverPropPair wpp = WeaverUtil.GetPropertyAttribute(pProperty); WeaverTitanPropertyAttribute att = WeaverTitanUtil.GetAndVerifyTitanPropertyAttribute(wpp); if (!att.HasTitanVertexCentricIndex(et)) { throw new WeaverException("Property '" + vt.Name + "." + wpp.Info.Name + "' does not have a " + "vertex-centric index for edge '" + et.Name + "'."); } }
public void GetPropertyAttribute() { WeaverPropPair result = WeaverUtil.GetPropertyAttribute <Person>(x => x.Age); Assert.NotNull(result, "Result should be filled."); Assert.AreEqual("Age", result.Info.Name, "Incorrect result PropertyInfo.Name."); }
protected override void PatchType(AssemblyDefinition assembly, TypeDefinition type) { type.CustomAttributes.Add(WeaverUtil.GetDoNotInjectAttribute(assembly, typeof(DoNotInjectAttribute))); foreach (var method in type.Methods) { if (!WeaverUtil.HasAttribute(typeof(PKTracer.Framework.Attributes.DoNotTraceAttribute).FullName, method.CustomAttributes)) { if (!method.IsAddOn && !method.IsRemoveOn) { if (method.Body != null) { using (new DebugTracer("PatchType")) { method.CustomAttributes.Add(WeaverUtil.GetDoNotInjectAttribute(assembly, typeof(DoNotTraceAttribute))); method.Body.SimplifyMacros(); itemTraceWeaver.Weave(assembly, method); exceptionWeaver.Weave(assembly, method); method.Body.OptimizeMacros(); } } } } } }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public IWeaverQuery AddVertex <T>(T pVertex) where T : IWeaverVertex { string props = WeaverUtil.BuildPropList(Path.Config, Path.Query, pVertex); Path.Query.FinalizeQuery("g.addVertex([" + props + "])"); return(Path.Query); }
private void InsertEndTrace( AssemblyDefinition assembly, MethodDefinition method, int count, Instruction beforeReturn, Instruction firstInstruction, Instruction lastRet) { ILProcessor ilProcessor = method.Body.GetILProcessor(); var instructions = new List <Instruction>(); instructions.Add(ilProcessor.Create(OpCodes.Ldloc, count)); instructions.Add(ilProcessor.Create(OpCodes.Callvirt, WeaverUtil.ImportMethod <ItemTracer>(assembly, "Dispose"))); instructions.Add(ilProcessor.Create(OpCodes.Nop)); instructions.Add(ilProcessor.Create(OpCodes.Endfinally)); instructions.ForEach(x => { ilProcessor.InsertBefore(lastRet, x); }); var handlerFinally = new ExceptionHandler(ExceptionHandlerType.Finally) { TryStart = firstInstruction, TryEnd = beforeReturn, HandlerStart = beforeReturn, HandlerEnd = lastRet }; method.Body.ExceptionHandlers.Add(handlerFinally); }
/*--------------------------------------------------------------------------------------------*/ private IWeaverQuery FinishEdgeVci <TEdge>(TEdge pEdge, string pOutV, string pInV, string pScript) where TEdge : IWeaverEdge { Type et = typeof(TEdge); var e = WeaverTitanUtil.GetAndVerifyElementAttribute <WeaverTitanEdgeAttribute>(et); string labelParam = Path.Query.AddStringParam(e.DbName); string propList = WeaverUtil.BuildPropList(Path.Config, Path.Query, pEdge); var sb = new StringBuilder(); AppendEdgeVciProps(sb, pOutV, et, WeaverUtil.GetElementPropertyAttributes(e.OutVertex)); AppendEdgeVciProps(sb, pInV, et, WeaverUtil.GetElementPropertyAttributes(e.InVertex)); const string tryLoop = "_TRY.each{k,v->if((z=v.getProperty(k))){_PROP.put(k,z)}};"; bool showTry = (sb.Length > 0); string propLine = (propList.Length > 0 || showTry ? "_PROP=" + (propList.Length > 0 ? "[" + propList + "];" : "[:];") : ""); Path.Query.FinalizeQuery( pScript + propLine + (showTry ? "_TRY=[" + sb + "];" + tryLoop : "") + "g.addEdge(" + pOutV + "," + pInV + "," + labelParam + (propLine.Length > 0 ? ",_PROP" : "") + ")" ); return(Path.Query); }
public void GetElementPropertyAttributes(Type pType, int pCount) { IList <WeaverPropPair> result = WeaverUtil.GetElementPropertyAttributes(pType); Assert.NotNull(result, "Result should be filled."); Assert.AreEqual(pCount, result.Count, "Incorrect result count."); }
public void PropNamePassLowerLabel() { Expression <Func <PersonLikesCandy, object> > expr = (p => p.Label); vPropExprResult = WeaverUtil.GetPropertyDbName(expr); Assert.AreEqual("label", vPropExprResult, "Incorrect property name."); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public RequestCmd AddQuery(string pScript, IDictionary <string, IWeaverQueryVal> pParams) { string[] args = WeaverUtil.GetScriptAndParamJson(pScript, pParams); RequestCmd rc = new RequestCmd(RexConn.Command.Query.ToString().ToLower(), args); CmdList.Add(rc); return(rc); }
/*--------------------------------------------------------------------------------------------*/ private IWeaverQuery FinishEdge <TEdge>(TEdge pEdge, string pScript) where TEdge : IWeaverEdge { string labelParam = Path.Query.AddStringParam(Path.Config.GetEdgeDbName <TEdge>()); string propList = WeaverUtil.BuildPropList(Path.Config, Path.Query, pEdge); Path.Query.FinalizeQuery(pScript + labelParam + (propList.Length > 0 ? ",[" + propList + "]" : "") + ")"); return(Path.Query); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ public static T GetAndVerifyElementAttribute <T>(Type pType) where T : WeaverElementAttribute { T att = WeaverUtil.GetElementAttribute <T>(pType); if (att == null) { throw new WeaverException("Type '" + pType.Name + "' must have a " + typeof(T).Name + "."); } return(att); }
/*--------------------------------------------------------------------------------------------*/ private void BuildType <T>(Type pType, Action <Type, T> pFinish) where T : WeaverElementAttribute { T att = WeaverUtil.GetElementAttribute <T>(pType); if (att == null) { throw new WeaverException("Type '" + pType.Name + "' must have a " + typeof(T).Name + "."); } pFinish(pType, att); }
public void GetElementAttribute(Type pType, bool pFound) { var result = WeaverUtil.GetElementAttribute <WeaverVertexAttribute>(pType); if (pFound) { Assert.NotNull(result, "Result should be filled."); } else { Assert.Null(result, "Result should be null."); } }
public void BuildPropListPerson(bool pIncludeId, string pName) { var p = new Person(); p.Id = "123456789123ABC"; p.PersonId = 3456789; p.Name = pName; p.Age = 27.3f; p.IsMale = true; var q = new WeaverQuery(); string propList = WeaverUtil.BuildPropList(WeavInst.Config, q, p, pIncludeId); Dictionary <string, string> pairMap = WeaverTestUtil.GetPropListDictionary(propList); int expectCount = 3 + (pIncludeId ? 1 : 0) + (pName != null ? 1 : 0); Assert.AreEqual(expectCount, pairMap.Keys.Count, "Incorrect Key count."); Assert.True(pairMap.ContainsKey(TestSchema.Person_PersonId), "Missing PersonId key."); Assert.True(pairMap.ContainsKey(TestSchema.Person_Age), "Missing Age key."); Assert.True(pairMap.ContainsKey(TestSchema.Person_IsMale), "Missing IsMale key."); Assert.AreEqual(pIncludeId, pairMap.ContainsKey("id"), "Incorrect Id key."); Assert.AreEqual((pName != null), pairMap.ContainsKey("Name"), "Incorrect Name key."); Assert.AreEqual("_P0", pairMap[TestSchema.Person_PersonId], "Incorrect PersonId value."); Assert.AreEqual("_P1", pairMap[TestSchema.Person_IsMale], "Incorrect IsMale value."); Assert.AreEqual("_P2", pairMap[TestSchema.Person_Age], "Incorrect Age value."); var expectParams = new Dictionary <string, IWeaverQueryVal>(); expectParams.Add("_P0", new WeaverQueryVal(p.PersonId)); expectParams.Add("_P1", new WeaverQueryVal(p.IsMale)); expectParams.Add("_P2", new WeaverQueryVal(p.Age)); int pi = 3; if (pName != null) { Assert.AreEqual("_P3", pairMap["Name"], "Incorrect Name value."); expectParams.Add("_P3", new WeaverQueryVal(pName)); pi++; } if (pIncludeId) { Assert.AreEqual("_P" + pi, pairMap["id"], "Incorrect Id value."); expectParams.Add("_P" + pi, new WeaverQueryVal(p.Id)); } WeaverTestUtil.CheckQueryParamsOriginalVal(q, expectParams); }
/*--------------------------------------------------------------------------------------------*/ private void BuildMaps <T>(IEnumerable <Type> pTypes, Action <Type, T> pFinish) where T : WeaverElementAttribute { foreach (Type t in pTypes) { BuildType(t, pFinish); IList <WeaverPropPair> props = WeaverUtil.GetElementPropertyAttributes(t); foreach (WeaverPropPair p in props) { BuildProp(p); } } }
/*--------------------------------------------------------------------------------------------*/ public void AssertScriptAndParams(string pScript, IDictionary <string, IWeaverQueryVal> pParams, string pExpectScript, string pExpectParamJson) { string[] args = WeaverUtil.GetScriptAndParamJson(pScript, pParams); Assert.NotNull(args, "Result should be filled."); Assert.AreEqual((pExpectParamJson == null ? 1 : 2), args.Length, "Incorrect argument count."); Assert.AreEqual(pExpectScript, args[0], "Incorrect script argument."); if (pExpectParamJson != null) { Assert.AreEqual(pExpectParamJson, args[1], "Incorrect parameters argument."); } }
public override void Weave(AssemblyDefinition assembly, MethodDefinition method) { method.Body.InitLocals = true; ILProcessor ilProcessor = method.Body.GetILProcessor(); var count = method.Body.Variables.Count; method.Body.Variables.Add(new VariableDefinition(WeaverUtil.ImportType <Exception>(assembly))); method.Body.Variables.Add(new VariableDefinition(WeaverUtil.ImportType <PKTracer.Framework.Tracer.ExceptionTracer>(assembly))); var lastRet = FixReturns(method); var firstInstruction = FirstInstructionSkipCtor(method); var beforeReturn = Instruction.Create(OpCodes.Nop); ilProcessor.InsertBefore(lastRet, beforeReturn); var instructions = new List <Instruction>(); instructions.Add(ilProcessor.Create(OpCodes.Stloc, count)); instructions.Add(ilProcessor.Create(OpCodes.Nop)); instructions.Add(ilProcessor.Create(OpCodes.Ldstr, assembly.Name.Name)); instructions.Add(ilProcessor.Create(OpCodes.Ldloc, count)); instructions.Add(ilProcessor.Create(OpCodes.Callvirt, WeaverUtil.ImportMethod <Exception>(assembly, "get_Message"))); instructions.Add(ilProcessor.Create(OpCodes.Newobj, method.Module.Import(typeof(PKTracer.Framework.Tracer.ExceptionTracer).GetConstructors()[0]))); instructions.Add(ilProcessor.Create(OpCodes.Stloc, count + 1)); instructions.Add(ilProcessor.Create(OpCodes.Ldloc, count + 1)); instructions.Add(ilProcessor.Create(OpCodes.Callvirt, WeaverUtil.ImportMethod <PKTracer.Framework.Tracer.ExceptionTracer>(assembly, "Dispose"))); instructions.Add(ilProcessor.Create(OpCodes.Nop)); instructions.Add(ilProcessor.Create(OpCodes.Ldloc, count)); instructions.Add(ilProcessor.Create(OpCodes.Throw)); instructions.ForEach(x => { ilProcessor.InsertBefore(lastRet, x); }); var handlerCatch = new ExceptionHandler(ExceptionHandlerType.Catch) { TryStart = firstInstruction, TryEnd = beforeReturn, HandlerStart = beforeReturn, HandlerEnd = lastRet, CatchType = WeaverUtil.ImportType <Exception>(assembly) }; method.Body.ExceptionHandlers.Add(handlerCatch); }
public override void Weave(AssemblyDefinition assembly, MethodDefinition method) { method.Body.InitLocals = true; ILProcessor ilProcessor = method.Body.GetILProcessor(); var count = method.Body.Variables.Count; method.Body.Variables.Add(new VariableDefinition(WeaverUtil.ImportType <PKTracer.Framework.Tracer.ItemTracer>(assembly))); var lastRet = FixReturns(method); var firstInstruction = FirstInstructionSkipCtor(method); var beforeReturn = Instruction.Create(OpCodes.Nop); ilProcessor.InsertBefore(lastRet, beforeReturn); Instruction i3 = InsertBeginTrace(assembly, method, count, firstInstruction); var weaver = new ParameterTraceWeaver(count, i3); weaver.Parameters = this.Parameters; weaver.Weave(assembly, method); InsertEndTrace(assembly, method, count, beforeReturn, firstInstruction, lastRet); }
public override void Weave(AssemblyDefinition assembly, MethodDefinition method) { ILProcessor ilProcessor = method.Body.GetILProcessor(); var objTracingInstructions = new List <Instruction>(); TypeSpecification referencedTypeSpec = null; MetadataType paramMetaData; TypeReference typeObject = assembly.MainModule.TypeSystem.Object; bool pointerToValueTypeVariable = false; int intMethodParamsCount = method.Parameters.Count; int intArrayVarNumber = method.Body.Variables.Count; ArrayType objArrType = new ArrayType(typeObject); method.Body.Variables.Add(new VariableDefinition((TypeReference)objArrType)); method.Body.InitLocals = true; //objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldstr,method.ToString())); objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldc_I4, intMethodParamsCount)); objTracingInstructions.Add(ilProcessor.Create(OpCodes.Newarr, typeObject)); objTracingInstructions.Add(ilProcessor.Create(OpCodes.Stloc, intArrayVarNumber)); // Loop over all the parameters of method and add their value to object[] // ------------------------------------------------------------ for (int i = 0; i < intMethodParamsCount; i++) { paramMetaData = method.Parameters[i].ParameterType.MetadataType; if (paramMetaData == MetadataType.UIntPtr || paramMetaData == MetadataType.FunctionPointer || paramMetaData == MetadataType.IntPtr || paramMetaData == MetadataType.Pointer) { // We don't want to log values of these parameters, so skip // this iteration break; } objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldloc, intArrayVarNumber)); objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldc_I4, i)); // Instance methods have an an implicit argument called "this" // and hence, we need to refer to actual arguments with +1 position // whereas, in case of static methods, "this" argument is not there // ------------------------------------------------------------ if (method.IsStatic) { objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldarg, i)); } else { objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldarg, i + 1)); } // Reset boolean flag variable to false pointerToValueTypeVariable = false; // If aparameter is passed by reference then you need to use ldind // ------------------------------------------------------------ TypeReference paramType = method.Parameters[i].ParameterType; if (paramType.IsByReference) { referencedTypeSpec = paramType as TypeSpecification; //Trace.WriteLine(string.Format("Parameter Name:{0}, Type:{1}", metDef.Parameters[i].Name, metDef.Parameters[i].ParameterType.Name)); if (referencedTypeSpec != null) { switch (referencedTypeSpec.ElementType.MetadataType) { //Indirect load value of type int8 as int32 on the stack case MetadataType.Boolean: case MetadataType.SByte: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_I1)); pointerToValueTypeVariable = true; break; // Indirect load value of type int16 as int32 on the stack case MetadataType.Int16: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_I2)); pointerToValueTypeVariable = true; break; // Indirect load value of type int32 as int32 on the stack case MetadataType.Int32: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_I4)); pointerToValueTypeVariable = true; break; // Indirect load value of type int64 as int64 on the stack // Indirect load value of type unsigned int64 as int64 on the stack (alias for ldind.i8) case MetadataType.Int64: case MetadataType.UInt64: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_I8)); pointerToValueTypeVariable = true; break; // Indirect load value of type unsigned int8 as int32 on the stack case MetadataType.Byte: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_U1)); pointerToValueTypeVariable = true; break; // Indirect load value of type unsigned int16 as int32 on the stack case MetadataType.UInt16: case MetadataType.Char: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_U2)); pointerToValueTypeVariable = true; break; // Indirect load value of type unsigned int32 as int32 on the stack case MetadataType.UInt32: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_U4)); pointerToValueTypeVariable = true; break; // Indirect load value of type float32 as F on the stack case MetadataType.Single: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_R4)); pointerToValueTypeVariable = true; break; // Indirect load value of type float64 as F on the stack case MetadataType.Double: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_R8)); pointerToValueTypeVariable = true; break; // Indirect load value of type native int as native int on the stack case MetadataType.IntPtr: case MetadataType.UIntPtr: objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_I)); pointerToValueTypeVariable = true; break; default: // Need to check if it is a value type instance, in which case // we use ldobj instruction to copy the contents of value type // instance to stack and then box it if (referencedTypeSpec.ElementType.IsValueType) { objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldobj, referencedTypeSpec.ElementType)); pointerToValueTypeVariable = true; } else { // It is a reference type so just use reference the pointer objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldind_Ref)); pointerToValueTypeVariable = false; } break; } } else { // We dont have complete details about the type of referenced parameter // So we will just ignore this parameter value } } // If it is a value type then you need to box the instance as we are going // to add it to an array which is of type object (reference type) // ------------------------------------------------------------ if (paramType.IsValueType || pointerToValueTypeVariable) { if (pointerToValueTypeVariable) { // Box the dereferenced parameter type objTracingInstructions.Add(ilProcessor.Create(OpCodes.Box, referencedTypeSpec.ElementType)); } else { // Box the parameter type objTracingInstructions.Add(ilProcessor.Create(OpCodes.Box, paramType)); } } // Store parameter in object[] array // ------------------------------------------------------------ objTracingInstructions.Add(ilProcessor.Create(OpCodes.Stelem_Ref)); } // Load address of array variable on evaluation stack, to pass // it as a paremter // ------------------------------------------------------------ objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldloc, tracerIndex)); objTracingInstructions.Add(ilProcessor.Create(OpCodes.Ldloc, intArrayVarNumber)); if (this.Parameters.DecodeParameters) { objTracingInstructions.Add(ilProcessor.Create(OpCodes.Callvirt, WeaverUtil.ImportMethod <ItemTracer>(assembly, "SetParametersWithDecode"))); } else { objTracingInstructions.Add(ilProcessor.Create(OpCodes.Callvirt, WeaverUtil.ImportMethod <ItemTracer>(assembly, "SetParameters"))); } for (var i = objTracingInstructions.Count - 1; i >= 0; i--) { ilProcessor.InsertAfter(lastInstruction, objTracingInstructions[i]); } }
/*--------------------------------------------------------------------------------------------*/ private void TryPropExpr() { vPropExprResult = WeaverUtil.GetPropertyDbName(vPropExpr); }
/*--------------------------------------------------------------------------------------------*/ public string GetPropertyDbName <T>(Expression <Func <T, object> > pExp) where T : IWeaverElement { return(WeaverUtil.GetPropertyDbName(pExp)); }
/*--------------------------------------------------------------------------------------------*/ public IWeaverPathPipeEnd BuildEdgeLabel <T>( Func <string, IWeaverVarAlias> pGetPropVarAliasByDbName) where T : IWeaverEdge { Type et = typeof(T); var e = WeaverTitanUtil.GetAndVerifyElementAttribute <WeaverTitanEdgeAttribute>(et); var ivc = e.InConn; var ovc = e.OutConn; var props = new List <WeaverPropPair>(); props.AddRange(WeaverUtil.GetElementPropertyAttributes(e.OutVertex)); props.AddRange(WeaverUtil.GetElementPropertyAttributes(e.InVertex)); var keys = new HashSet <string>(); var sigs = new HashSet <string>(); foreach (WeaverPropPair wpp in props) { WeaverTitanPropertyAttribute att = WeaverTitanUtil.GetAndVerifyTitanPropertyAttribute(wpp, true); if (att == null) { continue; } string alias = pGetPropVarAliasByDbName(att.DbName).Name; if (att.HasTitanVertexCentricIndex(et)) { keys.Add(alias); continue; } sigs.Add(alias); } //// AddCustom("makeType()"); AddCustom("name(" + Path.Query.AddParam(new WeaverQueryVal(e.DbName)) + ")"); if (keys.Count > 0) { AddCustom("primaryKey(" + string.Join(",", keys) + ")"); } if (sigs.Count > 0) { AddCustom("signature(" + string.Join(",", sigs) + ")"); } // An edge label is out-unique, if a vertex has at most one outgoing edge for that label. // "father" is of an out-unique edge label, since each god has at most one father. // https://github.com/thinkaurelius/titan/wiki/Type-Definition-Overview if (ivc == WeaverEdgeConn.InOne || ivc == WeaverEdgeConn.InZeroOrOne) { AddCustom("unique(IN)"); } if (ovc == WeaverEdgeConn.OutOne || ovc == WeaverEdgeConn.OutZeroOrOne) { AddCustom("unique(OUT)"); } return(AddCustom("makeEdgeLabel()")); }