Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -0,0 +1,95 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.Statements;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Runtime;
public sealed class Add<TLeft, TRight, TResult> : CodeActivity<TResult>
{
//Lock is not needed for operationFunction here. The reason is that delegates for a given Add<TLeft, TRight, TResult> are the same.
//It's possible that 2 threads are assigning the operationFucntion at the same time. But it's okay because the compiled codes are the same.
static Func<TLeft, TRight, TResult> checkedOperationFunction;
static Func<TLeft, TRight, TResult> uncheckedOperationFunction;
bool checkedOperation = true;
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TLeft> Left
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TRight> Right
{
get;
set;
}
[DefaultValue(true)]
public bool Checked
{
get { return this.checkedOperation; }
set { this.checkedOperation = value; }
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
BinaryExpressionHelper.OnGetArguments(metadata, this.Left, this.Right);
if (this.checkedOperation)
{
EnsureOperationFunction(metadata, ref checkedOperationFunction, ExpressionType.AddChecked);
}
else
{
EnsureOperationFunction(metadata, ref uncheckedOperationFunction, ExpressionType.Add);
}
}
void EnsureOperationFunction(CodeActivityMetadata metadata,
ref Func<TLeft, TRight, TResult> operationFunction,
ExpressionType operatorType)
{
if (operationFunction == null)
{
ValidationError validationError;
if (!BinaryExpressionHelper.TryGenerateLinqDelegate(
operatorType,
out operationFunction,
out validationError))
{
metadata.AddValidationError(validationError);
}
}
}
protected override TResult Execute(CodeActivityContext context)
{
TLeft leftValue = this.Left.Get(context);
TRight rightValue = this.Right.Get(context);
//if user changed Checked flag between Open and Execution,
//a NRE may be thrown and that's by design
if (this.checkedOperation)
{
return checkedOperationFunction(leftValue, rightValue);
}
else
{
return uncheckedOperationFunction(leftValue, rightValue);
}
}
}
}

View File

@@ -0,0 +1,62 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.Statements;
using System.Linq.Expressions;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime;
using System.Diagnostics.CodeAnalysis;
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotMatchKeywords,
Justification = "Optimizing for XAML naming. VB imperative users will [] qualify (e.g. New [And])")]
public sealed class And<TLeft, TRight, TResult> : CodeActivity<TResult>
{
//Lock is not needed for operationFunction here. The reason is that delegates for a given And<TLeft, TRight, TResult> are the same.
//It's possible that 2 threads are assigning the operationFucntion at the same time. But it's okay because the compiled codes are the same.
static Func<TLeft, TRight, TResult> operationFunction;
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TLeft> Left
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TRight> Right
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
BinaryExpressionHelper.OnGetArguments(metadata, this.Left, this.Right);
if (operationFunction == null)
{
ValidationError validationError;
if (!BinaryExpressionHelper.TryGenerateLinqDelegate(ExpressionType.And, out operationFunction, out validationError))
{
metadata.AddValidationError(validationError);
}
}
}
protected override TResult Execute(CodeActivityContext context)
{
Fx.Assert(operationFunction != null, "OperationFunction must exist.");
TLeft leftValue = this.Left.Get(context);
TRight rightValue = this.Right.Get(context);
return operationFunction(leftValue, rightValue);
}
}
}

View File

@@ -0,0 +1,82 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.DynamicUpdate;
using System.Activities.Statements;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotMatchKeywords, Justification = "Optimizing for XAML naming. VB imperative users will [] qualify (e.g. New [AndAlso])")]
public sealed class AndAlso : Activity<bool>
{
public AndAlso()
: base()
{
this.Implementation =
() =>
{
if (this.Left != null && this.Right != null)
{
return new If
{
Condition = this.Left,
Then = new Assign<bool>
{
To = new OutArgument<bool>(context => this.Result.Get(context)),
Value = new InArgument<bool>(this.Right)
},
Else = new Assign<bool>
{
To = new OutArgument<bool>(context => this.Result.Get(context)),
Value = false,
}
};
}
else
{
return null;
}
};
}
[DefaultValue(null)]
public Activity<bool> Left
{
get;
set;
}
[DefaultValue(null)]
public Activity<bool> Right
{
get;
set;
}
protected override void OnCreateDynamicUpdateMap(UpdateMapMetadata metadata, Activity originalActivity)
{
metadata.AllowUpdateInsideThisActivity();
}
protected override void CacheMetadata(ActivityMetadata metadata)
{
metadata.AddImportedChild(this.Left);
metadata.AddImportedChild(this.Right);
if (this.Left == null)
{
metadata.AddValidationError(SR.BinaryExpressionActivityRequiresArgument("Left", "AndAlso", this.DisplayName));
}
if (this.Right == null)
{
metadata.AddValidationError(SR.BinaryExpressionActivityRequiresArgument("Right", "AndAlso", this.DisplayName));
}
}
}
}

View File

@@ -0,0 +1,69 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime;
using System.Windows.Markup;
public sealed class ArgumentReference<T> : EnvironmentLocationReference<T>
{
RuntimeArgument targetArgument;
public ArgumentReference()
{
}
public ArgumentReference(string argumentName)
{
this.ArgumentName = argumentName;
}
public string ArgumentName
{
get;
set;
}
public override LocationReference LocationReference
{
get { return this.targetArgument; }
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
this.targetArgument = null;
if (string.IsNullOrEmpty(this.ArgumentName))
{
metadata.AddValidationError(SR.ArgumentNameRequired);
}
else
{
this.targetArgument = ActivityUtilities.FindArgument(this.ArgumentName, this);
if (this.targetArgument == null)
{
metadata.AddValidationError(SR.ArgumentNotFound(this.ArgumentName));
}
else if (this.targetArgument.Type != typeof(T))
{
metadata.AddValidationError(SR.ArgumentTypeMustBeCompatible(this.ArgumentName, this.targetArgument.Type, typeof(T)));
}
}
}
public override string ToString()
{
if (!string.IsNullOrEmpty(this.ArgumentName))
{
return this.ArgumentName;
}
return base.ToString();
}
}
}

