void GenerateExpressionGetTreeMethod(Activity activity, CompiledExpressionDescriptor expressionDescriptor, CompiledDataContextDescriptor dataContextDescriptor, bool isValue, bool isStatement, int nextExpressionId) { CodeMemberMethod expressionMethod = new CodeMemberMethod(); expressionMethod.Attributes = MemberAttributes.Assembly | MemberAttributes.Final; expressionMethod.Name = string.Format(CultureInfo.InvariantCulture, expressionGetTreeString, nextExpressionId); expressionMethod.ReturnType = new CodeTypeReference(typeof(Expression)); expressionDescriptor.GetExpressionTreeMethodName = expressionMethod.Name; if (isStatement) { // Can't generate expression tree for a statement expressionMethod.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null))); dataContextDescriptor.CodeTypeDeclaration.Members.Add(expressionMethod); return; } string coreExpressionText = expressionDescriptor.ExpressionText; CodeLinePragma pragma; AlignText(activity, ref coreExpressionText, out pragma); Type returnType = typeof(Expression<>).MakeGenericType(typeof(Func<>).MakeGenericType(expressionDescriptor.ResultType)); string expressionText = null; if (IsVB) { expressionText = string.Concat(vbLambdaString, coreExpressionText); } else if (IsCS) { expressionText = string.Concat(csharpLambdaString, coreExpressionText); } if (expressionText != null) { CodeVariableDeclarationStatement statement = new CodeVariableDeclarationStatement(returnType, "expression", new CodeSnippetExpression(expressionText)); statement.LinePragma = pragma; expressionMethod.Statements.Add(statement); CodeMethodInvokeExpression invokeExpression = new CodeMethodInvokeExpression( new CodeBaseReferenceExpression(), "RewriteExpressionTree", new CodeExpression[] { new CodeVariableReferenceExpression("expression") }); expressionMethod.Statements.Add(new CodeMethodReturnStatement(invokeExpression)); } else { expressionMethod.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null))); } if (isValue) { dataContextDescriptor.CodeTypeDeclarationForReadOnly.Members.Add(expressionMethod); } else { dataContextDescriptor.CodeTypeDeclaration.Members.Add(expressionMethod); } }
bool TryGenerateExpressionCode(Activity activity, CompiledDataContextDescriptor dataContextDescriptor, int nextExpressionId, string language) { ITextExpression textExpression = (ITextExpression)activity; if (!TextExpression.LanguagesAreEqual(textExpression.Language, language) || string.IsNullOrWhiteSpace(textExpression.ExpressionText)) { // // We can only compile expressions that match the project's flavor // and expression activities with no expressions don't need anything generated. return false; } Type resultType = (activity is ActivityWithResult) ? ((ActivityWithResult)activity).ResultType : null; string expressionText = textExpression.ExpressionText; bool isReference = false; bool isValue = false; bool isStatement = false; if (resultType == null) { isStatement = true; } else { isReference = TypeHelper.AreTypesCompatible(resultType, typeof(Location)); isValue = !isReference; } CodeTypeDeclaration typeDeclaration; if (isValue) { typeDeclaration = dataContextDescriptor.CodeTypeDeclarationForReadOnly; } else { // // Statement and reference get read/write context typeDeclaration = dataContextDescriptor.CodeTypeDeclaration; } CompiledExpressionDescriptor descriptor = new CompiledExpressionDescriptor(); descriptor.TypeName = typeDeclaration.Name; descriptor.Id = nextExpressionId; descriptor.ExpressionText = textExpression.ExpressionText; if (isReference) { if (resultType.IsGenericType) { resultType = resultType.GetGenericArguments()[0]; } else { resultType = typeof(object); } } descriptor.ResultType = resultType; GenerateExpressionGetTreeMethod(activity, descriptor, dataContextDescriptor, isValue, isStatement, nextExpressionId); if (isValue || isReference) { CodeMemberMethod expressionGetMethod = GenerateGetMethod(activity, resultType, expressionText, nextExpressionId); typeDeclaration.Members.Add(expressionGetMethod); CodeMemberMethod expressionGetValueTypeAccessorMethod = GenerateGetMethodWrapper(expressionGetMethod); typeDeclaration.Members.Add(expressionGetValueTypeAccessorMethod); descriptor.GetMethodName = expressionGetValueTypeAccessorMethod.Name; } if (isReference) { CodeMemberMethod expressionSetMethod = GenerateSetMethod(activity, resultType, expressionText, nextExpressionId); dataContextDescriptor.CodeTypeDeclaration.Members.Add(expressionSetMethod); CodeMemberMethod expressionSetValueTypeAccessorMethod = GenerateSetMethodWrapper(expressionSetMethod); dataContextDescriptor.CodeTypeDeclaration.Members.Add(expressionSetValueTypeAccessorMethod); descriptor.SetMethodName = expressionSetValueTypeAccessorMethod.Name; } if (isStatement) { CodeMemberMethod statementMethod = GenerateStatementMethod(activity, expressionText, nextExpressionId); dataContextDescriptor.CodeTypeDeclaration.Members.Add(statementMethod); CodeMemberMethod expressionSetValueTypeAccessorMethod = GenerateStatementMethodWrapper(statementMethod); dataContextDescriptor.CodeTypeDeclaration.Members.Add(expressionSetValueTypeAccessorMethod); descriptor.StatementMethodName = expressionSetValueTypeAccessorMethod.Name; } expressionDescriptors.Add(descriptor); return true; }
CodeStatement[] GenerateStatementInvocation(CompiledExpressionDescriptor descriptor, bool withLocationReferences, Dictionary<string, int> cacheIndicies) { string indexString = descriptor.Id.ToString(CultureInfo.InvariantCulture); string dataContextVariableName = "valDataContext" + indexString; CodeVariableDeclarationStatement dataContextVariable = new CodeVariableDeclarationStatement( new CodeTypeReference(descriptor.TypeName), dataContextVariableName); CodeStatementCollection compiledDataContextStatements = new CodeStatementCollection(); GenerateGetDataContextVariable(descriptor, dataContextVariable, compiledDataContextStatements, withLocationReferences, cacheIndicies); compiledDataContextStatements.Add(dataContextVariable); CodeMethodInvokeExpression expressionInvoke = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeVariableReferenceExpression(dataContextVariableName), descriptor.StatementMethodName)); CodeMethodReturnStatement returnStatement = new CodeMethodReturnStatement(new CodePrimitiveExpression(null)); compiledDataContextStatements.Add(expressionInvoke); compiledDataContextStatements.Add(returnStatement); CodeStatement[] returnStatements = new CodeStatement[compiledDataContextStatements.Count]; compiledDataContextStatements.CopyTo(returnStatements, 0); return returnStatements; }
CodeStatement[] GenerateReferenceExpressionInvocation(CompiledExpressionDescriptor descriptor, bool withLocationReferences, Dictionary<string, int> cacheIndicies) { string indexString = descriptor.Id.ToString(CultureInfo.InvariantCulture); string dataContextVariableName = "refDataContext" + indexString; CodeVariableDeclarationStatement dataContextVariable = new CodeVariableDeclarationStatement( new CodeTypeReference(descriptor.TypeName), dataContextVariableName); CodeStatementCollection compiledDataContextStatements = new CodeStatementCollection(); GenerateGetDataContextVariable(descriptor, dataContextVariable, compiledDataContextStatements, withLocationReferences, cacheIndicies); compiledDataContextStatements.Add(dataContextVariable); CodeExpression getExpression = null; CodeExpression setExpression = null; if (this.IsVB) { getExpression = new CodeDelegateCreateExpression( new CodeTypeReference(descriptor.TypeName), new CodeVariableReferenceExpression(dataContextVariableName), descriptor.GetMethodName); setExpression = new CodeDelegateCreateExpression( new CodeTypeReference(descriptor.TypeName), new CodeVariableReferenceExpression(dataContextVariableName), descriptor.SetMethodName); } else { getExpression = new CodeMethodReferenceExpression(new CodeVariableReferenceExpression(dataContextVariableName), descriptor.GetMethodName); setExpression = new CodeMethodReferenceExpression(new CodeVariableReferenceExpression(dataContextVariableName), descriptor.SetMethodName); } CodeMethodReferenceExpression getLocationMethod = new CodeMethodReferenceExpression( new CodeVariableReferenceExpression(dataContextVariableName), "GetLocation", new CodeTypeReference[] { new CodeTypeReference(descriptor.ResultType) }); CodeExpression[] getLocationParameters = null; if (withLocationReferences) { getLocationParameters = new CodeExpression[] { getExpression, setExpression, new CodeVariableReferenceExpression("expressionId"), new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), rootActivityFieldName), new CodeVariableReferenceExpression("activityContext") }; } else { getLocationParameters = new CodeExpression[] { getExpression, setExpression }; } CodeMethodInvokeExpression getLocationExpression = new CodeMethodInvokeExpression( getLocationMethod, getLocationParameters); CodeMethodReturnStatement returnStatement = new CodeMethodReturnStatement(getLocationExpression); compiledDataContextStatements.Add(returnStatement); CodeStatement[] returnStatements = new CodeStatement[compiledDataContextStatements.Count]; compiledDataContextStatements.CopyTo(returnStatements, 0); return returnStatements; }
void GenerateGetDataContextVariable(CompiledExpressionDescriptor descriptor, CodeVariableDeclarationStatement dataContextVariable, CodeStatementCollection statements, bool withLocationReferences, Dictionary<string, int> cacheIndicies) { CodeObjectCreateExpression dataContext = GenerateDataContextCreateExpression(descriptor.TypeName, withLocationReferences); if (withLocationReferences) { // // System.Activities.XamlIntegration.CompiledDataContext[] cachedCompiledDataContext = CompiledExpressions_TypedDataContext2.GetCompiledDataContextCacheHelper(this, activityContext, 2); // if ((cachedCompiledDataContext[1] == null)) // { // if (!CompiledExpressions_TypedDataContext2.Validate(locations, activityContext)) // { // return false; // } // cachedCompiledDataContext[1] = new CompiledExpressions_TypedDataContext2(locations, activityContext); // } // CodeVariableDeclarationStatement cachedCompiledDataContextArray = new CodeVariableDeclarationStatement( typeof(CompiledDataContext[]), "cachedCompiledDataContext", new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeTypeReferenceExpression(descriptor.TypeName), "GetCompiledDataContextCacheHelper"), new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), dataContextActivitiesFieldName), new CodeVariableReferenceExpression("activityContext"), new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), rootActivityFieldName), new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), forImplementationName), new CodePrimitiveExpression(cacheIndicies.Count))); CodeIndexerExpression compiledDataContextIndexer = new CodeIndexerExpression( new CodeVariableReferenceExpression("cachedCompiledDataContext"), new CodePrimitiveExpression(cacheIndicies[descriptor.TypeName])); // // if (cachedCompiledDataContext[index] == null) // { // cachedCompiledDataContext[index] = new TCDC(locations, activityContext); // } // CodeBinaryOperatorExpression nullCacheItemExpression = new CodeBinaryOperatorExpression( compiledDataContextIndexer, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)); CodeAssignStatement cacheIndexInitializer = new CodeAssignStatement( compiledDataContextIndexer, dataContext); CodeConditionStatement conditionStatement = new CodeConditionStatement( nullCacheItemExpression, cacheIndexInitializer); // // [compiledDataContextVariable] = cachedCompiledDataContext[index] // dataContextVariable.InitExpression = new CodeCastExpression(descriptor.TypeName, compiledDataContextIndexer); statements.Add(cachedCompiledDataContextArray); statements.Add(conditionStatement); } else { // // [compiledDataContextVariable] = new [compiledDataContextType](locations); // dataContextVariable.InitExpression = dataContext; } }
CodeConditionStatement GenerateDataContextActivitiesCheck(CompiledExpressionDescriptor descriptor) { CodeBinaryOperatorExpression dataContextActivitiesNullExpression = new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), dataContextActivitiesFieldName), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)); CodeConditionStatement dataContextActivitiesNullStatement = new CodeConditionStatement( dataContextActivitiesNullExpression, new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), dataContextActivitiesFieldName), new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeTypeReferenceExpression(new CodeTypeReference(descriptor.TypeName)), "GetDataContextActivitiesHelper"), new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), rootActivityFieldName), new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), forImplementationName)))); return dataContextActivitiesNullStatement; }