public PropertyReferenceReflectionEmitter(MemberReferenceExpression memberReferenceExpression, Type target, MemberInfo member, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer, IAstVisitor<ILGenerator, AstNode> visitor, List<LocalBuilder> locals, bool isSetter = false) : base(memberReferenceExpression, target, member, ilGenerator, instructionsIndexer, visitor, locals) { var propertyInfo = Member as PropertyInfo; _isSetter = isSetter; _propertyDefinition = MemberReference.Annotation<Cecil.PropertyDefinition>(); NonPublic = !_propertyDefinition.GetMethod.IsPublic; Type = _propertyDefinition.PropertyType.GetActualType(); if (isSetter) { _propertyMethod = propertyInfo.GetSetMethod(NonPublic); _emitPrivateAction = EmitPrivateStorePropertyReference; } else { _propertyMethod = propertyInfo.GetGetMethod(NonPublic); _emitPrivateAction = EmitPrivateLoadPropertyReference; } }
internal FieldReferenceReflectionEmitter(MemberReferenceExpression memberReferenceExpression, Type target, MemberInfo member, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer, IAstVisitor<ILGenerator, AstNode> visitor, List<LocalBuilder> locals, bool isSetter = false) : base(memberReferenceExpression, target, member, ilGenerator, instructionsIndexer, visitor, locals) { FieldReference = MemberReference.Annotation<FieldReference>(); IsByRef = MemberReference.Parent is DirectionExpression; Type = FieldReference.FieldType.GetActualType(); FieldInfo = FieldReference.GetActualField(); NonPublic = !((FieldInfo.Attributes & (_publicFieldAttributes)) == _publicFieldAttributes); if (isSetter) { _emitAction = EmitStoreFieldReference; _emitPrivateAction = EmitPrivateStoreFieldReference; } else { _emitAction = EmitLoadFieldReference; _emitPrivateAction = EmitPrivateLoadFieldReference; } }
internal EventReferenceReflectionEmitter(MemberReferenceExpression memberReferenceExpression, Type target, MemberInfo member, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer, IAstVisitor<ILGenerator, AstNode> visitor, List<LocalBuilder> locals) : base(memberReferenceExpression, target, member, ilGenerator, instructionsIndexer, visitor, locals) { }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { base.VisitMemberReferenceExpression(memberReferenceExpression); HandleMemberReference( memberReferenceExpression, memberReferenceExpression.Target, memberReferenceExpression.MemberNameToken, memberReferenceExpression.TypeArguments, NameLookupMode.Expression, script => { script.Replace(memberReferenceExpression, RefactoringAstHelper.RemoveTarget(memberReferenceExpression)); }); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { if (!IsTargetOfInvocation(memberReferenceExpression)) { var mgr = ctx.Resolve (memberReferenceExpression) as MethodGroupResolveResult; if (mgr != null) UsedMethods.AddRange (mgr.Methods); } base.VisitMemberReferenceExpression(memberReferenceExpression); }
AstNode ToStaticMethodInvocation(InvocationExpression invocation, MemberReferenceExpression memberReference, CSharpInvocationResolveResult invocationRR) { var newArgumentList = invocation.Arguments.Select(arg => arg.Clone()).ToList(); newArgumentList.Insert(0, memberReference.Target.Clone()); var newTarget = memberReference.Clone() as MemberReferenceExpression; newTarget.Target = new IdentifierExpression(invocationRR.Member.DeclaringType.Name); return new InvocationExpression(newTarget, newArgumentList); }
internal MultipuleAssignmentEmitter(MemberReferenceExpression memberReferenceExpression, Expression assignor, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer, IAstVisitor<ILGenerator, AstNode> visitor, List<LocalBuilder> locals) : base(memberReferenceExpression, ilGenerator, instructionsIndexer, visitor, locals) { _assignorExpression = assignor; }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { var identifierExpression = memberReferenceExpression.Target as IdentifierExpression; if (identifierExpression != null && identifierExpression.Identifier == _fromIdentifier) { memberReferenceExpression.Target = new IdentifierExpression("doc"); } base.VisitMemberReferenceExpression(memberReferenceExpression); }
internal AbstractMemberReferenceEmitter(MemberReferenceExpression memberReferenceExpression, Type target, MemberInfo member, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer, IAstVisitor<ILGenerator, AstNode> visitor, List<LocalBuilder> locals) : base(ilGenerator, instructionsIndexer, visitor, locals) { Target = target; Member = member; MemberReference = memberReferenceExpression; }
public void LookupAmbiguousMemberInOtherAssembly() { _compilationUnit.UsingDirectives.Add(new UsingNamespaceDirective("System")); var reference = new MemberReferenceExpression(new IdentifierExpression("Console"), "WriteLine"); var result = reference.Resolve(_compilationUnit.GetScope()); Assert.IsInstanceOfType(result, typeof(AmbiguousMemberResolveResult)); var memberResult = (AmbiguousMemberResolveResult)result; Assert.AreEqual("System.Console", memberResult.Member.DeclaringType.FullName); Assert.AreEqual("WriteLine", memberResult.Member.Name); Assert.IsTrue(memberResult.Candidates.Count > 1); }
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data) { if (objectCreateExpression.Arguments.Count() == 2) { Expression obj = objectCreateExpression.Arguments.First(); Expression func = objectCreateExpression.Arguments.Last(); Annotation annotation = func.Annotation<Annotation>(); if (annotation != null) { IdentifierExpression methodIdent = (IdentifierExpression)((InvocationExpression)func).Arguments.Single(); MethodReference method = methodIdent.Annotation<MethodReference>(); if (method != null) { if (HandleAnonymousMethod(objectCreateExpression, obj, method)) return null; // Perform the transformation to "new Action(obj.func)". obj.Remove(); methodIdent.Remove(); if (!annotation.IsVirtual && obj is ThisReferenceExpression) { // maybe it's getting the pointer of a base method? if (method.DeclaringType != context.CurrentType) { obj = new BaseReferenceExpression(); } } if (!annotation.IsVirtual && obj is NullReferenceExpression && !method.HasThis) { // We're loading a static method. // However it is possible to load extension methods with an instance, so we compare the number of arguments: bool isExtensionMethod = false; TypeReference delegateType = objectCreateExpression.Type.Annotation<TypeReference>(); if (delegateType != null) { TypeDefinition delegateTypeDef = delegateType.Resolve(); if (delegateTypeDef != null) { MethodDefinition invokeMethod = delegateTypeDef.Methods.FirstOrDefault(m => m.Name == "Invoke"); if (invokeMethod != null) { isExtensionMethod = (invokeMethod.Parameters.Count + 1 == method.Parameters.Count); } } } if (!isExtensionMethod) { obj = new TypeReferenceExpression { Type = AstBuilder.ConvertType(method.DeclaringType) }; } } // now transform the identifier into a member reference MemberReferenceExpression mre = new MemberReferenceExpression(); mre.Target = obj; mre.MemberName = methodIdent.Identifier; methodIdent.TypeArguments.MoveTo(mre.TypeArguments); mre.AddAnnotation(method); objectCreateExpression.Arguments.Clear(); objectCreateExpression.Arguments.Add(mre); return null; } } } return base.VisitObjectCreateExpression(objectCreateExpression, data); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { base.VisitMemberReferenceExpression(memberReferenceExpression); if (memberReferenceExpression == null || memberReferenceExpression.Target is ThisReferenceExpression) // Call within current class scope using 'this' or 'base' return; var memberResolveResult = context.Resolve(memberReferenceExpression) as MemberResolveResult; if (memberResolveResult == null) return; if (!memberResolveResult.Member.IsStatic) return; HandleMember(memberReferenceExpression, memberReferenceExpression.Target, memberResolveResult.Member, memberResolveResult.TargetResult); }
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) { const string typeToUse = "System.Threading.Thread"; const string methodToFind = "Abort"; if (_codebaseDeclarations.Any(a => a.Name == memberReferenceExpression.Target.GetIdentifier() && a.IsType(typeToUse)) || memberReferenceExpression.IsReferenceOfTypeFromScope(typeToUse)) { if (memberReferenceExpression.MemberName == methodToFind) { UnlockWith(memberReferenceExpression); } } return base.VisitMemberReferenceExpression(memberReferenceExpression, data); }
// fixes bug https://github.com/ashmind/TryRoslyn/issues/7 // todo: report this to the decompiler guys -- but does not seem like they are reading their queue public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { StartNode(memberReferenceExpression); var useParentheses = RequiresParenthesesWhenTargetOfMemberReference(memberReferenceExpression.Target); if (useParentheses) LPar(); memberReferenceExpression.Target.AcceptVisitor(this); if (useParentheses) RPar(); WriteToken(Roles.Dot); WriteIdentifier(memberReferenceExpression.MemberName); WriteTypeArguments(memberReferenceExpression.TypeArguments); EndNode(memberReferenceExpression); }
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) { if(memberReferenceExpression.MemberName == "Length") { var variableName = memberReferenceExpression.Target.GetIdentifier(); if(memberReferenceExpression.GetVariablesOfInitializer<ArrayCreateExpression>().Any(a => a.Name == variableName)) { UnlockWith(memberReferenceExpression); } else if(_codebaseDeclarations.Any(a => a.Name == variableName && a.Initializer is ArrayCreateExpression)) { UnlockWith(memberReferenceExpression); } } return base.VisitMemberReferenceExpression(memberReferenceExpression, data); }
IEnumerable<CodeAction> GetActionsFromMemberReferenceExpression(RefactoringContext context, MemberReferenceExpression invocation) { if (!(context.Resolve(invocation).IsError)) yield break; var methodName = invocation.MemberName; var guessedType = TypeGuessing.GuessType(context, invocation); if (guessedType.Kind != TypeKind.Delegate) yield break; var invocationMethod = guessedType.GetDelegateInvokeMethod(); var state = context.GetResolverStateBefore(invocation); if (state.CurrentTypeDefinition == null) yield break; ResolveResult targetResolveResult = context.Resolve(invocation.Target); bool createInOtherType = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition()); bool isStatic; if (createInOtherType) { if (targetResolveResult.Type.GetDefinition() == null || targetResolveResult.Type.GetDefinition().Region.IsEmpty) yield break; isStatic = targetResolveResult is TypeResolveResult; if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface || targetResolveResult.Type.Kind == TypeKind.Enum) yield break; } else { if (state.CurrentMember == null) yield break; isStatic = state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic; } // var service = (NamingConventionService)context.GetService(typeof(NamingConventionService)); // if (service != null && !service.IsValidName(methodName, AffectedEntity.Method, Modifiers.Private, isStatic)) { // yield break; // } yield return CreateAction( context, invocation, methodName, context.CreateShortType(invocationMethod.ReturnType), invocationMethod.Parameters.Select(parameter => new ParameterDeclaration(context.CreateShortType(parameter.Type), parameter.Name) { ParameterModifier = GetModifiers(parameter) }), createInOtherType, isStatic, targetResolveResult); }
public IEnumerable<CodeAction> GetActions(RefactoringContext context) { // TODO: Invert if without else // ex. if (cond) DoSomething () == if (!cond) return; DoSomething () // beware of loop contexts return should be continue then. var methodDeclaration = GetMethodDeclaration(context); if (methodDeclaration == null) yield break; var resolved = context.Resolve(methodDeclaration) as MemberResolveResult; if (resolved == null) yield break; var isImplementingInterface = resolved.Member.ImplementedInterfaceMembers.Any(); if (isImplementingInterface) yield break; yield return new CodeAction(context.TranslateString(string.Format("Make '{0}' static", methodDeclaration.Name)), script => { var clonedDeclaration = (MethodDeclaration)methodDeclaration.Clone(); clonedDeclaration.Modifiers |= Modifiers.Static; script.Replace(methodDeclaration, clonedDeclaration); var rr = context.Resolve (methodDeclaration) as MemberResolveResult; var method = (IMethod)rr.Member; //method.ImplementedInterfaceMembers.Any(m => methodGroupResolveResult.Methods.Contains((IMethod)m)); script.DoGlobalOperationOn(rr.Member, (fctx, fscript, fnode) => { if (fnode is MemberReferenceExpression) { var memberReference = new MemberReferenceExpression ( new TypeReferenceExpression (fctx.CreateShortType (rr.Member.DeclaringType)), rr.Member.Name ); fscript.Replace (fnode, memberReference); } else if (fnode is InvocationExpression) { var invoke = (InvocationExpression)fnode; if (!(invoke.Target is MemberReferenceExpression)) return; var memberReference = new MemberReferenceExpression ( new TypeReferenceExpression (fctx.CreateShortType (rr.Member.DeclaringType)), rr.Member.Name ); fscript.Replace (invoke.Target, memberReference); } }); }, methodDeclaration); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { base.VisitMemberReferenceExpression(memberReferenceExpression); var targetResolveResult = context.Resolve(memberReferenceExpression.Target) as LocalResolveResult; if (targetResolveResult == null) return; var variable = targetResolveResult.Variable; var conversion = context.GetConversion(memberReferenceExpression); if (conversion.IsMethodGroupConversion) { AddCriterion(variable, new HasMemberCriterion(conversion.Method)); } else { var resolveResult = context.Resolve(memberReferenceExpression); var memberResolveResult = resolveResult as MemberResolveResult; if (memberResolveResult != null) AddCriterion(variable, new HasMemberCriterion(memberResolveResult.Member)); } }
public IEnumerable<CodeAction> GetActions(RefactoringContext context) { //TODO: implement variable assignment & ctor param var varInit = context.GetNode<VariableInitializer>(); if (varInit != null) { AstType type = varInit.GetPrevNode() as AstType; if (type == null) yield break; if (varInit.Parent is FieldDeclaration) yield break; if (CannotExtractField(varInit)) yield break; yield return new CodeAction("Extract field", s=>{ var name = varInit.Name; FieldDeclaration field = new FieldDeclaration(){ ReturnType = type.Clone(), Variables = { new VariableInitializer(name) } }; AstNode nodeToRemove = RemoveDeclaration(varInit) ? varInit.Parent : type; s.Remove(nodeToRemove, true); s.InsertWithCursor(context.TranslateString("Extract field"),Script.InsertPosition.Before,field); s.FormatText(varInit.Parent); }); } var idntf = context.GetNode<Identifier>(); if (idntf == null) yield break; var paramDec = idntf.Parent as ParameterDeclaration; if (paramDec != null) { var ctor = paramDec.Parent as ConstructorDeclaration; if (ctor == null) yield break; MemberReferenceExpression thisField = new MemberReferenceExpression(new ThisReferenceExpression(), idntf.Name, new AstType[]{}); var assign = new AssignmentExpression(thisField, AssignmentOperatorType.Assign, new IdentifierExpression(idntf.Name)); var statement = new ExpressionStatement(assign); var type = (idntf.GetPrevNode() as AstType).Clone(); FieldDeclaration field = new FieldDeclaration(){ ReturnType = type.Clone(), Variables = { new VariableInitializer(idntf.Name) } }; yield return new CodeAction("Extract field", s=>{ s.InsertWithCursor(context.TranslateString("Extract field"),Script.InsertPosition.Before,field); s.AddTo(ctor.Body, statement); }); } }
public void LookupArrayTypeMember() { _compilationUnit.UsingDirectives.Add(new UsingNamespaceDirective("System")); var reference = new MemberReferenceExpression { Target = new ParenthesizedExpression( new CreateArrayExpression( new PrimitiveTypeReference(PrimitiveType.Byte), new PrimitiveExpression(3))), Identifier = new Identifier("Length") }; var result = reference.Resolve(_compilationUnit.GetScope()); Assert.IsInstanceOfType(result, typeof(MemberResolveResult)); var memberResult = (MemberResolveResult)result; Assert.AreEqual("System.Array", memberResult.Member.DeclaringType.FullName); Assert.AreEqual("Length", memberResult.Member.Name); Assert.AreEqual("System.Int32", memberResult.Member.MemberType.FullName); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { if (this.m_Mappings.ContainsKey(memberReferenceExpression.MemberName)) { if (memberReferenceExpression.Target is ThisReferenceExpression) { memberReferenceExpression.ReplaceWith( new IdentifierExpression( this.m_Mappings[memberReferenceExpression.MemberName])); return; } } base.VisitMemberReferenceExpression(memberReferenceExpression); }
public override void Visit(MemberReferenceExpression memberReferenceExpression) { base.Visit(memberReferenceExpression); CheckUsage(memberReferenceExpression.TypeInference.Declaration as Variable); }
QueryExpression DecompileQuery(InvocationExpression invocation) { if (invocation == null) { return(null); } MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; if (mre == null) { return(null); } switch (mre.MemberName) { case "Select": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression body; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); query.Clauses.Add(new QuerySelectClause { Expression = body.Detach() }); return(query); } return(null); } case "GroupBy": { if (invocation.Arguments.Count == 2) { string parameterName1, parameterName2; Expression keySelector, elementSelector; if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector) && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector) && parameterName1 == parameterName2) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName1, Expression = mre.Target.Detach() }); query.Clauses.Add(new QueryGroupClause { Projection = elementSelector.Detach(), Key = keySelector.Detach() }); return(query); } } else if (invocation.Arguments.Count == 1) { string parameterName; Expression keySelector; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameterName), Key = keySelector.Detach() }); return(query); } } return(null); } case "SelectMany": { if (invocation.Arguments.Count != 2) { return(null); } string parameterName; Expression collectionSelector; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector)) { return(null); } LambdaExpression lambda = invocation.Arguments.ElementAt(1) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); if (p1.Name == parameterName) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = p1.Name, Expression = mre.Target.Detach() }); query.Clauses.Add(new QueryFromClause { Identifier = p2.Name, Expression = collectionSelector.Detach() }); query.Clauses.Add(new QuerySelectClause { Expression = ((Expression)lambda.Body).Detach() }); return(query); } } return(null); } case "Where": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression body; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); query.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }); return(query); } return(null); } case "OrderBy": case "OrderByDescending": case "ThenBy": case "ThenByDescending": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression orderExpression; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression)) { if (ValidateThenByChain(invocation, parameterName)) { QueryOrderClause orderClause = new QueryOrderClause(); InvocationExpression tmp = invocation; while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { // insert new ordering at beginning orderClause.Orderings.InsertAfter( null, new QueryOrdering { Expression = orderExpression.Detach(), Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) }); tmp = (InvocationExpression)mre.Target; mre = (MemberReferenceExpression)tmp.Target; MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression); } // insert new ordering at beginning orderClause.Orderings.InsertAfter( null, new QueryOrdering { Expression = orderExpression.Detach(), Direction = (mre.MemberName == "OrderBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) }); QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = mre.Target.Detach() }); query.Clauses.Add(orderClause); return(query); } } return(null); } case "Join": case "GroupJoin": { if (invocation.Arguments.Count != 4) { return(null); } Expression source1 = mre.Target; Expression source2 = invocation.Arguments.ElementAt(0); string elementName1, elementName2; Expression key1, key2; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1)) { return(null); } if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2)) { return(null); } LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); if (p1.Name == elementName1 && (p2.Name == elementName2 || mre.MemberName == "GroupJoin")) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = elementName1, Expression = source1.Detach() }); QueryJoinClause joinClause = new QueryJoinClause(); joinClause.JoinIdentifier = elementName2; // join elementName2 joinClause.InExpression = source2.Detach(); // in source2 joinClause.OnExpression = key1.Detach(); // on key1 joinClause.EqualsExpression = key2.Detach(); // equals key2 if (mre.MemberName == "GroupJoin") { joinClause.IntoIdentifier = p2.Name; // into p2.Name } query.Clauses.Add(joinClause); query.Clauses.Add(new QuerySelectClause { Expression = ((Expression)lambda.Body).Detach() }); return(query); } } return(null); } default: return(null); } }
public static CompilerError InstanceMethodInvocationBeforeInitialization(Constructor ctor, MemberReferenceExpression mre) { return(Instantiate("BCE0158", mre, mre.Name, SelfKeyword)); }
public void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { StartNode(memberReferenceExpression); memberReferenceExpression.Target.AcceptVisitor(this); WriteToken(Roles.Dot); WriteIdentifier(memberReferenceExpression.MemberName); WriteTypeArguments(memberReferenceExpression.TypeArguments); EndNode(memberReferenceExpression); }
public virtual void VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression) { VisitChildren (memberReferenceExpression); }
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data) { if (objectCreateExpression.Arguments.Count == 2) { Expression obj = objectCreateExpression.Arguments.First(); Expression func = objectCreateExpression.Arguments.Last(); Annotation annotation = func.Annotation <Annotation>(); if (annotation != null) { IdentifierExpression methodIdent = (IdentifierExpression)((InvocationExpression)func).Arguments.Single(); MethodReference method = methodIdent.Annotation <MethodReference>(); if (method != null) { if (HandleAnonymousMethod(objectCreateExpression, obj, method)) { return(null); } // Perform the transformation to "new Action(obj.func)". obj.Remove(); methodIdent.Remove(); if (!annotation.IsVirtual && obj is ThisReferenceExpression) { // maybe it's getting the pointer of a base method? if (method.DeclaringType.GetElementType() != context.CurrentType) { obj = new BaseReferenceExpression(); } } if (!annotation.IsVirtual && obj is NullReferenceExpression && !method.HasThis) { // We're loading a static method. // However it is possible to load extension methods with an instance, so we compare the number of arguments: bool isExtensionMethod = false; TypeReference delegateType = objectCreateExpression.Type.Annotation <TypeReference>(); if (delegateType != null) { TypeDefinition delegateTypeDef = delegateType.Resolve(); if (delegateTypeDef != null) { MethodDefinition invokeMethod = delegateTypeDef.Methods.FirstOrDefault(m => m.Name == "Invoke"); if (invokeMethod != null) { isExtensionMethod = (invokeMethod.Parameters.Count + 1 == method.Parameters.Count); } } } if (!isExtensionMethod) { obj = new TypeReferenceExpression { Type = AstBuilder.ConvertType(method.DeclaringType) }; } } // now transform the identifier into a member reference MemberReferenceExpression mre = new MemberReferenceExpression(); mre.Target = obj; mre.MemberName = methodIdent.Identifier; methodIdent.TypeArguments.MoveTo(mre.TypeArguments); mre.AddAnnotation(method); objectCreateExpression.Arguments.Clear(); objectCreateExpression.Arguments.Add(mre); return(null); } } } return(base.VisitObjectCreateExpression(objectCreateExpression, data)); }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) { int numberOfVariablesOutsideBlock = currentlyUsedVariableNames.Count; base.VisitBlockStatement(blockStatement, data); foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray()) { Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt); if (!displayClassAssignmentMatch.Success) { continue; } ILVariable variable = displayClassAssignmentMatch.Get <AstNode>("variable").Single().Annotation <ILVariable>(); if (variable == null) { continue; } TypeDefinition type = variable.Type.ResolveWithinSameModule(); if (!IsPotentialClosure(context, type)) { continue; } if (displayClassAssignmentMatch.Get <AstType>("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type) { continue; } // Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses: bool ok = true; foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>()) { if (identExpr.Identifier == variable.Name && identExpr != displayClassAssignmentMatch.Get("variable").Single()) { if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation <FieldReference>() != null)) { ok = false; } } } if (!ok) { continue; } Dictionary <FieldReference, AstNode> dict = new Dictionary <FieldReference, AstNode>(); // Delete the variable declaration statement: VariableDeclarationStatement displayClassVarDecl = PatternStatementTransform.FindVariableDeclaration(stmt, variable.Name); if (displayClassVarDecl != null) { displayClassVarDecl.Remove(); } // Delete the assignment statement: AstNode cur = stmt.NextSibling; stmt.Remove(); // Delete any following statements as long as they assign parameters to the display class BlockStatement rootBlock = blockStatement.Ancestors.OfType <BlockStatement>().LastOrDefault() ?? blockStatement; List <ILVariable> parameterOccurrances = rootBlock.Descendants.OfType <IdentifierExpression>() .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).ToList(); AstNode next; for (; cur != null; cur = next) { next = cur.NextSibling; // Test for the pattern: // "variableName.MemberName = right;" ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement( new AssignmentExpression( new NamedNode("left", new MemberReferenceExpression { Target = new IdentifierExpression(variable.Name), MemberName = Pattern.AnyString }), new AnyNode("right") ) ); Match m = closureFieldAssignmentPattern.Match(cur); if (m.Success) { FieldDefinition fieldDef = m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule(); AstNode right = m.Get <AstNode>("right").Single(); bool isParameter = false; bool isDisplayClassParentPointerAssignment = false; if (right is ThisReferenceExpression) { isParameter = true; } else if (right is IdentifierExpression) { // handle parameters only if the whole method contains no other occurrence except for 'right' ILVariable v = right.Annotation <ILVariable>(); isParameter = v.IsParameter && parameterOccurrances.Count(c => c == v) == 1; if (!isParameter && IsPotentialClosure(context, v.Type.ResolveWithinSameModule())) { // parent display class within the same method // (closure2.localsX = closure1;) isDisplayClassParentPointerAssignment = true; } } else if (right is MemberReferenceExpression) { // copy of parent display class reference from an outer lambda // closure2.localsX = this.localsY MemberReferenceExpression mre = m.Get <MemberReferenceExpression>("right").Single(); do { // descend into the targets of the mre as long as the field types are closures FieldDefinition fieldDef2 = mre.Annotation <FieldReference>().ResolveWithinSameModule(); if (fieldDef2 == null || !IsPotentialClosure(context, fieldDef2.FieldType.ResolveWithinSameModule())) { break; } // if we finally get to a this reference, it's copying a display class parent pointer if (mre.Target is ThisReferenceExpression) { isDisplayClassParentPointerAssignment = true; } mre = mre.Target as MemberReferenceExpression; } while (mre != null); } if (isParameter || isDisplayClassParentPointerAssignment) { dict[fieldDef] = right; cur.Remove(); } else { break; } } else { break; } } // Now create variables for all fields of the display class (except for those that we already handled as parameters) List <Tuple <AstType, ILVariable> > variablesToDeclare = new List <Tuple <AstType, ILVariable> >(); foreach (FieldDefinition field in type.Fields) { if (field.IsStatic) { continue; // skip static fields } if (dict.ContainsKey(field)) // skip field if it already was handled as parameter { continue; } string capturedVariableName = field.Name; if (capturedVariableName.StartsWith("$VB$Local_", StringComparison.Ordinal) && capturedVariableName.Length > 10) { capturedVariableName = capturedVariableName.Substring(10); } EnsureVariableNameIsAvailable(blockStatement, capturedVariableName); currentlyUsedVariableNames.Add(capturedVariableName); ILVariable ilVar = new ILVariable { IsGenerated = true, Name = capturedVariableName, Type = field.FieldType, }; variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), ilVar)); dict[field] = new IdentifierExpression(capturedVariableName).WithAnnotation(ilVar); } // Now figure out where the closure was accessed and use the simpler replacement expression there: foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>()) { if (identExpr.Identifier == variable.Name) { MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent; AstNode replacement; if (dict.TryGetValue(mre.Annotation <FieldReference>().ResolveWithinSameModule(), out replacement)) { mre.ReplaceWith(replacement.Clone()); } } } // Now insert the variable declarations (we can do this after the replacements only so that the scope detection works): Statement insertionPoint = blockStatement.Statements.FirstOrDefault(); foreach (var tuple in variablesToDeclare) { var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2.Name); newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation()); newVarDecl.Variables.Single().AddAnnotation(tuple.Item2); blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl); } } currentlyUsedVariableNames.RemoveRange(numberOfVariablesOutsideBlock, currentlyUsedVariableNames.Count - numberOfVariablesOutsideBlock); return(null); }
void ProcessInvocationExpression(InvocationExpression invocationExpression) { var method = invocationExpression.GetSymbol() as IMethod; if (method == null) { return; } var arguments = invocationExpression.Arguments.ToArray(); // Reduce "String.Concat(a, b)" to "a + b" if (method.Name == "Concat" && method.DeclaringType.FullName == "System.String" && CheckArgumentsForStringConcat(arguments)) { invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression Expression expr = arguments[0]; for (int i = 1; i < arguments.Length; i++) { expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]); } invocationExpression.ReplaceWith(expr); return; } switch (method.FullName) { case "System.Type.GetTypeFromHandle": if (arguments.Length == 1) { if (typeHandleOnTypeOfPattern.IsMatch(arguments[0])) { invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target); return; } } break; case "System.Reflection.FieldInfo.GetFieldFromHandle": if (arguments.Length == 1) { MemberReferenceExpression mre = arguments[0] as MemberReferenceExpression; if (mre != null && mre.MemberName == "FieldHandle" && mre.Target.Annotation <LdTokenAnnotation>() != null) { invocationExpression.ReplaceWith(mre.Target); return; } } else if (arguments.Length == 2) { MemberReferenceExpression mre1 = arguments[0] as MemberReferenceExpression; MemberReferenceExpression mre2 = arguments[1] as MemberReferenceExpression; if (mre1 != null && mre1.MemberName == "FieldHandle" && mre1.Target.Annotation <LdTokenAnnotation>() != null) { if (mre2 != null && mre2.MemberName == "TypeHandle" && mre2.Target is TypeOfExpression) { Expression oldArg = ((InvocationExpression)mre1.Target).Arguments.Single(); FieldReference field = oldArg.Annotation <FieldReference>(); if (field != null) { AstType declaringType = ((TypeOfExpression)mre2.Target).Type.Detach(); oldArg.ReplaceWith(new MemberReferenceExpression(new TypeReferenceExpression(declaringType), field.Name).CopyAnnotationsFrom(oldArg)); invocationExpression.ReplaceWith(mre1.Target); return; } } } } break; } BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(method.Name); if (bop != null && arguments.Length == 2) { invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression invocationExpression.ReplaceWith( new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).CopyAnnotationsFrom(invocationExpression) ); return; } UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(method.Name); if (uop != null && arguments.Length == 1) { arguments[0].Remove(); // detach argument invocationExpression.ReplaceWith( new UnaryOperatorExpression(uop.Value, arguments[0]).CopyAnnotationsFrom(invocationExpression) ); return; } if (method.Name == "op_Explicit" && arguments.Length == 1) { arguments[0].Remove(); // detach argument invocationExpression.ReplaceWith( new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.ReturnType), arguments[0]) .CopyAnnotationsFrom(invocationExpression) ); return; } if (method.Name == "op_Implicit" && arguments.Length == 1) { invocationExpression.ReplaceWith(arguments[0]); return; } if (method.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition) { invocationExpression.ReplaceWith(arguments[0]); return; } return; }
public MemberReferenceBlock(IEmitter emitter, MemberReferenceExpression memberReferenceExpression) : base(emitter, memberReferenceExpression) { this.Emitter = emitter; this.MemberReferenceExpression = memberReferenceExpression; }
protected void VisitMemberReferenceExpression() { MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression; int pos = this.Emitter.Output.Length; bool isRefArg = this.Emitter.IsRefArg; this.Emitter.IsRefArg = false; ResolveResult resolveResult = null; ResolveResult expressionResolveResult = null; string targetVar = null; string valueVar = null; bool isStatement = false; bool isConstTarget = false; var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter); if (targetrr is ConstantResolveResult) { isConstTarget = true; } var memberTargetrr = targetrr as MemberResolveResult; if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && Helpers.EnumEmitMode(memberTargetrr.Type) == 2) { isConstTarget = true; } if (memberReferenceExpression.Target is ParenthesizedExpression || (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Int64)) || (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.UInt64)) || (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Decimal))) { isConstTarget = false; } var isInvoke = memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression); if (isInvoke) { resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter); expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter); if (expressionResolveResult is InvocationResolveResult) { resolveResult = expressionResolveResult; } else if (expressionResolveResult is MemberResolveResult) { if (((MemberResolveResult)expressionResolveResult).Member is IProperty) { resolveResult = expressionResolveResult; } } } else { resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter); } bool oldIsAssignment = this.Emitter.IsAssignment; bool oldUnary = this.Emitter.IsUnaryAccessor; if (resolveResult == null) { this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; this.WriteDot(); string name = memberReferenceExpression.MemberName; this.Write(name.ToLowerCamelCase()); return; } bool isDynamic = false; if (resolveResult is DynamicInvocationResolveResult) { var dynamicResolveResult = (DynamicInvocationResolveResult)resolveResult; var group = dynamicResolveResult.Target as MethodGroupResolveResult; if (group != null && group.Methods.Count() > 1) { var method = group.Methods.FirstOrDefault(m => { if (dynamicResolveResult.Arguments.Count != m.Parameters.Count) { return(false); } for (int i = 0; i < m.Parameters.Count; i++) { var argType = dynamicResolveResult.Arguments[i].Type; if (argType.Kind == TypeKind.Dynamic) { argType = this.Emitter.Resolver.Compilation.FindType(TypeCode.Object); } if (!m.Parameters[i].Type.Equals(argType)) { return(false); } } return(true); }) ?? group.Methods.Last(); isDynamic = true; resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method); resolveResult = new InvocationResolveResult(resolveResult, method, dynamicResolveResult.Arguments); } } if (resolveResult is MethodGroupResolveResult) { var oldResult = (MethodGroupResolveResult)resolveResult; resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter); if (resolveResult is DynamicInvocationResolveResult) { var method = oldResult.Methods.Last(); resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method); } } MemberResolveResult member = resolveResult as MemberResolveResult; var globalTarget = member != null?this.Emitter.IsGlobalTarget(member.Member) : null; if (member != null && member.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.NonScriptableAttribute")) { throw new EmitterException(this.MemberReferenceExpression, "Member " + member.ToString() + " is marked as not usable from script"); } if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod) { var interceptor = this.Emitter.Plugins.OnReference(this, this.MemberReferenceExpression, member); if (interceptor.Cancel) { return; } if (!string.IsNullOrEmpty(interceptor.Replacement)) { this.Write(interceptor.Replacement); return; } } if (globalTarget != null && globalTarget.Item1) { var target = globalTarget.Item2; if (!string.IsNullOrWhiteSpace(target)) { bool assign = false; var memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent; var targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression; var assignment = memberExpression as AssignmentExpression; if (assignment != null && assignment.Right == targetExpression) { assign = true; } else { var varInit = memberExpression as VariableInitializer; if (varInit != null && varInit.Initializer == targetExpression) { assign = true; } else if (memberExpression is InvocationExpression) { var targetInvocation = (InvocationExpression)memberExpression; if (targetInvocation.Arguments.Any(a => a == targetExpression)) { assign = true; } } } if (assign) { if (resolveResult is InvocationResolveResult) { this.PushWriter(target); } else { this.Write(target); } return; } } if (resolveResult is InvocationResolveResult) { this.PushWriter(""); } return; } Tuple <bool, bool, string> inlineInfo = member != null ? (isDynamic ? ((Emitter)this.Emitter).GetInlineCodeFromMember(member.Member, null) : this.Emitter.GetInlineCode(memberReferenceExpression)) : null; //string inline = member != null ? this.Emitter.GetInline(member.Member) : null; string inline = inlineInfo != null ? inlineInfo.Item3 : null; if (string.IsNullOrEmpty(inline) && member != null && member.Member is IMethod && !(member is InvocationResolveResult) && !( memberReferenceExpression.Parent is InvocationExpression && memberReferenceExpression.NextSibling != null && memberReferenceExpression.NextSibling.Role is TokenRole && ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "(" ) ) { var method = (IMethod)member.Member; if (method.TypeArguments.Count > 0) { inline = MemberReferenceBlock.GenerateInlineForMethodReference(method, this.Emitter); } } if (member != null && member.Member is IMethod && isInvoke) { var i_rr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter) as CSharpInvocationResolveResult; if (i_rr != null && !i_rr.IsExpandedForm) { var tpl = this.Emitter.GetAttribute(member.Member.Attributes, JS.NS.BRIDGE + ".TemplateAttribute"); if (tpl != null && tpl.PositionalArguments.Count == 2) { inline = tpl.PositionalArguments[1].ConstantValue.ToString(); } } } bool hasInline = !string.IsNullOrEmpty(inline); bool hasThis = hasInline && inline.Contains("{this}"); bool isInterfaceMember = false; if (hasInline && inline.StartsWith("<self>")) { hasThis = true; inline = inline.Substring(6); } bool nativeImplementation = true; bool isInterface = inline == null && member != null && member.Member.DeclaringTypeDefinition != null && member.Member.DeclaringTypeDefinition.Kind == TypeKind.Interface; var hasTypeParemeter = isInterface && Helpers.IsTypeParameterType(member.Member.DeclaringType); if (isInterface) { var ei = this.Emitter.Validator.IsExternalInterface(member.Member.DeclaringTypeDefinition); if (ei != null) { nativeImplementation = ei.IsNativeImplementation; } else { nativeImplementation = member.Member.DeclaringTypeDefinition.ParentAssembly.AssemblyName == CS.NS.ROOT || !this.Emitter.Validator.IsExternalType(member.Member.DeclaringTypeDefinition); } if (ei != null && ei.IsSimpleImplementation) { nativeImplementation = false; isInterfaceMember = false; } else if (ei != null || hasTypeParemeter) { if (hasTypeParemeter || !nativeImplementation) { isInterfaceMember = true; } } } string interfaceTempVar = null; if (hasThis) { this.Write(""); var oldBuilder = this.Emitter.Output; var oldInline = inline; string thisArg = null; bool isSimple = true; if (this.MemberReferenceExpression.Target is BaseReferenceExpression) { thisArg = "this"; } else { this.Emitter.Output = new StringBuilder(); this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } this.WriteSimpleTarget(resolveResult); if (isConstTarget) { this.Write(")"); } thisArg = this.Emitter.Output.ToString(); if (Regex.Matches(inline, @"\{(\*?)this\}").Count > 1) { var mrr = resolveResult as MemberResolveResult; bool isField = mrr != null && mrr.Member is IField && (mrr.TargetResult is ThisResolveResult || mrr.TargetResult is LocalResolveResult || mrr.TargetResult is MemberResolveResult && ((MemberResolveResult)mrr.TargetResult).Member is IField); isSimple = (mrr != null && (mrr.TargetResult is ThisResolveResult || mrr.TargetResult is ConstantResolveResult || mrr.TargetResult is LocalResolveResult)) || isField; } } int thisIndex; if (!isSimple) { StringBuilder sb = new StringBuilder(); sb.Append("("); var tempVar = this.GetTempVarName(); inline = inline.Replace("{this}", tempVar); thisIndex = tempVar.Length + 2; sb.Append(tempVar); sb.Append(" = "); sb.Append(thisArg); sb.Append(", "); sb.Append(inline); sb.Append(")"); inline = sb.ToString(); } else { thisIndex = inline.IndexOf("{this}", StringComparison.Ordinal); inline = inline.Replace("{this}", thisArg); } if (member != null && member.Member is IProperty) { this.Emitter.Output = new StringBuilder(); inline = inline.Replace("{0}", "[[0]]"); new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit(); inline = this.Emitter.Output.ToString(); inline = inline.Replace("[[0]]", "{0}"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; this.Emitter.Output = oldBuilder; int[] range = null; if (thisIndex > -1) { range = new[] { thisIndex, thisIndex + thisArg.Length }; } if (resolveResult is InvocationResolveResult) { this.PushWriter(inline, null, thisArg, range); } else { if (member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), oldInline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else if (member != null && member.Member is IField && inline.Contains("{0}")) { this.PushWriter(inline, null, thisArg, range); } else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inline)) { this.PushWriter(inline, null, thisArg, range); } else { this.Write(inline); } } return; } if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member)) { var parentExpression = memberReferenceExpression.Parent as MemberReferenceExpression; bool wrap = false; if (parentExpression != null) { var ii = this.Emitter.GetInlineCode(parentExpression); if (string.IsNullOrEmpty(ii.Item3)) { wrap = true; this.WriteOpenParentheses(); } } this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter)); if (wrap) { this.WriteCloseParentheses(); } } else if (hasInline && member.Member.IsStatic) { if (resolveResult is InvocationResolveResult) { this.PushWriter(inline); } else { if (member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit(); } } } else { if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum) { var typeDef = member.Member.DeclaringType as ITypeDefinition; if (typeDef != null) { var enumMode = Helpers.EnumEmitMode(typeDef); if ((this.Emitter.Validator.IsExternalType(typeDef) && enumMode == -1) || enumMode == 2) { this.WriteScript(member.ConstantValue); return; } if (enumMode >= 3 && enumMode < 7) { string enumStringName = this.Emitter.GetEntityName(member.Member); this.WriteScript(enumStringName); return; } } } if (resolveResult is TypeResolveResult) { TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult; this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); return; } else if (member != null && member.Member is IMethod && !(member is InvocationResolveResult) && !( memberReferenceExpression.Parent is InvocationExpression && memberReferenceExpression.NextSibling != null && memberReferenceExpression.NextSibling.Role is TokenRole && ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "(" ) ) { if (!string.IsNullOrEmpty(inline)) { if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment)) { this.PushWriter(inline); } else { this.Write(inline); } } else { var resolvedMethod = (IMethod)member.Member; bool isStatic = resolvedMethod != null && resolvedMethod.IsStatic; var isExtensionMethod = resolvedMethod.IsExtensionMethod; this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (!isStatic) { this.Write(isExtensionMethod ? JS.Funcs.BRIDGE_BIND_SCOPE : JS.Funcs.BRIDGE_CACHE_BIND); this.WriteOpenParentheses(); if (memberReferenceExpression.Target is BaseReferenceExpression) { this.WriteThis(); } else { interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, false); } this.Write(", "); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; if (isExtensionMethod) { this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter)); } else { this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } if (interfaceTempVar != null) { this.Write(interfaceTempVar); } else { this.WriteSimpleTarget(resolveResult); } if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; } if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar, member, false); } else { this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation)); } if (!isStatic) { this.Write(")"); } } return; } else { bool isProperty = false; if (member != null && member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))) { isProperty = true; bool writeTargetVar = false; if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign) { writeTargetVar = true; } else if (this.Emitter.IsUnaryAccessor) { writeTargetVar = true; isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement; if (NullableType.IsNullable(member.Type)) { isStatement = false; } if (!isStatement) { this.WriteOpenParentheses(); } } if (writeTargetVar) { bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult); if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField)) { targetVar = this.GetTempVarName(); this.Write(targetVar); this.Write(" = "); } } } if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null) { valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); } this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } if (targetVar == null && isInterfaceMember) { interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, true); } else { this.WriteSimpleTarget(resolveResult); } if (member != null && targetrr != null && targetrr.Type.Kind == TypeKind.Delegate && (member.Member.Name == "Invoke")) { var method = member.Member as IMethod; if (!(method != null && method.IsExtensionMethod)) { return; } } if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; if (targetVar != null) { if (this.Emitter.IsUnaryAccessor && !isStatement) { this.WriteComma(false); valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.Write(targetVar); } else { this.WriteSemiColon(); this.WriteNewLine(); this.Write(targetVar); } } } var targetResolveResult = targetrr as MemberResolveResult; if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null) { if (isRefArg) { this.WriteComma(); } else if (!isInterfaceMember && !this.NoTarget) { this.WriteDot(); } } if (member == null) { if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic) { this.Write(memberReferenceExpression.MemberName); } else { this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase()); } } else if (!string.IsNullOrEmpty(inline)) { if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment)) { this.PushWriter(inline); } else { this.Write(inline); } } else if (member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || (!this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition) || member.Member.IsStatic))) { if (member.Member is IProperty && targetrr != null && targetrr.Type.GetDefinition() != null && this.Emitter.Validator.IsObjectLiteral(targetrr.Type.GetDefinition()) && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition)) { this.Write(this.Emitter.GetLiteralEntityName(member.Member)); } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { var name = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation); var property = (IProperty)member.Member; var proto = member.IsVirtualCall || property.IsVirtual || property.IsOverride; if (this.MemberReferenceExpression.Target is BaseReferenceExpression && !property.IsIndexer && proto) { var alias = BridgeTypes.ToJsName(member.Member.DeclaringType, this.Emitter, isAlias: true); if (alias.StartsWith("\"")) { alias = alias.Insert(1, "$"); name = alias + "+\"$" + name + "\""; this.WriteIdentifier(name, false); } else { name = "$" + alias + "$" + name; this.WriteIdentifier(name); } } else { this.WriteIdentifier(name); } } } } else if (member.Member.SymbolKind == SymbolKind.Field) { bool isConst = this.Emitter.IsMemberConst(member.Member); if (isConst && this.Emitter.IsInlineConst(member.Member)) { this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter)); } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { var fieldName = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation); if (isRefArg) { this.WriteScript(fieldName); } else { this.WriteIdentifier(fieldName); } } } } else if (resolveResult is InvocationResolveResult) { InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult; CSharpInvocationResolveResult cInvocationResult = resolveResult as CSharpInvocationResolveResult; var expresssionMember = expressionResolveResult as MemberResolveResult; if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else if (expresssionMember != null && cInvocationResult != null && cInvocationResult.IsDelegateInvocation && invocationResult.Member != expresssionMember.Member) { this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName(!nativeImplementation)); } else { this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(!nativeImplementation)); } } else if (member.Member is IEvent) { if (this.Emitter.IsAssignment && (this.Emitter.AssignmentType == AssignmentOperatorType.Add || this.Emitter.AssignmentType == AssignmentOperatorType.Subtract)) { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract, Helpers.GetAddOrRemove(this.Emitter.AssignmentType == AssignmentOperatorType.Add)); } else { this.Write(Helpers.GetEventRef(member.Member, this.Emitter, this.Emitter.AssignmentType != AssignmentOperatorType.Add, ignoreInterface: !nativeImplementation)); } this.WriteOpenParentheses(); } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { this.Write(this.Emitter.GetEntityName(member.Member)); } } } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { this.Write(this.Emitter.GetEntityName(member.Member)); } } Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos); } }
private void Visit(MemberReferenceExpression memberReferenceExpression) { Visit((Node)memberReferenceExpression); CheckUsage(memberReferenceExpression.TypeInference.Declaration as Variable); }
protected void VisitInvocationExpression() { InvocationExpression invocationExpression = this.InvocationExpression; int pos = this.Emitter.Output.Length; if (this.Emitter.IsForbiddenInvocation(invocationExpression)) { throw new EmitterException(invocationExpression, "This method cannot be invoked directly"); } var oldValue = this.Emitter.ReplaceAwaiterByVar; var oldAsyncExpressionHandling = this.Emitter.AsyncExpressionHandling; if (this.Emitter.IsAsync && !this.Emitter.AsyncExpressionHandling) { this.WriteAwaiters(invocationExpression); this.Emitter.ReplaceAwaiterByVar = true; this.Emitter.AsyncExpressionHandling = true; } Tuple <bool, bool, string> inlineInfo = this.Emitter.GetInlineCode(invocationExpression); var argsInfo = new ArgumentsInfo(this.Emitter, invocationExpression); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; var targetResolve = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter); var csharpInvocation = targetResolve as CSharpInvocationResolveResult; MemberReferenceExpression targetMember = invocationExpression.Target as MemberReferenceExpression; bool isObjectLiteral = csharpInvocation != null && csharpInvocation.Member.DeclaringTypeDefinition != null?this.Emitter.Validator.IsObjectLiteral(csharpInvocation.Member.DeclaringTypeDefinition) : false; var interceptor = this.Emitter.Plugins.OnInvocation(this, this.InvocationExpression, targetResolve as InvocationResolveResult); if (interceptor.Cancel) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } if (!string.IsNullOrEmpty(interceptor.Replacement)) { this.Write(interceptor.Replacement); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } if (inlineInfo != null) { bool isStaticMethod = inlineInfo.Item1; bool isInlineMethod = inlineInfo.Item2; string inlineScript = inlineInfo.Item3; if (isInlineMethod) { if (invocationExpression.Arguments.Count > 0) { var code = invocationExpression.Arguments.First(); var inlineExpression = code as PrimitiveExpression; if (inlineExpression == null) { throw new EmitterException(invocationExpression, "Only primitive expression can be inlined"); } string value = inlineExpression.Value.ToString().Trim(); if (value.Length > 0) { value = InlineArgumentsBlock.ReplaceInlineArgs(this, inlineExpression.Value.ToString(), invocationExpression.Arguments.Skip(1).ToArray()); this.Write(value); value = value.Trim(); if (value[value.Length - 1] == ';' || value.EndsWith("*/", StringComparison.InvariantCulture) || value.StartsWith("//")) { this.Emitter.EnableSemicolon = false; this.WriteNewLine(); } } else { // Empty string, emit nothing. this.Emitter.EnableSemicolon = false; } this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else { MemberReferenceExpression targetMemberRef = invocationExpression.Target as MemberReferenceExpression; bool isBase = targetMemberRef != null && targetMemberRef.Target is BaseReferenceExpression; if (!String.IsNullOrEmpty(inlineScript) && (isBase || invocationExpression.Target is IdentifierExpression)) { argsInfo.ThisArgument = "this"; bool noThis = !inlineScript.Contains("{this}"); if (inlineScript.StartsWith("<self>")) { noThis = false; inlineScript = inlineScript.Substring(6); } if (!noThis) { Emitter.ThisRefCounter++; } if (!isStaticMethod && noThis) { this.WriteThis(); this.WriteDot(); } new InlineArgumentsBlock(this.Emitter, argsInfo, inlineScript).Emit(); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } } if (targetMember != null || isObjectLiteral) { var member = targetMember != null?this.Emitter.Resolver.ResolveNode(targetMember.Target, this.Emitter) : null; if (targetResolve != null) { InvocationResolveResult invocationResult; bool isExtensionMethodInvocation = false; if (csharpInvocation != null) { if (member != null && member.Type.Kind == TypeKind.Delegate && (/*csharpInvocation.Member.Name == "Invoke" || */ csharpInvocation.Member.Name == "BeginInvoke" || csharpInvocation.Member.Name == "EndInvoke") && !csharpInvocation.IsExtensionMethodInvocation) { throw new EmitterException(invocationExpression, "Delegate's 'Invoke' methods are not supported. Please use direct delegate invoke."); } if (csharpInvocation.IsExtensionMethodInvocation) { invocationResult = csharpInvocation; isExtensionMethodInvocation = true; var resolvedMethod = invocationResult.Member as IMethod; if (resolvedMethod != null && resolvedMethod.IsExtensionMethod) { string inline = this.Emitter.GetInline(resolvedMethod); bool isNative = this.IsNativeMethod(resolvedMethod); if (string.IsNullOrWhiteSpace(inline) && isNative) { invocationResult = null; } } } else { invocationResult = null; } if (this.IsEmptyPartialInvoking(csharpInvocation.Member as IMethod) || IsConditionallyRemoved(invocationExpression, csharpInvocation.Member)) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else { invocationResult = targetResolve as InvocationResolveResult; if (invocationResult != null && (this.IsEmptyPartialInvoking(invocationResult.Member as IMethod) || IsConditionallyRemoved(invocationExpression, invocationResult.Member))) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } if (invocationResult == null) { invocationResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as InvocationResolveResult; } if (invocationResult != null) { var resolvedMethod = invocationResult.Member as IMethod; if (resolvedMethod != null && (resolvedMethod.IsExtensionMethod || isObjectLiteral)) { string inline = this.Emitter.GetInline(resolvedMethod); bool isNative = this.IsNativeMethod(resolvedMethod); if (isExtensionMethodInvocation || isObjectLiteral) { if (!string.IsNullOrWhiteSpace(inline)) { this.Write(""); StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit(); } else if (!isNative) { var overloads = OverloadsCollection.Create(this.Emitter, resolvedMethod); if (isObjectLiteral && !resolvedMethod.IsStatic && resolvedMethod.DeclaringType.Kind == TypeKind.Interface) { this.Write("Bridge.getType("); this.WriteThisExtension(invocationExpression.Target); this.Write(")."); } else { string name = BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter) + "."; this.Write(name); } if (isObjectLiteral && !resolvedMethod.IsStatic) { this.Write(JS.Fields.PROTOTYPE + "." + overloads.GetOverloadName() + "." + JS.Funcs.CALL); } else { this.Write(overloads.GetOverloadName()); } var isIgnoreClass = resolvedMethod.DeclaringTypeDefinition != null && this.Emitter.Validator.IsIgnoreType(resolvedMethod.DeclaringTypeDefinition); int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); this.Emitter.Comma = false; if (isObjectLiteral && !resolvedMethod.IsStatic) { this.WriteThisExtension(invocationExpression.Target); this.Emitter.Comma = true; } if (!isIgnoreClass && !Helpers.IsIgnoreGeneric(resolvedMethod, this.Emitter) && argsInfo.HasTypeArguments) { this.EnsureComma(false); new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); this.Emitter.Comma = true; } if (!isObjectLiteral && resolvedMethod.IsStatic) { this.EnsureComma(false); this.WriteThisExtension(invocationExpression.Target); this.Emitter.Comma = true; } if (invocationExpression.Arguments.Count > 0) { this.EnsureComma(false); } new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit(); this.WriteCloseParentheses(); } if (!string.IsNullOrWhiteSpace(inline) || !isNative) { this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else if (isNative) { if (!string.IsNullOrWhiteSpace(inline)) { this.Write(""); StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit(); } else { argsExpressions.First().AcceptVisitor(this.Emitter); this.WriteDot(); string name = this.Emitter.GetEntityName(resolvedMethod); this.Write(name); int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); new ExpressionListBlock(this.Emitter, argsExpressions.Skip(1), paramsArg, invocationExpression, openPos).Emit(); this.WriteCloseParentheses(); } this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } } } } var proto = false; if (targetMember != null && targetMember.Target is BaseReferenceExpression) { var rr = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter) as MemberResolveResult; if (rr != null) { proto = rr.IsVirtualCall; /*var method = rr.Member as IMethod; * if (method != null && method.IsVirtual) * { * proto = true; * } * else * { * var prop = rr.Member as IProperty; * * if (prop != null && prop.IsVirtual) * { * proto = true; * } * }*/ } } if (proto) { var baseType = this.Emitter.GetBaseMethodOwnerTypeDefinition(targetMember.MemberName, targetMember.TypeArguments.Count); bool isIgnore = this.Emitter.Validator.IsIgnoreType(baseType); if (isIgnore) { //throw (System.Exception)this.Emitter.CreateException(targetMember.Target, "Cannot call base method, because parent class code is ignored"); } bool needComma = false; var resolveResult = this.Emitter.Resolver.ResolveNode(targetMember, this.Emitter); string name = null; if (this.Emitter.TypeInfo.GetBaseTypes(this.Emitter).Any()) { name = BridgeTypes.ToJsName(this.Emitter.TypeInfo.GetBaseClass(this.Emitter), this.Emitter); } else { name = BridgeTypes.ToJsName(baseType, this.Emitter); } string baseMethod; bool isIgnoreGeneric = false; if (resolveResult is InvocationResolveResult) { InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult; baseMethod = OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(); isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, this.Emitter); } else if (resolveResult is MemberResolveResult) { MemberResolveResult memberResult = (MemberResolveResult)resolveResult; baseMethod = OverloadsCollection.Create(this.Emitter, memberResult.Member).GetOverloadName(); isIgnoreGeneric = Helpers.IsIgnoreGeneric(memberResult.Member, this.Emitter); } else { baseMethod = targetMember.MemberName; baseMethod = this.Emitter.AssemblyInfo.PreserveMemberCase ? baseMethod : Object.Net.Utilities.StringUtils.ToLowerCamelCase(baseMethod); } this.Write(name, "." + JS.Fields.PROTOTYPE + ".", baseMethod); this.WriteCall(); this.WriteOpenParentheses(); this.WriteThis(); this.Emitter.Comma = true; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); } needComma = false; foreach (var arg in argsExpressions) { if (arg == null) { continue; } this.EnsureComma(false); if (needComma) { this.WriteComma(); } needComma = true; arg.AcceptVisitor(this.Emitter); } this.Emitter.Comma = false; this.WriteCloseParentheses(); } else { var dynamicResolveResult = this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter) as DynamicInvocationResolveResult; if (dynamicResolveResult != null) { var group = dynamicResolveResult.Target as MethodGroupResolveResult; if (group != null && group.Methods.Count() > 1) { throw new EmitterException(invocationExpression, "Cannot compile this dynamic invocation because there are two or more method overloads with the same parameter count. To work around this limitation, assign the dynamic value to a non-dynamic variable before use or call a method with different parameter count"); } } var targetResolveResult = this.Emitter.Resolver.ResolveNode(invocationExpression.Target, this.Emitter); var invocationResolveResult = targetResolveResult as MemberResolveResult; IMethod method = null; if (invocationResolveResult != null) { method = invocationResolveResult.Member as IMethod; } if (this.IsEmptyPartialInvoking(method) || IsConditionallyRemoved(invocationExpression, method)) { this.Emitter.SkipSemiColon = true; this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } bool isIgnore = method != null && method.DeclaringTypeDefinition != null && this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition); bool needExpand = false; if (method != null) { string paramsName = null; var paramsParam = method.Parameters.FirstOrDefault(p => p.IsParams); if (paramsParam != null) { paramsName = paramsParam.Name; } if (paramsName != null) { if (csharpInvocation != null && !csharpInvocation.IsExpandedForm) { needExpand = true; } } } int count = this.Emitter.Writers.Count; invocationExpression.Target.AcceptVisitor(this.Emitter); if (this.Emitter.Writers.Count > count) { var writer = this.Emitter.Writers.Pop(); if (method != null && method.IsExtensionMethod) { StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; } else if (writer.ThisArg != null) { argsInfo.ThisArgument = writer.ThisArg; } new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode) { IgnoreRange = writer.IgnoreRange }.Emit(); var result = this.Emitter.Output.ToString(); this.Emitter.Output = writer.Output; this.Emitter.IsNewLine = writer.IsNewLine; this.Write(result); if (writer.Callback != null) { writer.Callback.Invoke(); } } else { if (needExpand && isIgnore) { this.Write("." + JS.Funcs.APPLY); } int openPos = this.Emitter.Output.Length; this.WriteOpenParentheses(); bool isIgnoreGeneric = false; var invocationResult = targetResolve as InvocationResolveResult; if (invocationResult != null) { isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, this.Emitter); } if (needExpand && isIgnore) { StringBuilder savedBuilder = this.Emitter.Output; this.Emitter.Output = new StringBuilder(); this.WriteThisExtension(invocationExpression.Target); var thisArg = this.Emitter.Output.ToString(); this.Emitter.Output = savedBuilder; this.Write(thisArg); this.Emitter.Comma = true; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); } this.EnsureComma(false); if (argsExpressions.Length > 1) { this.WriteOpenBracket(); new ExpressionListBlock(this.Emitter, argsExpressions.Take(argsExpressions.Length - 1).ToArray(), paramsArg, invocationExpression, openPos).Emit(); this.WriteCloseBracket(); this.Write(".concat("); new ExpressionListBlock(this.Emitter, new Expression[] { argsExpressions[argsExpressions.Length - 1] }, paramsArg, invocationExpression, openPos).Emit(); this.Write(")"); } else { new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, -1).Emit(); } } else { this.Emitter.Comma = false; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(this.Emitter, argsInfo.TypeArguments).Emit(); } if (invocationExpression.Arguments.Count > 0) { this.EnsureComma(false); } new ExpressionListBlock(this.Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit(); } this.WriteCloseParentheses(); } } Helpers.CheckValueTypeClone(this.Emitter.Resolver.ResolveNode(invocationExpression, this.Emitter), invocationExpression, this, pos); this.Emitter.ReplaceAwaiterByVar = oldValue; this.Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; }
public override StringBuilder VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, int data) { var result = new StringBuilder(); if (!(memberReferenceExpression.Target is ThisReferenceExpression)) result.Append(memberReferenceExpression.Target.AcceptVisitor(this, data)).Append("."); var def = memberReferenceExpression.Annotation<IMemberDefinition>(); if (def != null) return result.Append(Shader.ResolveName(def)); var fref = memberReferenceExpression.Annotation<FieldReference>(); if (fref != null) return result.Append(Shader.ResolveName(fref.Resolve())); throw new NotImplementedException(); }
// ******************************************************************************************************************************** /// <summary> /// Tries to infer the resource key being referenced from the given expression. /// </summary> static string GetKeyFromExpression(Expression expr, out bool isPrefixOnly) { isPrefixOnly = false; #if DEBUG LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver trying to get key from expression: " + expr.ToString()); #endif IndexerExpression indexer = expr as IndexerExpression; if (indexer != null) { foreach (Expression index in indexer.Indexes) { PrimitiveExpression p = index as PrimitiveExpression; if (p != null) { string key = p.Value as string; if (key != null) { #if DEBUG LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found key: " + key); #endif return(key); } } } } InvocationExpression invocation = expr as InvocationExpression; if (invocation != null) { MemberReferenceExpression fre = invocation.TargetObject as MemberReferenceExpression; if (fre != null) { if (fre.MemberName == "GetString" || fre.MemberName == "GetObject" || fre.MemberName == "GetStream") { if (invocation.Arguments.Count > 0) { PrimitiveExpression p = invocation.Arguments[0] as PrimitiveExpression; if (p != null) { string key = p.Value as string; if (key != null) { #if DEBUG LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found key: " + key); #endif return(key); } } } } else if (fre.MemberName == "ApplyResources") { if (invocation.Arguments.Count >= 2) { PrimitiveExpression p = invocation.Arguments[1] as PrimitiveExpression; if (p != null) { string key = p.Value as string; if (key != null) { #if DEBUG LoggingService.Debug("ResourceToolkit: BclNRefactoryResourceResolver found key prefix: " + key); #endif isPrefixOnly = true; return(key); } } } } } } return(null); }
public virtual Node VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { throw new System.NotImplementedException(); }
public void VisitMemberReference(MemberReferenceExpression memRef) { // At this point we can't figure out which scope to use for the member expression // because we don't know anything about the type of the target expression. // So for now bind only the target expression. // Instead we'll do that in type check phase. memRef.Target.AcceptWalker(this); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { new MemberReferenceBlock(this, memberReferenceExpression).Emit(); }
public Node VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { throw new NotImplementedException(); }
bool ConvertPInvoke(MethodDeclaration method, ICSharpCode.OldNRefactory.Ast.Attribute att) { if (att.PositionalArguments.Count != 1) { return(false); } PrimitiveExpression pe = att.PositionalArguments[0] as PrimitiveExpression; if (pe == null || !(pe.Value is string)) { return(false); } string libraryName = (string)pe.Value; string alias = null; bool setLastError = false; bool exactSpelling = false; CharsetModifier charSet = CharsetModifier.Auto; foreach (NamedArgumentExpression arg in att.NamedArguments) { switch (arg.Name) { case "SetLastError": pe = arg.Expression as PrimitiveExpression; if (pe != null && pe.Value is bool) { setLastError = (bool)pe.Value; } else { return(false); } break; case "ExactSpelling": pe = arg.Expression as PrimitiveExpression; if (pe != null && pe.Value is bool) { exactSpelling = (bool)pe.Value; } else { return(false); } break; case "CharSet": { MemberReferenceExpression fre = arg.Expression as MemberReferenceExpression; if (fre == null || !(fre.TargetObject is IdentifierExpression)) { return(false); } if ((fre.TargetObject as IdentifierExpression).Identifier != "CharSet") { return(false); } switch (fre.MemberName) { case "Unicode": charSet = CharsetModifier.Unicode; break; case "Auto": charSet = CharsetModifier.Auto; break; case "Ansi": charSet = CharsetModifier.Ansi; break; default: return(false); } } break; case "EntryPoint": pe = arg.Expression as PrimitiveExpression; if (pe != null) { alias = pe.Value as string; } break; default: return(false); } } if (setLastError && exactSpelling) { // Only P/Invokes with SetLastError and ExactSpelling can be converted to a DeclareDeclaration const Modifiers removeModifiers = Modifiers.Static | Modifiers.Extern; DeclareDeclaration decl = new DeclareDeclaration(method.Name, method.Modifier & ~removeModifiers, method.TypeReference, method.Parameters, method.Attributes, libraryName, alias, charSet); ReplaceCurrentNode(decl); base.VisitDeclareDeclaration(decl, null); return(true); } else { return(false); } }
public static CompilerError MemberNotFound(MemberReferenceExpression node, INamespace @namespace, string suggestion) { return(MemberNotFound(node, node.Name, @namespace, suggestion)); }
override public void LeaveMemberReferenceExpression(MemberReferenceExpression node) { OnReferenceExpression(node); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { HandleExpressionNode(memberReferenceExpression); }
public virtual object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) { throw new global::System.NotImplementedException("MemberReferenceExpression"); }
public static CompilerError MemberNotFound(MemberReferenceExpression node, string @namespace, string suggestion) { return(Instantiate("BCE0019", node, node.Name, @namespace, DidYouMeanOrNull(suggestion))); }
override public void LeaveMemberReferenceExpression(MemberReferenceExpression node) { CheckName(node, node.Name); }
static bool CanTransformToExtensionMethodCall(CSharpResolver resolver, InvocationExpression invocationExpression, out MemberReferenceExpression memberRefExpr, out ResolveResult target, out Expression firstArgument) { var method = invocationExpression.GetSymbol() as IMethod; memberRefExpr = null; target = null; firstArgument = null; if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any()) { return(false); } IReadOnlyList <IType> typeArguments; switch (invocationExpression.Target) { case MemberReferenceExpression mre: typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance; memberRefExpr = mre; break; case IdentifierExpression ide: typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance; memberRefExpr = null; break; default: return(false); } firstArgument = invocationExpression.Arguments.First(); if (firstArgument is NamedArgumentExpression) { return(false); } target = firstArgument.GetResolveResult(); if (target is ConstantResolveResult crr && crr.ConstantValue == null) { target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion); } ResolveResult[] args = new ResolveResult[invocationExpression.Arguments.Count - 1]; string[] argNames = null; int pos = 0; foreach (var arg in invocationExpression.Arguments.Skip(1)) { if (arg is NamedArgumentExpression nae) { if (argNames == null) { argNames = new string[args.Length]; } argNames[pos] = nae.Name; args[pos] = nae.Expression.GetResolveResult(); } else { args[pos] = arg.GetResolveResult(); } pos++; } return(CanTransformToExtensionMethodCall(resolver, method, typeArguments, target, args, argNames)); }
protected virtual Tuple <bool, bool, string> AltGetInlineCode(InvocationExpression node) { var parts = new List <string>(); Expression current = node.Target; var genericCount = -1; while (true) { MemberReferenceExpression member = current as MemberReferenceExpression; if (member != null) { parts.Insert(0, member.MemberName); current = member.Target; if (genericCount < 0) { genericCount = member.TypeArguments.Count; } continue; } IdentifierExpression id = current as IdentifierExpression; if (id != null) { parts.Insert(0, id.Identifier); if (genericCount < 0) { genericCount = id.TypeArguments.Count; } break; } TypeReferenceExpression typeRef = current as TypeReferenceExpression; if (typeRef != null) { parts.Insert(0, Helpers.GetScriptName(typeRef.Type, false)); break; } break; } if (parts.Count < 1) { return(null); } if (genericCount < 0) { genericCount = 0; } string typeName = parts.Count < 2 ? this.TypeInfo.GenericFullName : this.ResolveType(String.Join(".", parts.ToArray(), 0, parts.Count - 1)); if (String.IsNullOrEmpty(typeName)) { return(null); } string methodName = parts[parts.Count - 1]; TypeDefinition type = this.TypeDefinitions[typeName]; var methods = type.Methods.Where(m => m.Name == methodName); foreach (var method in methods) { if (method.Parameters.Count == node.Arguments.Count && method.GenericParameters.Count == genericCount) { bool isInlineMethod = this.Validator.IsInlineMethod(method); string inlineCode = isInlineMethod ? null : this.Validator.GetInlineCode(method); return(new Tuple <bool, bool, string>(method.IsStatic, isInlineMethod, inlineCode)); } } return(null); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression p) { base.VisitMemberReferenceExpression(p); // Check to see whether this is on the owner of the ProcessCell method. if (p.Target is ThisReferenceExpression) { // Replace the AST node with the current value. var field = this.Algorithm.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .Where(v => v.Name == p.MemberName).DefaultIfEmpty(null).First(); var prop = this.Algorithm.GetType() .GetProperties() .Where(v => v.Name == p.MemberName) .DefaultIfEmpty(null) .First(); if (prop == null && field == null) throw new NotSupportedException( "Unable to inline ProcessCell methods that invoke other methods on this algorithm."); if (field != null) return; var value = prop.GetGetMethod().Invoke(this.Algorithm, null); if (value is Enum) p.ReplaceWith(new PrimitiveExpression(value, value.GetType().FullName.Replace("+", ".") + "." + value)); else p.ReplaceWith(new PrimitiveExpression(value)); } else if (p.Target is IdentifierExpression && (p.Target as IdentifierExpression).Identifier == ParameterContextName) { // This is a reference to the runtime context, which we replace with this. p.Target.ReplaceWith(new ThisReferenceExpression()); } }
// Primary expressions public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { ParenthesizeIfRequired(memberReferenceExpression.Target, Primary); base.VisitMemberReferenceExpression(memberReferenceExpression); }
public override object Visit (MemberAccess memberAccess) { Expression result; if (memberAccess.LeftExpression is Indirection) { var ind = memberAccess.LeftExpression as Indirection; result = new PointerReferenceExpression (); result.AddChild ((Expression)ind.Expr.Accept (this), PointerReferenceExpression.Roles.TargetExpression); result.AddChild (new CSharpTokenNode (Convert (ind.Location), "->".Length), PointerReferenceExpression.ArrowRole); } else { result = new MemberReferenceExpression (); if (memberAccess.LeftExpression != null) { var leftExpr = memberAccess.LeftExpression.Accept (this); result.AddChild ((Expression)leftExpr, MemberReferenceExpression.Roles.TargetExpression); } if (!memberAccess.DotLocation.IsNull) { result.AddChild (new CSharpTokenNode (Convert (memberAccess.DotLocation), 1), MemberReferenceExpression.Roles.Dot); } } result.AddChild (Identifier.Create (memberAccess.Name, Convert (memberAccess.Location)), MemberReferenceExpression.Roles.Identifier); if (memberAccess.TypeArguments != null) { AddTypeArguments (result, memberAccess.TypeArguments); } return result; }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { memberReferenceExpression.Target.AcceptVisitor(this); }
public override object Visit(MemberAccess memberAccess) { Expression result; var ind = memberAccess.LeftExpression as Indirection; if (ind != null) { result = new PointerReferenceExpression(); result.AddChild((Expression)ind.Expr.Accept(this), Roles.TargetExpression); result.AddChild(new CSharpTokenNode(Convert(ind.Location), PointerReferenceExpression.ArrowRole), PointerReferenceExpression.ArrowRole); } else { result = new MemberReferenceExpression(); if (memberAccess.LeftExpression != null) { var leftExpr = memberAccess.LeftExpression.Accept(this); result.AddChild((Expression)leftExpr, Roles.TargetExpression); } var loc = LocationsBag.GetLocations(memberAccess); if (loc != null) { result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot); } } result.AddChild(Identifier.Create(memberAccess.Name, Convert(memberAccess.Location)), Roles.Identifier); AddTypeArguments(result, memberAccess); return result; }
internal AstNode EmitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, ILGenerator ilGenerator) { return(new MemberReferenceReflectionEmitter(memberReferenceExpression, ilGenerator, _instructionIndexer, _visitor, _locals).Emit()); }
public override void VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression) { output.Add (Tuple.Create (memberReferenceExpression.MemberNameToken.StartLocation, memberReferenceExpression.MemberName)); }
ArrayInitializerExpression ConvertMemberBindings(Expression elementsArray) { Match m = memberBindingArrayPattern.Match(elementsArray); if (!m.Success) { return(null); } ArrayInitializerExpression result = new ArrayInitializerExpression(); foreach (var binding in m.Get <Expression>("binding")) { InvocationExpression bindingInvocation = binding as InvocationExpression; if (bindingInvocation == null || bindingInvocation.Arguments.Count != 2) { return(null); } MemberReferenceExpression bindingMRE = bindingInvocation.Target as MemberReferenceExpression; if (bindingMRE == null || !expressionTypeReference.IsMatch(bindingMRE.Target)) { return(null); } Expression bindingTarget = bindingInvocation.Arguments.ElementAt(0); Expression bindingValue = bindingInvocation.Arguments.ElementAt(1); string memberName; Match m2 = getMethodFromHandlePattern.Match(bindingTarget); if (m2.Success) { MethodReference setter = m2.Get <AstNode>("method").Single().Annotation <MethodReference>(); if (setter == null) { return(null); } memberName = GetPropertyName(setter); } else { return(null); } Expression convertedValue; switch (bindingMRE.MemberName) { case "Bind": convertedValue = Convert(bindingValue); break; case "MemberBind": convertedValue = ConvertMemberBindings(bindingValue); break; case "ListBind": convertedValue = ConvertElementInit(bindingValue); break; default: return(null); } if (convertedValue == null) { return(null); } result.Elements.Add(new NamedExpression(memberName, convertedValue)); } return(result); }
public override object Visit (MemberAccess memberAccess) { var result = new MemberReferenceExpression (); result.AddChild ((INode)memberAccess.LeftExpression.Accept (this), MemberReferenceExpression.Roles.TargetExpression); result.AddChild (new Identifier (memberAccess.Name, Convert (memberAccess.Location)), MemberReferenceExpression.Roles.Identifier); if (memberAccess.TypeArguments != null) { var location = LocationsBag.GetLocations (memberAccess); if (location != null) result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), MemberReferenceExpression.Roles.LChevron); // AddTypeArguments (result, location, memberAccess.TypeArguments); if (location != null && location.Count > 1) result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), MemberReferenceExpression.Roles.RChevron); } return result; }
Expression ConvertCall(InvocationExpression invocation) { if (invocation.Arguments.Count < 2) { return(NotSupported(invocation)); } Expression target; int firstArgumentPosition; Match m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(0)); if (m.Success) { target = null; firstArgumentPosition = 1; } else { m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(1)); if (!m.Success) { return(NotSupported(invocation)); } target = invocation.Arguments.ElementAt(0); firstArgumentPosition = 2; } MethodReference mr = m.Get <AstNode>("method").Single().Annotation <MethodReference>(); if (mr == null) { return(null); } Expression convertedTarget; if (target == null || target is NullReferenceExpression) { // static method if (m.Has("declaringType")) { convertedTarget = new TypeReferenceExpression(m.Get <AstType>("declaringType").Single().Clone()); } else { convertedTarget = new TypeReferenceExpression(AstBuilder.ConvertType(mr.DeclaringType)); } } else { convertedTarget = Convert(target); if (convertedTarget == null) { return(null); } } MemberReferenceExpression mre = convertedTarget.Member(mr.Name); GenericInstanceMethod gim = mr as GenericInstanceMethod; if (gim != null) { foreach (TypeReference tr in gim.GenericArguments) { mre.TypeArguments.Add(AstBuilder.ConvertType(tr)); } } IList <Expression> arguments = null; if (invocation.Arguments.Count == firstArgumentPosition + 1) { Expression argumentArray = invocation.Arguments.ElementAt(firstArgumentPosition); arguments = ConvertExpressionsArray(argumentArray); } if (arguments == null) { arguments = new List <Expression>(); foreach (Expression argument in invocation.Arguments.Skip(firstArgumentPosition)) { Expression convertedArgument = Convert(argument); if (convertedArgument == null) { return(null); } arguments.Add(convertedArgument); } } MethodDefinition methodDef = mr.Resolve(); if (methodDef != null && methodDef.IsGetter) { PropertyDefinition indexer = AstMethodBodyBuilder.GetIndexer(methodDef); if (indexer != null) { return(new IndexerExpression(mre.Target.Detach(), arguments).WithAnnotation(indexer)); } } return(new InvocationExpression(mre, arguments).WithAnnotation(mr)); }
override public void OnMemberReferenceExpression(MemberReferenceExpression node) { base.OnMemberReferenceExpression(node); CheckName(node, node.Name); }
/// <inheritdoc /> public override void Visit(MemberReferenceExpression memberReferenceExpression) { VisitDynamic(memberReferenceExpression.Target); Write("."); VisitDynamic(memberReferenceExpression.Member); }