View File

@@ -0,0 +1,69 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime;
using System.Windows.Markup;
public sealed class ArgumentValue<T> : EnvironmentLocationValue<T>
{
RuntimeArgument targetArgument;
public ArgumentValue()
{
}
public ArgumentValue(string argumentName)
{
this.ArgumentName = argumentName;
}
public string ArgumentName
{
get;
set;
}
public override LocationReference LocationReference
{
get { return this.targetArgument; }
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
this.targetArgument = null;
if (string.IsNullOrEmpty(this.ArgumentName))
{
metadata.AddValidationError(SR.ArgumentNameRequired);
}
else
{
this.targetArgument = ActivityUtilities.FindArgument(this.ArgumentName, this);
if (this.targetArgument == null)
{
metadata.AddValidationError(SR.ArgumentNotFound(this.ArgumentName));
}
else if (!TypeHelper.AreTypesCompatible(this.targetArgument.Type, typeof(T)))
{
metadata.AddValidationError(SR.ArgumentTypeMustBeCompatible(this.ArgumentName, this.targetArgument.Type, typeof(T)));
}
}
}
public override string ToString()
{
if (!string.IsNullOrEmpty(this.ArgumentName))
{
return this.ArgumentName;
}
return base.ToString();
}
}
}

View File

@@ -0,0 +1,109 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities.Statements;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.Serialization;
public sealed class ArrayItemReference<TItem> : CodeActivity<Location<TItem>>
{
public ArrayItemReference()
: base()
{
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TItem[]> Array
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<int> Index
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
RuntimeArgument arrayArgument = new RuntimeArgument("Array", typeof(TItem[]), ArgumentDirection.In, true);
metadata.Bind(this.Array, arrayArgument);
RuntimeArgument indexArgument = new RuntimeArgument("Index", typeof(int), ArgumentDirection.In, true);
metadata.Bind(this.Index, indexArgument);
RuntimeArgument resultArgument = new RuntimeArgument("Result", typeof(Location<TItem>), ArgumentDirection.Out);
metadata.Bind(this.Result, resultArgument);
metadata.SetArgumentsCollection(
new Collection<RuntimeArgument>
{
arrayArgument,
indexArgument,
resultArgument
});
}
protected override Location<TItem> Execute(CodeActivityContext context)
{
TItem[] items = this.Array.Get(context);
if (items == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.MemberCannotBeNull("Array", this.GetType().Name, this.DisplayName)));
}
int itemIndex = this.Index.Get(context);
return new ArrayLocation(items, itemIndex);
}
[DataContract]
internal class ArrayLocation : Location<TItem>
{
TItem[] array;
int index;
public ArrayLocation(TItem[] array, int index)
: base()
{
this.array = array;
this.index = index;
}
public override TItem Value
{
get
{
return this.array[this.index];
}
set
{
this.array[this.index] = value;
}
}
[DataMember(Name = "array")]
internal TItem[] SerializedArray
{
get { return this.array; }
set { this.array = value; }
}
[DataMember(EmitDefaultValue = false, Name = "index")]
internal int SerializedIndex
{
get { return this.index; }
set { this.index = value; }
}
}
}
}

View File

@@ -0,0 +1,65 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System;
using System.Activities.Statements;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
public sealed class ArrayItemValue<TItem> : CodeActivity<TItem>
{
public ArrayItemValue()
: base()
{
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TItem[]> Array
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<int> Index
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
RuntimeArgument arrayArgument = new RuntimeArgument("Array", typeof(TItem[]), ArgumentDirection.In, true);
metadata.Bind(this.Array, arrayArgument);
RuntimeArgument indexArgument = new RuntimeArgument("Index", typeof(int), ArgumentDirection.In, true);
metadata.Bind(this.Index, indexArgument);
metadata.SetArgumentsCollection(
new Collection<RuntimeArgument>
{
arrayArgument,
indexArgument,
});
}
protected override TItem Execute(CodeActivityContext context)
{
TItem[] items = this.Array.Get(context);
if (items == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.MemberCannotBeNull("Array", this.GetType().Name, this.DisplayName)));
}
int itemIndex = this.Index.Get(context);
return items[itemIndex];
}
}
}

View File

@@ -0,0 +1,53 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.Statements;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Runtime;
[SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotMatchKeywords,
Justification = "Optimizing for XAML naming. VB imperative users will [] qualify (e.g. New [As])")]
public sealed class As<TOperand, TResult> : CodeActivity<TResult>
{
//Lock is not needed for operationFunction here. The reason is that delegates for a given As<TLeft, TRight, TResult> are the same.
//It's possible that 2 threads are assigning the operationFucntion at the same time. But it's okay because the compiled codes are the same.
static Func<TOperand, TResult> operationFunction;
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TOperand> Operand
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
UnaryExpressionHelper.OnGetArguments(metadata, this.Operand);
if (operationFunction == null)
{
ValidationError validationError;
if (!UnaryExpressionHelper.TryGenerateLinqDelegate(ExpressionType.TypeAs, out operationFunction, out validationError))
{
metadata.AddValidationError(validationError);
}
}
}
protected override TResult Execute(CodeActivityContext context)
{
Fx.Assert(operationFunction != null, "OperationFunction must exist.");
TOperand operandValue = this.Operand.Get(context);
return operationFunction(operandValue);
}
}
}

