public void VisitNode(JSPropertyAccess pa) { var targetType = pa.Target.GetActualType(TypeSystem); if (IsNullable(targetType)) { var @null = JSLiteral.Null(targetType); switch (pa.Property.Property.Member.Name) { case "HasValue": var replacement = new JSBinaryOperatorExpression( JSOperator.NotEqual, pa.Target, @null, TypeSystem.Boolean ); ParentNode.ReplaceChild(pa, replacement); VisitReplacement(replacement); break; case "Value": ParentNode.ReplaceChild(pa, pa.Target); VisitReplacement(pa.Target); break; default: throw new NotImplementedException(pa.Property.Property.Member.FullName); } return; } VisitChildren(pa); }
public void VisitNode(JSPropertyAccess pa) { var targetType = pa.Target.GetActualType(TypeSystem); if (IsNullable(targetType)) { var @null = JSLiteral.Null(targetType); switch (pa.Property.Property.Member.Name) { case "HasValue": { var replacement = JSIL.NullableHasValue(pa.Target); ParentNode.ReplaceChild(pa, replacement); VisitReplacement(replacement); break; } case "Value": { var replacement = JSIL.ValueOfNullable(pa.Target); ParentNode.ReplaceChild(pa, replacement); VisitReplacement(replacement); break; } default: throw new NotImplementedException(pa.Property.Property.Member.FullName); } return; } VisitChildren(pa); }
public bool IsPropertyAccess( JSBinaryOperatorExpression boe, out JSPropertyAccess pa ) { pa = boe.Left as JSPropertyAccess; return(pa != null); }
public bool IsPropertyAccess( JSBinaryOperatorExpression boe, out JSPropertyAccess pa ) { pa = boe.Left as JSPropertyAccess; return pa != null; }
public void VisitNode(JSPropertyAccess pa) { if (IsPropertyGetterInvocation(pa)) { // getter var replacement = ConstructInvocation(pa); ParentNode.ReplaceChild(pa, replacement); VisitReplacement(replacement); } else { VisitChildren(pa); } }
public void VisitNode(JSPropertyAccess pa) { if (pa.ThisReference.Equals(ThisReference) && pa.Property.Equals(Property)) { ParentNode.ReplaceChild(pa, Replacement); VisitReplacement(Replacement); } else { VisitChildren(pa); } }
public static bool IsPropertySetterInvocation(JSNode parentNode, JSBinaryOperatorExpression boe, out JSPropertyAccess pa) { var isValidParent = (parentNode is JSExpressionStatement); pa = boe.Left as JSPropertyAccess; return (pa != null) && pa.IsWrite && (boe.Operator == JSOperator.Assignment) && isValidParent && CanConvertToInvocation(pa); }
public static bool CanConvertToInvocation (JSPropertyAccess pa) { var prop = pa.Property.Property; if (prop.IsAutoProperty && !prop.IsVirtual && !prop.DeclaringType.IsInterface ) { return false; } else { return !prop.Metadata.HasAttribute("JSIL.Meta.JSAlwaysAccessAsProperty"); } }
public bool IsPropertySetterInvocation(JSBinaryOperatorExpression boe, out JSPropertyAccess pa) { var isValidParent = (ParentNode is JSExpressionStatement) || (ParentNode is JSCommaExpression); pa = boe.Left as JSPropertyAccess; return((pa != null) && pa.IsWrite && (boe.Operator == JSOperator.Assignment) && isValidParent && CanConvertToInvocation(pa)); }
public void VisitNode(JSPropertyAccess pa) { if (pa.IsWrite) { throw new Exception("Unhandled property write: " + pa); } var method = pa.OriginalMethod; var memberName = WasmUtil.FormatMemberName(method.Reference.Resolve()); Formatter.WriteSExpr("call", (_) => { _.WriteRaw("${0}", memberName); }); }
public static bool CanConvertToInvocation(JSPropertyAccess pa) { var prop = pa.Property.Property; if (prop.IsAutoProperty && !prop.IsVirtual && !prop.DeclaringType.IsInterface ) { return(false); } else { return (!prop.Metadata.HasAttribute("JSIL.Meta.JSAlwaysAccessAsProperty")); } }
public bool IsPropertyGetterInvocation(JSPropertyAccess pa) { if (Stack.OfType<JSBinaryOperatorExpression>().Any( (boe) => (boe.Operator is JSAssignmentOperator) && (boe.Left.SelfAndChildrenRecursive.Contains(pa)) )) return false; else if (Stack.OfType<JSUnaryOperatorExpression>().Any( (uoe) => uoe.Operator is JSUnaryMutationOperator )) return false; return !pa.IsWrite && CanConvertToInvocation(pa); }
public static bool IsPropertyGetterInvocation(JSNode parentNode, JSPropertyAccess pa) { var parentBoe = parentNode as JSBinaryOperatorExpression; var parentUoe = parentNode as JSUnaryOperatorExpression; bool isMutation = ( (parentUoe != null) && (parentUoe.Operator is JSUnaryMutationOperator) ) || ( (parentBoe != null) && (parentBoe.Operator is JSAssignmentOperator) && (pa == parentBoe.Left) ); return !pa.IsWrite && !isMutation && CanConvertToInvocation(pa); }
public bool IsPropertyGetterInvocation(JSPropertyAccess pa) { if (Stack.OfType <JSBinaryOperatorExpression>().Any( (boe) => (boe.Operator is JSAssignmentOperator) && (boe.Left.SelfAndChildrenRecursive.Contains(pa)) )) { return(false); } else if (Stack.OfType <JSUnaryOperatorExpression>().Any( (uoe) => uoe.Operator is JSUnaryMutationOperator )) { return(false); } return(!pa.IsWrite && CanConvertToInvocation(pa)); }
public void VisitNode(JSPropertyAccess prop) { var parentBoe = ParentNode as JSBinaryOperatorExpression; var v = ExtractAffectedVariable(prop.Target); var p = prop.Property.Property; if (prop.HasGlobalStateDependency) { State.StaticReferences.Add(new FunctionAnalysis1stPass.StaticReference( GetParentNodeIndices(), StatementIndex, NodeIndex, p.DeclaringType )); } if ( (parentBoe != null) && (parentBoe.Operator is JSAssignmentOperator) && (parentBoe.Left == prop) ) { // Setter if (v != null) { State.SideEffects.Add(new FunctionAnalysis1stPass.SideEffect( GetParentNodeIndices(), StatementIndex, NodeIndex, v, "property set" )); } /* * State.Invocations.Add(new FunctionAnalysis1stPass.Invocation( * StatementIndex, NodeIndex, */ } else { // Getter } VisitChildren(prop); }
private JSExpression ConstructInvocation ( JSPropertyAccess pa, JSExpression argument = null ) { JSExpression[] arguments; if (argument == null) arguments = new JSExpression[0]; else arguments = new JSExpression[] { argument }; var originalMethod = pa.OriginalMethod; var declaringType = originalMethod.Reference.DeclaringType; var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType); var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem); var isSelf = TypeUtil.TypesAreAssignable( TypeInfo, thisReferenceType, declaringType ); // ILSpy converts compound assignments from: // x.set_Value(x.get_Value + n) // to // x.get_Value += n; // so we have to detect this and reconstruct the correct method // references. var actualMethod = originalMethod; var correctName = String.Format( "{0}_{1}", pa.IsWrite ? "set" : "get", pa.Property.Property.ShortName ); if (!actualMethod.Reference.Name.Contains(correctName)) { var dt = originalMethod.Method.DeclaringType; var actualMethodInfo = dt.Members.Values .OfType<MethodInfo>().FirstOrDefault( (m) => ( m.Name.Contains(correctName) && m.DeclaringType == originalMethod.Method.DeclaringType ) ); MethodReference actualMethodReference = actualMethodInfo.Member; if (originalMethod.Reference is GenericInstanceMethod) { throw new InvalidDataException("Reconstructing an invocation of a generic instance method? Shouldn't be possible."); } else if (declaringType is GenericInstanceType) { var declaringGit = (GenericInstanceType)declaringType; var returnType = actualMethodReference.ReturnType; if (TypeUtil.IsOpenType(returnType)) { var actualReturnType = JSExpression.SubstituteTypeArgs(TypeInfo, actualMethodReference.ReturnType, actualMethodReference); returnType = actualReturnType; } actualMethodReference = new MethodReference( actualMethodReference.Name, returnType, declaringGit ); } actualMethod = new JSMethod( actualMethodReference, actualMethodInfo, originalMethod.MethodTypes, originalMethod.GenericArguments ); } bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis( declaringType, declaringTypeDef, originalMethod.Method.DeclaringType, isSelf, thisReferenceType, originalMethod.Method ); JSInvocationExpressionBase invocation; if (pa.Property.Property.IsStatic) invocation = JSInvocationExpression.InvokeStatic( actualMethod.Reference.DeclaringType, actualMethod, arguments ); else if (needsExplicitThis) invocation = JSInvocationExpression.InvokeBaseMethod( actualMethod.Reference.DeclaringType, actualMethod, pa.ThisReference, arguments ); else invocation = JSInvocationExpression.InvokeMethod( pa.OriginalType, actualMethod, pa.ThisReference, arguments ); JSExpression replacement; if (TypeUtil.IsStruct(pa.Property.Property.ReturnType)) replacement = new JSResultReferenceExpression(invocation); else replacement = invocation; return replacement; }
private JSExpression ConstructInvocation( JSPropertyAccess pa, JSExpression argument = null ) { JSExpression[] arguments; if (argument == null) { arguments = new JSExpression[0]; } else { arguments = new JSExpression[] { argument } }; var originalMethod = pa.OriginalMethod; var declaringType = originalMethod.Reference.DeclaringType; var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType); var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem); var isSelf = TypeUtil.TypesAreAssignable( TypeInfo, thisReferenceType, declaringType ); // ILSpy converts compound assignments from: // x.set_Value(x.get_Value + n) // to // x.get_Value += n; // so we have to detect this and reconstruct the correct method // references. var actualMethod = originalMethod; var correctName = String.Format( "{0}_{1}", pa.IsWrite ? "set" : "get", pa.Property.Property.ShortName ); if (!actualMethod.Reference.Name.Contains(correctName)) { var dt = originalMethod.Method.DeclaringType; var actualMethodInfo = dt.Members.Values .OfType <MethodInfo>().FirstOrDefault( (m) => ( m.Name.Contains(correctName) && m.DeclaringType == originalMethod.Method.DeclaringType ) ); MethodReference actualMethodReference = actualMethodInfo.Member; if (originalMethod.Reference is GenericInstanceMethod) { throw new InvalidDataException("Reconstructing an invocation of a generic instance method? Shouldn't be possible."); } else if (declaringType is GenericInstanceType) { var declaringGit = (GenericInstanceType)declaringType; var returnType = actualMethodReference.ReturnType; if (TypeUtil.IsOpenType(returnType)) { var actualReturnType = JSExpression.SubstituteTypeArgs(TypeInfo, actualMethodReference.ReturnType, actualMethodReference); returnType = actualReturnType; } actualMethodReference = new MethodReference( actualMethodReference.Name, returnType, declaringGit ); } actualMethod = new JSMethod( actualMethodReference, actualMethodInfo, originalMethod.MethodTypes, originalMethod.GenericArguments ); } bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis( declaringType, declaringTypeDef, originalMethod.Method.DeclaringType, isSelf, thisReferenceType, originalMethod.Method ); JSInvocationExpressionBase invocation; if (pa.Property.Property.IsStatic) { invocation = JSInvocationExpression.InvokeStatic( actualMethod.Reference.DeclaringType, actualMethod, arguments ); } else if (needsExplicitThis) { invocation = JSInvocationExpression.InvokeBaseMethod( actualMethod.Reference.DeclaringType, actualMethod, pa.ThisReference, arguments ); } else { invocation = JSInvocationExpression.InvokeMethod( pa.OriginalType, actualMethod, pa.ThisReference, arguments ); } JSExpression replacement; if (TypeUtil.IsStruct(pa.Property.Property.ReturnType)) { replacement = new JSResultReferenceExpression(invocation); } else { replacement = invocation; } return(replacement); }
private JSExpression ConstructInvocation( JSPropertyAccess pa, JSExpression argument = null ) { JSExpression[] arguments; if (argument == null) arguments = new JSExpression[0]; else arguments = new JSExpression[] { argument }; var originalMethod = pa.OriginalMethod; var declaringType = originalMethod.Reference.DeclaringType; var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType); var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem); var isSelf = TypeUtil.TypesAreAssignable( TypeInfo, thisReferenceType, declaringType ); bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis( declaringType, declaringTypeDef, originalMethod.Method.DeclaringType, isSelf, thisReferenceType, originalMethod.Method ); JSInvocationExpressionBase invocation; if (pa.Property.Property.IsStatic) invocation = JSInvocationExpression.InvokeStatic( pa.OriginalMethod.Reference.DeclaringType, pa.OriginalMethod, arguments ); else if (needsExplicitThis) invocation = JSInvocationExpression.InvokeBaseMethod( pa.OriginalMethod.Reference.DeclaringType, pa.OriginalMethod, pa.ThisReference, arguments ); else invocation = JSInvocationExpression.InvokeMethod( pa.OriginalMethod, pa.ThisReference, arguments ); JSExpression replacement; if (TypeUtil.IsStruct(pa.Property.Property.ReturnType)) replacement = new JSResultReferenceExpression(invocation); else replacement = invocation; return replacement; }
public void VisitNode(JSPropertyAccess pa) { var targetType = pa.Target.GetExpectedType(TypeSystem); if (targetType.FullName.StartsWith("System.Nullable")) { var @null = JSLiteral.Null(targetType); switch (pa.Property.Property.Member.Name) { case "HasValue": var replacement = new JSBinaryOperatorExpression( JSOperator.NotEqual, pa.Target, @null, TypeSystem.Boolean ); ParentNode.ReplaceChild(pa, replacement); VisitReplacement(replacement); break; case "Value": ParentNode.ReplaceChild(pa, pa.Target); VisitReplacement(pa.Target); break; default: throw new NotImplementedException(pa.Property.Property.Member.FullName); } return; } VisitChildren(pa); }
public void VisitNode(JSPropertyAccess pa) { VisitDotExpression(pa); }