View File

@@ -0,0 +1,158 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime;
class AssemblyNameEqualityComparer : IEqualityComparer, IEqualityComparer<AssemblyName>
{
public AssemblyNameEqualityComparer()
{
}
public new bool Equals(object xparam, object yparam)
{
if (xparam == null && yparam == null)
{
return true;
}
return this.Equals(xparam as AssemblyName, yparam as AssemblyName);
}
public bool Equals(AssemblyName x, AssemblyName y)
{
// this expects non-null AssemblyName
if (x == null || y == null)
{
return false;
}
if (Object.ReferenceEquals(x, y))
{
return true;
}
if (x.Name != null && y.Name != null)
{
if (string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) != 0)
{
return false;
}
}
else if (!(x.Name == null && y.Name == null))
{
return false;
}
if (x.Version != null && y.Version != null)
{
if (x.Version != y.Version)
{
return false;
}
}
else if (!(x.Version == null && y.Version == null))
{
return false;
}
if (x.CultureInfo != null && y.CultureInfo != null)
{
if (!x.CultureInfo.Equals(y.CultureInfo))
{
return false;
}
}
else if (!(x.CultureInfo == null && y.CultureInfo == null))
{
return false;
}
byte[] xArray = x.GetPublicKeyToken();
byte[] yArray = y.GetPublicKeyToken();
if (!IsSameKeyToken(xArray, yArray))
{
return false;
}
return true;
}
public int GetHashCode(object objparam)
{
AssemblyName obj = objparam as AssemblyName;
if (obj == null)
{
return 0;
}
return this.GetHashCode(obj);
}
public int GetHashCode(AssemblyName obj)
{
int hashcode = 0;
if (obj.Name != null)
{
hashcode ^= obj.Name.GetHashCode();
}
if (obj.Version != null)
{
hashcode ^= obj.Version.GetHashCode();
}
if (obj.CultureInfo != null)
{
hashcode ^= obj.CultureInfo.GetHashCode();
}
byte[] objArray = obj.GetPublicKeyToken();
if (objArray != null)
{
// distinguishing no PKToken from "PKToken = null" which is an array of length=0
hashcode ^= objArray.Length.GetHashCode() + 1;
if (objArray.Length > 0)
{
hashcode ^= BitConverter.ToUInt64(objArray, 0).GetHashCode();
}
}
return hashcode;
}
public static bool IsSameKeyToken(byte[] reqKeyToken, byte[] curKeyToken)
{
bool isSame = false;
if (reqKeyToken == null && curKeyToken == null)
{
// Both Key Tokens are not set, treat them as same.
isSame = true;
}
else if (reqKeyToken != null && curKeyToken != null)
{
// Both KeyTokens are set.
if (reqKeyToken.Length == curKeyToken.Length)
{
isSame = true;
for (int i = 0; i < reqKeyToken.Length; i++)
{
if (reqKeyToken[i] != curKeyToken[i])
{
isSame = false;
break;
}
}
}
}
return isSame;
}
}
}

View File

@@ -0,0 +1,302 @@
// <copyright>
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
namespace System.Activities.Expressions
{
using System;
using System.Activities.XamlIntegration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime;
using System.Xaml;
[TypeConverter(typeof(AssemblyReferenceConverter))]
public class AssemblyReference
{
private const int AssemblyToAssemblyNameCacheInitSize = 100;
private const int AssemblyCacheInitialSize = 100;
// cache for Assembly ==> AssemblyName
// Assembly.GetName() is very very expensive
private static object assemblyToAssemblyNameCacheLock = new object();
// Double-checked locking pattern requires volatile for read/write synchronization
private static volatile Hashtable assemblyToAssemblyNameCache;
// cache for AssemblyName ==> Assembly
// For back-compat with VB (which in turn was roughly emulating XamlSchemaContext)
// we want to cache a given AssemblyName once it's resolved, so it doesn't get re-resolved
// even if a new matching assembly is loaded later.
// Double-checked locking pattern requires volatile for read/write synchronization
private static volatile Hashtable assemblyCache;
private static object assemblyCacheLock = new object();
private Assembly assembly;
private AssemblyName assemblyName;
private bool isImmutable;
public AssemblyReference()
{
}
// This immutable ctor is for the default references, so they can be shared freely
internal AssemblyReference(Assembly assembly, AssemblyName assemblyName)
{
this.assembly = assembly;
this.assemblyName = assemblyName;
this.isImmutable = true;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Assembly Assembly
{
get
{
return this.assembly;
}
set
{
this.ThrowIfImmutable();
this.assembly = value;
}
}
public AssemblyName AssemblyName
{
get
{
return this.assemblyName;
}
set
{
this.ThrowIfImmutable();
this.assemblyName = value;
}
}
[SuppressMessage(FxCop.Category.Usage, FxCop.Rule.OperatorOverloadsHaveNamedAlternates,
Justification = "A named method provides no advantage over the property setter.")]
public static implicit operator AssemblyReference(Assembly assembly)
{
return new AssemblyReference { Assembly = assembly };
}
[SuppressMessage(FxCop.Category.Usage, FxCop.Rule.OperatorOverloadsHaveNamedAlternates,
Justification = "A named method provides no advantage over the property setter.")]
public static implicit operator AssemblyReference(AssemblyName assemblyName)
{
return new AssemblyReference { AssemblyName = assemblyName };
}
public void LoadAssembly()
{
if (AssemblyName != null && (this.assembly == null || !this.isImmutable))
{
this.assembly = GetAssembly(this.AssemblyName);
}
}
// this code is borrowed from XamlSchemaContext
internal static bool AssemblySatisfiesReference(AssemblyName assemblyName, AssemblyName reference)
{
if (reference.Name != assemblyName.Name)
{
return false;
}
if (reference.Version != null && !reference.Version.Equals(assemblyName.Version))
{
return false;
}
if (reference.CultureInfo != null && !reference.CultureInfo.Equals(assemblyName.CultureInfo))
{
return false;
}
byte[] requiredToken = reference.GetPublicKeyToken();
if (requiredToken != null)
{
byte[] actualToken = assemblyName.GetPublicKeyToken();
if (!AssemblyNameEqualityComparer.IsSameKeyToken(requiredToken, actualToken))
{
return false;
}
}
return true;
}
internal static Assembly GetAssembly(AssemblyName assemblyName)
{
// the following assembly resolution logic
// emulates the Xaml's assembly resolution logic as closely as possible.
// Should Xaml's assembly resolution logic ever change, this code needs update as well.
// please see XamlSchemaContext.ResolveAssembly()
if (assemblyCache == null)
{
lock (assemblyCacheLock)
{
if (assemblyCache == null)
{
assemblyCache = new Hashtable(AssemblyCacheInitialSize, new AssemblyNameEqualityComparer());
}
}
}
Assembly assembly = assemblyCache[assemblyName] as Assembly;
if (assembly != null)
{
return assembly;
}
// search current AppDomain first
// this for-loop part is to ensure that
// loose AssemblyNames get resolved in the same way
// as Xaml would do. that is to find the first match
// found starting from the end of the array of Assemblies
// returned by AppDomain.GetAssemblies()
Assembly[] currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = currentAssemblies.Length - 1; i >= 0; i--)
{
Assembly curAsm = currentAssemblies[i];
if (curAsm.IsDynamic)
{
// ignore dynamic assemblies
continue;
}
AssemblyName curAsmName = GetFastAssemblyName(curAsm);
Version curVersion = curAsmName.Version;
CultureInfo curCulture = curAsmName.CultureInfo;
byte[] curKeyToken = curAsmName.GetPublicKeyToken();
Version reqVersion = assemblyName.Version;
CultureInfo reqCulture = assemblyName.CultureInfo;
byte[] reqKeyToken = assemblyName.GetPublicKeyToken();
if ((String.Compare(curAsmName.Name, assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0) &&
(reqVersion == null || reqVersion.Equals(curVersion)) &&
(reqCulture == null || reqCulture.Equals(curCulture)) &&
(reqKeyToken == null || AssemblyNameEqualityComparer.IsSameKeyToken(reqKeyToken, curKeyToken)))
{
lock (assemblyCacheLock)
{
assemblyCache[assemblyName] = curAsm;
return curAsm;
}
}
}
assembly = LoadAssembly(assemblyName);
if (assembly != null)
{
lock (assemblyCacheLock)
{
assemblyCache[assemblyName] = assembly;
}
}
return assembly;
}
// this gets the cached AssemblyName
// if not found, it caches the Assembly and creates its AssemblyName set it as the value
// we don't cache DynamicAssemblies because they may be collectible and we don't want to root them
internal static AssemblyName GetFastAssemblyName(Assembly assembly)
{
if (assembly.IsDynamic)
{
return new AssemblyName(assembly.FullName);
}
if (assemblyToAssemblyNameCache == null)
{
lock (assemblyToAssemblyNameCacheLock)
{
if (assemblyToAssemblyNameCache == null)
{
assemblyToAssemblyNameCache = new Hashtable(AssemblyToAssemblyNameCacheInitSize);
}
}
}
AssemblyName assemblyName = assemblyToAssemblyNameCache[assembly] as AssemblyName;
if (assemblyName != null)
{
return assemblyName;
}
assemblyName = new AssemblyName(assembly.FullName);
lock (assemblyToAssemblyNameCacheLock)
{
assemblyToAssemblyNameCache[assembly] = assemblyName;
}
return assemblyName;
}
#pragma warning disable 618
[SuppressMessage(
"Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods",
MessageId = "System.Reflection.Assembly.LoadWithPartialName",
Justification = "Assembly.LoadWithPartialName is the only method with the right behavior.")]
private static Assembly LoadAssembly(AssemblyName assemblyName)
{
Assembly loaded = null;
Fx.Assert(assemblyName.Name != null, "AssemblyName.Name cannot be null");
byte[] publicKeyToken = assemblyName.GetPublicKeyToken();
if (assemblyName.Version != null || assemblyName.CultureInfo != null || publicKeyToken != null)
{
// Assembly.Load(string)
try
{
loaded = Assembly.Load(assemblyName.FullName);
}
catch (Exception ex)
{
if (ex is FileNotFoundException ||
ex is FileLoadException ||
(ex is TargetInvocationException &&
(((TargetInvocationException)ex).InnerException is FileNotFoundException ||
((TargetInvocationException)ex).InnerException is FileNotFoundException)))
{
loaded = null;
FxTrace.Exception.AsWarning(ex);
}
else
{
throw;
}
}
}
else
{
// partial assembly name
loaded = Assembly.LoadWithPartialName(assemblyName.FullName);
}
return loaded;
}
#pragma warning restore 618
private void ThrowIfImmutable()
{
if (this.isImmutable)
{
throw FxTrace.Exception.AsError(new NotSupportedException(SR.AssemblyReferenceIsImmutable));
}
}
}
}

View File

@@ -0,0 +1,62 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities.Validation;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Runtime;
static class BinaryExpressionHelper
{
public static void OnGetArguments<TLeft, TRight>(CodeActivityMetadata metadata, InArgument<TLeft> left, InArgument<TRight> right)
{
RuntimeArgument rightArgument = new RuntimeArgument("Right", typeof(TRight), ArgumentDirection.In, true);
metadata.Bind(right, rightArgument);
RuntimeArgument leftArgument = new RuntimeArgument("Left", typeof(TLeft), ArgumentDirection.In, true);
metadata.Bind(left, leftArgument);
metadata.SetArgumentsCollection(
new Collection<RuntimeArgument>
{
rightArgument,
leftArgument
});
}
public static bool TryGenerateLinqDelegate<TLeft, TRight, TResult>(ExpressionType operatorType, out Func<TLeft, TRight, TResult> function, out ValidationError validationError)
{
function = null;
validationError = null;
ParameterExpression leftParameter = Expression.Parameter(typeof(TLeft), "left");
ParameterExpression rightParameter = Expression.Parameter(typeof(TRight), "right");
try
{
BinaryExpression binaryExpression = Expression.MakeBinary(operatorType, leftParameter, rightParameter);
Expression expressionToCompile = OperatorPermissionHelper.InjectReflectionPermissionIfNecessary(binaryExpression.Method, binaryExpression);
Expression<Func<TLeft, TRight, TResult>> lambdaExpression = Expression.Lambda<Func<TLeft, TRight, TResult>>(expressionToCompile, leftParameter, rightParameter);
function = lambdaExpression.Compile();
return true;
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
validationError = new ValidationError(e.Message);
return false;
}
}
}
}

View File

@@ -0,0 +1,85 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.Statements;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Runtime;
public sealed class Cast<TOperand, TResult> : CodeActivity<TResult>
{
//Lock is not needed for operationFunction here. The reason is that delegates for a given Cast<TLeft, TRight, TResult> are the same.
//It's possible that 2 threads are assigning the operationFucntion at the same time. But it's okay because the compiled codes are the same.
static Func<TOperand, TResult> checkedOperationFunction;
static Func<TOperand, TResult> uncheckedOperationFunction;
bool checkedOperation = true;
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TOperand> Operand
{
get;
set;
}
[DefaultValue(true)]
public bool Checked
{
get { return this.checkedOperation; }
set { this.checkedOperation = value; }
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
UnaryExpressionHelper.OnGetArguments(metadata, this.Operand);
if (this.checkedOperation)
{
EnsureOperationFunction(metadata, ref checkedOperationFunction, ExpressionType.ConvertChecked);
}
else
{
EnsureOperationFunction(metadata, ref uncheckedOperationFunction, ExpressionType.Convert);
}
}
void EnsureOperationFunction(CodeActivityMetadata metadata,
ref Func<TOperand, TResult> operationFunction,
ExpressionType operatorType)
{
if (operationFunction == null)
{
ValidationError validationError;
if (!UnaryExpressionHelper.TryGenerateLinqDelegate(
operatorType,
out operationFunction,
out validationError))
{
metadata.AddValidationError(validationError);
}
}
}
protected override TResult Execute(CodeActivityContext context)
{
TOperand operandValue = this.Operand.Get(context);
//if user changed Checked flag between Open and Execution,
//a NRE may be thrown and that's by design
if (this.checkedOperation)
{
return checkedOperationFunction(operandValue);
}
else
{
return uncheckedOperationFunction(operandValue);
}
}
}
}

View File

@@ -0,0 +1,360 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System;
using System.Activities.XamlIntegration;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Xaml;
public class CompiledExpressionInvoker
{
private static readonly AttachableMemberIdentifier compiledExpressionRootProperty =
new AttachableMemberIdentifier(typeof(CompiledExpressionInvoker), "CompiledExpressionRoot");
private static readonly AttachableMemberIdentifier compiledExpressionRootForImplementationProperty =
new AttachableMemberIdentifier(typeof(CompiledExpressionInvoker), "CompiledExpressionRootForImplementation");
int expressionId;
Activity expressionActivity;
bool isReference;
ITextExpression textExpression;
Activity metadataRoot;
ICompiledExpressionRoot compiledRoot;
IList<LocationReference> locationReferences;
CodeActivityMetadata metadata;
CodeActivityPublicEnvironmentAccessor accessor;
public bool IsStaticallyCompiled
{
get;
private set;
}
public CompiledExpressionInvoker(ITextExpression expression, bool isReference, CodeActivityMetadata metadata)
{
if (expression == null)
{
throw FxTrace.Exception.ArgumentNull("expression");
}
if (metadata == null)
{
throw FxTrace.Exception.ArgumentNull("metadata");
}
this.expressionId = -1;
this.textExpression = expression;
this.expressionActivity = expression as Activity;
this.isReference = isReference;
this.locationReferences = new List<LocationReference>();
this.metadata = metadata;
this.accessor = CodeActivityPublicEnvironmentAccessor.Create(this.metadata);
if (this.expressionActivity == null)
{
throw FxTrace.Exception.Argument("expression", SR.ITextExpressionParameterMustBeActivity);
}
ActivityWithResult resultActivity = this.expressionActivity as ActivityWithResult;
this.metadataRoot = metadata.Environment.Root;
this.ProcessLocationReferences();
}
public object InvokeExpression(ActivityContext activityContext)
{
if (activityContext == null)
{
throw FxTrace.Exception.ArgumentNull("activityContext");
}
if (this.compiledRoot == null || this.expressionId < 0)
{
if (!TryGetCompiledExpressionRoot(this.expressionActivity, this.metadataRoot, out this.compiledRoot) ||
!CanExecuteExpression(this.compiledRoot, out expressionId))
{
if (!TryGetCurrentCompiledExpressionRoot(activityContext, out this.compiledRoot, out this.expressionId))
{
throw FxTrace.Exception.AsError(new NotSupportedException(SR.TextExpressionMetadataRequiresCompilation(this.expressionActivity.GetType().Name)));
}
}
}
return this.compiledRoot.InvokeExpression(this.expressionId, this.locationReferences, activityContext);
}
//
// Attached property setter for the compiled expression root for the public surface area of an activity
public static void SetCompiledExpressionRoot(object target, ICompiledExpressionRoot compiledExpressionRoot)
{
if (compiledExpressionRoot == null)
{
AttachablePropertyServices.RemoveProperty(target, compiledExpressionRootProperty);
}
else
{
AttachablePropertyServices.SetProperty(target, compiledExpressionRootProperty, compiledExpressionRoot);
}
}
//
// Attached property getter for the compiled expression root for the public surface area of an activity
public static object GetCompiledExpressionRoot(object target)
{
object value = null;
AttachablePropertyServices.TryGetProperty(target, compiledExpressionRootProperty, out value);
return value;
}
//
// Attached property setter for the compiled expression root for the implementation surface area of an activity
public static void SetCompiledExpressionRootForImplementation(object target, ICompiledExpressionRoot compiledExpressionRoot)
{
if (compiledExpressionRoot == null)
{
AttachablePropertyServices.RemoveProperty(target, compiledExpressionRootForImplementationProperty);
}
else
{
AttachablePropertyServices.SetProperty(target, compiledExpressionRootForImplementationProperty, compiledExpressionRoot);
}
}
//
// Attached property getter for the compiled expression root for the implementation surface area of an activity
public static object GetCompiledExpressionRootForImplementation(object target)
{
object value = null;
AttachablePropertyServices.TryGetProperty(target, compiledExpressionRootForImplementationProperty, out value);
return value;
}
//
// Internal helper to find the correct ICER for a given expression.
internal static bool TryGetCompiledExpressionRoot(Activity expression, Activity target, out ICompiledExpressionRoot compiledExpressionRoot)
{
bool forImplementation = expression.MemberOf != expression.RootActivity.MemberOf;
return TryGetCompiledExpressionRoot(target, forImplementation, out compiledExpressionRoot);
}
//
// Helper to find the correct ICER for a given expression.
// This is separate from the above because within this class we switch forImplementation for the same target Activity
// to matched the ICER model of using one ICER for all expressions in the implementation and root argument defaults.
internal static bool TryGetCompiledExpressionRoot(Activity target, bool forImplementation, out ICompiledExpressionRoot compiledExpressionRoot)
{
if (!forImplementation)
{
compiledExpressionRoot = GetCompiledExpressionRoot(target) as ICompiledExpressionRoot;
if (compiledExpressionRoot != null)
{
return true;
}
//
// Default expressions for Arguments show up in the public surface area
// If we didn't find an ICER for the public surface area continue
// and try to use the implementation ICER
}
if (target is ICompiledExpressionRoot)
{
compiledExpressionRoot = (ICompiledExpressionRoot)target;
return true;
}
compiledExpressionRoot = GetCompiledExpressionRootForImplementation(target) as ICompiledExpressionRoot;
if (compiledExpressionRoot != null)
{
return true;
}
compiledExpressionRoot = null;
return false;
}
internal Expression GetExpressionTree()
{
if (this.compiledRoot == null || this.expressionId < 0)
{
if (!TryGetCompiledExpressionRootAtDesignTime(this.expressionActivity, this.metadataRoot, out this.compiledRoot, out this.expressionId))
{
return null;
}
}
return this.compiledRoot.GetExpressionTreeForExpression(this.expressionId, this.locationReferences);
}
bool TryGetCurrentCompiledExpressionRoot(ActivityContext activityContext, out ICompiledExpressionRoot compiledExpressionRoot, out int expressionId)
{
ActivityInstance current = activityContext.CurrentInstance;
while (current != null && current.Activity != this.metadataRoot)
{
ICompiledExpressionRoot currentCompiledExpressionRoot = null;
if (CompiledExpressionInvoker.TryGetCompiledExpressionRoot(current.Activity, true, out currentCompiledExpressionRoot))
{
if (CanExecuteExpression(currentCompiledExpressionRoot, out expressionId))
{
compiledExpressionRoot = currentCompiledExpressionRoot;
return true;
}
}
current = current.Parent;
}
compiledExpressionRoot = null;
expressionId = -1;
return false;
}
bool CanExecuteExpression(ICompiledExpressionRoot compiledExpressionRoot, out int expressionId)
{
if (compiledExpressionRoot.CanExecuteExpression(this.textExpression.ExpressionText, this.isReference, locationReferences, out expressionId))
{
return true;
}
return false;
}
void ProcessLocationReferences()
{
Stack<LocationReferenceEnvironment> environments = new Stack<LocationReferenceEnvironment>();
//
// Build list of location by enumerating environments
// in top down order to match the traversal pattern of TextExpressionCompiler
LocationReferenceEnvironment current = this.accessor.ActivityMetadata.Environment;
while (current != null)
{
environments.Push(current);
current = current.Parent;
}
foreach (LocationReferenceEnvironment environment in environments)
{
foreach (LocationReference reference in environment.GetLocationReferences())
{
if (this.textExpression.RequiresCompilation)
{
this.accessor.CreateLocationArgument(reference, false);
}
this.locationReferences.Add(new InlinedLocationReference(reference, this.metadata.CurrentActivity));
}
}
// Scenarios like VBV/R needs to know if they should run their own compiler
// during CacheMetadata. If we find a compiled expression root, means we're
// already compiled. So set the IsStaticallyCompiled flag to true
bool foundCompiledExpressionRoot = this.TryGetCompiledExpressionRootAtDesignTime(this.expressionActivity,
this.metadataRoot,
out this.compiledRoot,
out this.expressionId);
if (foundCompiledExpressionRoot)
{
this.IsStaticallyCompiled = true;
// For compiled C# expressions we create temp auto generated arguments
// for all locations whether they are used in the expressions or not.
// The TryGetReferenceToPublicLocation method call above also generates
// temp arguments for all locations.
// However for VB expressions, this leads to inconsistency between build
// time and run time as during build time VB only generates temp arguments
// for locations that are referenced in the expressions. To maintain
// consistency the we call the CreateRequiredArguments method seperately to
// generates auto arguments only for locations that are referenced.
if (!this.textExpression.RequiresCompilation)
{
IList<string> requiredLocationNames = this.compiledRoot.GetRequiredLocations(this.expressionId);
this.CreateRequiredArguments(requiredLocationNames);
}
}
}
bool TryGetCompiledExpressionRootAtDesignTime(Activity expression, Activity target, out ICompiledExpressionRoot compiledExpressionRoot, out int exprId)
{
exprId = -1;
compiledExpressionRoot = null;
if (!CompiledExpressionInvoker.TryGetCompiledExpressionRoot(expression, target, out compiledExpressionRoot) ||
!CanExecuteExpression(compiledExpressionRoot, out exprId))
{
return FindCompiledExpressionRoot(out exprId, out compiledExpressionRoot);
}
return true;
}
bool FindCompiledExpressionRoot(out int exprId, out ICompiledExpressionRoot compiledExpressionRoot)
{
Activity root = this.metadata.CurrentActivity.Parent;
while (root != null)
{
ICompiledExpressionRoot currentCompiledExpressionRoot = null;
if (CompiledExpressionInvoker.TryGetCompiledExpressionRoot(metadata.CurrentActivity, root, out currentCompiledExpressionRoot))
{
if (CanExecuteExpression(currentCompiledExpressionRoot, out exprId))
{
compiledExpressionRoot = currentCompiledExpressionRoot;
return true;
}
}
root = root.Parent;
}
exprId = -1;
compiledExpressionRoot = null;
return false;
}
void CreateRequiredArguments(IList<string> requiredLocationNames)
{
LocationReference reference;
if (requiredLocationNames != null && requiredLocationNames.Count > 0)
{
foreach (string name in requiredLocationNames)
{
reference = FindLocationReference(name);
if (reference != null)
{
if (this.isReference)
{
this.accessor.CreateLocationArgument(reference, true);
}
else
{
this.accessor.CreateArgument(reference, ArgumentDirection.In, true);
}
}
}
}
}
LocationReference FindLocationReference(string name)
{
LocationReference returnValue = null;
LocationReferenceEnvironment current = this.accessor.ActivityMetadata.Environment;
while (current != null)
{
if (current.TryGetLocationReference(name, out returnValue))
{
return returnValue;
}
current = current.Parent;
}
return returnValue;
}
}
}

View File

@@ -0,0 +1,61 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Linq.Expressions;
using System.Runtime;
using System.Windows.Markup;
[ContentProperty("DelegateArgument")]
public sealed class DelegateArgumentReference<T> : EnvironmentLocationReference<T>
{
public DelegateArgumentReference()
: base()
{
}
public DelegateArgumentReference(DelegateArgument delegateArgument)
: this()
{
this.DelegateArgument = delegateArgument;
}
public DelegateArgument DelegateArgument
{
get;
set;
}
public override LocationReference LocationReference
{
get { return this.DelegateArgument; }
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
if (this.DelegateArgument == null)
{
metadata.AddValidationError(SR.DelegateArgumentMustBeSet);
}
else
{
if (!this.DelegateArgument.IsInTree)
{
metadata.AddValidationError(SR.DelegateArgumentMustBeReferenced(this.DelegateArgument.Name));
}
if (!metadata.Environment.IsVisible(this.DelegateArgument))
{
metadata.AddValidationError(SR.DelegateArgumentNotVisible(this.DelegateArgument.Name));
}
if (!(this.DelegateArgument is DelegateOutArgument<T>) && !(this.DelegateArgument is DelegateInArgument<T>))
{
metadata.AddValidationError(SR.DelegateArgumentTypeInvalid(this.DelegateArgument, typeof(T), this.DelegateArgument.Type));
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Linq.Expressions;
using System.Runtime;
using System.Windows.Markup;
[ContentProperty("DelegateArgument")]
public sealed class DelegateArgumentValue<T> : EnvironmentLocationValue<T>
{
public DelegateArgumentValue()
: base()
{
}
public DelegateArgumentValue(DelegateArgument delegateArgument)
: this()
{
this.DelegateArgument = delegateArgument;
}
public DelegateArgument DelegateArgument
{
get;
set;
}
public override LocationReference LocationReference
{
get { return this.DelegateArgument; }
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
if (this.DelegateArgument == null)
{
metadata.AddValidationError(SR.DelegateArgumentMustBeSet);
}
else
{
if (!this.DelegateArgument.IsInTree)
{
metadata.AddValidationError(SR.DelegateArgumentMustBeReferenced(this.DelegateArgument.Name));
}
if (!metadata.Environment.IsVisible(this.DelegateArgument))
{
metadata.AddValidationError(SR.DelegateArgumentNotVisible(this.DelegateArgument.Name));
}
if (!(this.DelegateArgument is DelegateInArgument<T>) && !TypeHelper.AreTypesCompatible(this.DelegateArgument.Type, typeof(T)))
{
metadata.AddValidationError(SR.DelegateArgumentTypeInvalid(this.DelegateArgument, typeof(T), this.DelegateArgument.Type));
}
}
}
}
}

View File

@@ -0,0 +1,59 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.Statements;
using System.Linq.Expressions;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime;
public sealed class Divide<TLeft, TRight, TResult> : CodeActivity<TResult>
{
//Lock is not needed for operationFunction here. The reason is that delegates for a given Divide<TLeft, TRight, TResult> are the same.
//It's possible that 2 threads are assigning the operationFucntion at the same time. But it's okay because the compiled codes are the same.
static Func<TLeft, TRight, TResult> operationFunction;
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TLeft> Left
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TRight> Right
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
BinaryExpressionHelper.OnGetArguments(metadata, this.Left, this.Right);
if (operationFunction == null)
{
ValidationError validationError;
if (!BinaryExpressionHelper.TryGenerateLinqDelegate(ExpressionType.Divide, out operationFunction, out validationError))
{
metadata.AddValidationError(validationError);
}
}
}
protected override TResult Execute(CodeActivityContext context)
{
Fx.Assert(operationFunction != null, "OperationFunction must exist.");
TLeft leftValue = this.Left.Get(context);
TRight rightValue = this.Right.Get(context);
return operationFunction(leftValue, rightValue);
}
}
}

View File

@@ -0,0 +1,59 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Linq.Expressions;
using System.Runtime;
[Fx.Tag.XamlVisible(false)]
public class EnvironmentLocationReference<T> : CodeActivity<Location<T>>, IExpressionContainer, ILocationReferenceExpression
{
LocationReference locationReference;
// Ctors are internal because we rely on validation from creator or descendant
internal EnvironmentLocationReference()
{
this.UseOldFastPath = true;
}
internal EnvironmentLocationReference(LocationReference locationReference)
: this()
{
this.locationReference = locationReference;
}
public virtual LocationReference LocationReference
{
get
{
return this.locationReference;
}
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
// the creator of this activity is expected to have checked visibility of LocationReference.
// we override the base CacheMetadata to avoid unnecessary reflection overhead.
}
protected sealed override Location<T> Execute(CodeActivityContext context)
{
try
{
context.AllowChainedEnvironmentAccess = true;
return context.GetLocation<T>(this.LocationReference);
}
finally
{
context.AllowChainedEnvironmentAccess = false;
}
}
ActivityWithResult ILocationReferenceExpression.CreateNewInstance(LocationReference locationReference)
{
return new EnvironmentLocationReference<T>(locationReference);
}
}
}

View File

@@ -0,0 +1,59 @@
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Linq.Expressions;
using System.Runtime;
[Fx.Tag.XamlVisible(false)]
public class EnvironmentLocationValue<T> : CodeActivity<T>, IExpressionContainer, ILocationReferenceExpression
{
LocationReference locationReference;
// Ctors are internal because we rely on validation from creator or descendant
internal EnvironmentLocationValue()
{
this.UseOldFastPath = true;
}
internal EnvironmentLocationValue(LocationReference locationReference)
: this()
{
this.locationReference = locationReference;
}
public virtual LocationReference LocationReference
{
get
{
return this.locationReference;
}
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
// the creator of this activity is expected to have checked visibility of LocationReference.
// we override the base CacheMetadata to avoid unnecessary reflection overhead.
}
protected override T Execute(CodeActivityContext context)
{
try
{
context.AllowChainedEnvironmentAccess = true;
return context.GetValue<T>(this.LocationReference);
}
finally
{
context.AllowChainedEnvironmentAccess = false;
}
}
ActivityWithResult ILocationReferenceExpression.CreateNewInstance(LocationReference locationReference)
{
return new EnvironmentLocationValue<T>(locationReference);
}
}
}

View File

@@ -0,0 +1,59 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.Activities.Expressions
{
using System.Activities;
using System.Activities.Statements;
using System.Linq.Expressions;
using System.Activities.Validation;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime;
public sealed class Equal<TLeft, TRight, TResult> : CodeActivity<TResult>
{
//Lock is not needed for operationFunction here. The reason is that delegates for a given Equal<TLeft, TRight, TResult> are the same.
//It's possible that 2 threads are assigning the operationFucntion at the same time. But it's okay because the compiled codes are the same.
static Func<TLeft, TRight, TResult> operationFunction;
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TLeft> Left
{
get;
set;
}
[RequiredArgument]
[DefaultValue(null)]
public InArgument<TRight> Right
{
get;
set;
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
BinaryExpressionHelper.OnGetArguments(metadata, this.Left, this.Right);
if (operationFunction == null)
{
ValidationError validationError;
if (!BinaryExpressionHelper.TryGenerateLinqDelegate(ExpressionType.Equal, out operationFunction, out validationError))
{
metadata.AddValidationError(validationError);
}
}
}
protected override TResult Execute(CodeActivityContext context)
{
Fx.Assert(operationFunction != null, "OperationFunction must exist.");
TLeft leftValue = this.Left.Get(context);
TRight rightValue = this.Right.Get(context);
return operationFunction(leftValue, rightValue);
}
}
}

Some files were not shown because too many files have changed in this diff Show More