internal ArgumentReferenceEmitter(IdentifierExpression identifierExpression, ParameterDefinition parameterDefinition, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer) : base(ilGenerator, instructionsIndexer) { _parameterDefinition = parameterDefinition; _identifierExpression = identifierExpression; Type = parameterDefinition.ParameterType.GetActualType(); }
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) { if (nameComparer.Equals(identifierExpression.Identifier, from)) { identifierExpression.Identifier = to; } return base.VisitIdentifierExpression(identifierExpression, data); }
public void Run (RefactoringContext context) { var property = context.GetNode<PropertyDeclaration> (); string backingStoreName = context.GetNameProposal (property.Name); // create field var backingStore = new FieldDeclaration (); backingStore.ReturnType = property.ReturnType.Clone (); var initializer = new VariableInitializer (backingStoreName); backingStore.Variables.Add (initializer); // create new property & implement the get/set bodies var newProperty = (PropertyDeclaration)property.Clone (); var id1 = new IdentifierExpression (backingStoreName); var id2 = new IdentifierExpression (backingStoreName); newProperty.Getter.Body = new BlockStatement () { new ReturnStatement (id1) }; newProperty.Setter.Body = new BlockStatement () { new ExpressionStatement (new AssignmentExpression (id2, AssignmentOperatorType.Assign, new IdentifierExpression ("value"))) }; using (var script = context.StartScript ()) { script.Replace (property, newProperty); script.InsertBefore (property, backingStore); script.Link (initializer, id1, id2); } }
public PPPragmaNode(IdentifierExpression identifier, NodeCollection<ConstantExpression> value, PragmaAction action) : base(identifier.RelatedToken) { this.identifier = identifier; this.value = value; this.Action = action; }
public LocalDeclarationStatement(IType type, IdentifierExpression identifier, ExpressionNode rightSide) : base(identifier.RelatedToken) { this.type = type; this.identifiers.Expressions.Add(identifier); this.rightSide = rightSide; }
public string BuildExpression(Dictionary<string, Expression> selectExpressions) { var anonymousTypeCreateExpression = new AnonymousTypeCreateExpression(); var crrv = new ChangeRootReferenceVisitor(FromIdentifier); foreach (var curExpr in selectExpressions.OrderBy(x => x.Key)) { curExpr.Value.AcceptVisitor(crrv); anonymousTypeCreateExpression.Initializers.Add( new AssignmentExpression(new IdentifierExpression(curExpr.Key), curExpr.Value.Clone())); } if (FromExpression == null) FromExpression = new IdentifierExpression(); var queryExpr = new QueryExpression { Clauses = { new QueryFromClause { Identifier = "doc", Expression = FromExpression.Clone() }, new QuerySelectClause { Expression = anonymousTypeCreateExpression.Clone() } } }; FromIdentifier = "doc"; var printer = new StringWriter(); var printerVisitor = new CSharpOutputVisitor(printer, FormattingOptionsFactory.CreateSharpDevelop()); queryExpr.AcceptVisitor(printerVisitor); return printer.GetStringBuilder().ToString(); }
public static string ReplaceStringLiteralsWithVariables(string text, IEnumerable<string> macros, Func<int, int, string, string, string> onReplace) { var setting = new CompilerSettings(); foreach (var macro in macros) setting.ConditionalSymbols.Add(macro); var tree = SyntaxTree.Parse(text, string.Empty, setting); tree.Freeze(); var doc = new StringBuilderDocument(text); using (var editor = new DocumentScript(doc, FormattingOptionsFactory.CreateAllman(), TextEditorOptions.Default)) { var originDoc = editor.OriginalDocument; foreach (var node in tree.Descendants.OfType<PrimitiveExpression>().Where(e => e.Value is string)) { var line = originDoc.GetLineByNumber(node.StartLocation.Line); var result = onReplace(node.StartLocation.Line, node.StartLocation.Column, originDoc.GetText(line), node.Value as string); if (result != null) { var names = result.Split('.'); Expression exp = new IdentifierExpression(names.First()); foreach (var name in names.Skip(1)) exp = exp.Member(name); editor.Replace(node, exp); } } } return doc.Text; }
public override DVariable GetLocal(string LocalName, IdentifierExpression id = null) { foreach (var kv in Locals) if (kv.Key.Name == LocalName) return kv.Key; return null; }
ISemantic E(IdentifierExpression id, bool ImplicitlyExecute = true) { if (id.IsIdentifier) { var o = GetOverloads(id, ctxt); if (eval) { if (o == null || o.Length == 0) { EvalError(id, "Symbol could not be found"); return null; } return TryDoCTFEOrGetValueRefs(o, id, ImplicitlyExecute); } else { ctxt.CheckForSingleResult(o, id); if (o != null) if (o.Length == 1) return o[0]; else if (o.Length > 1) return new InternalOverloadValue(o); return null; } } else return EvaluateLiteral(id); }
static AstNode GenerateFieldDeclaration (RefactoringContext context, IdentifierExpression identifier) { return new FieldDeclaration () { ReturnType = GuessType (context, identifier), Variables = { new VariableInitializer (identifier.Identifier) } }; }
public void IdentifierExpressionProducesIdentifier() { var id = new IdentifierExpression("test"); Assert.AreEqual("test", id.Name); Assert.AreEqual("test", id.ToString(false)); }
CodeAction CreateFromExpression(RefactoringContext context, Expression expression) { var resolveResult = context.Resolve(expression); if (resolveResult.IsError) return null; return new CodeAction(context.TranslateString("Extract method"), script => { string methodName = "NewMethod"; var method = new MethodDeclaration() { ReturnType = context.CreateShortType(resolveResult.Type), Name = methodName, Body = new BlockStatement() { new ReturnStatement(expression.Clone()) } }; if (!StaticVisitor.UsesNotStaticMember(context, expression)) method.Modifiers |= Modifiers.Static; var task = script.InsertWithCursor(context.TranslateString("Extract method"), Script.InsertPosition.Before, method); Action<Task> replaceStatements = delegate { var target = new IdentifierExpression(methodName); script.Replace(expression, new InvocationExpression(target)); script.Link(target, method.NameToken); }; if (task.IsCompleted) { replaceStatements (null); } else { task.ContinueWith (replaceStatements, TaskScheduler.FromCurrentSynchronizationContext ()); } }); }
public void Run (RefactoringContext context) { var foreachStatement = GetForeachStatement (context); var result = context.ResolveType (foreachStatement.InExpression); var countProperty = GetCountProperty (result); var initializer = new VariableDeclarationStatement (new PrimitiveType ("int"), "i", new PrimitiveExpression (0)); var id1 = new IdentifierExpression ("i"); var id2 = id1.Clone (); var id3 = id1.Clone (); var forStatement = new ForStatement () { Initializers = { initializer }, Condition = new BinaryOperatorExpression (id1, BinaryOperatorType.LessThan, new MemberReferenceExpression (foreachStatement.InExpression.Clone (), countProperty)), Iterators = { new ExpressionStatement (new UnaryOperatorExpression (UnaryOperatorType.PostIncrement, id2)) }, EmbeddedStatement = new BlockStatement { new VariableDeclarationStatement (foreachStatement.VariableType.Clone (), foreachStatement.VariableName, new IndexerExpression (foreachStatement.InExpression.Clone (), id3)) } }; if (foreachStatement.EmbeddedStatement is BlockStatement) { foreach (var child in ((BlockStatement)foreachStatement.EmbeddedStatement).Statements) { forStatement.EmbeddedStatement.AddChild (child.Clone (), BlockStatement.StatementRole); } } else { forStatement.EmbeddedStatement.AddChild (foreachStatement.EmbeddedStatement.Clone (), BlockStatement.StatementRole); } using (var script = context.StartScript ()) { script.Replace (foreachStatement, forStatement); script.Link (initializer.Variables.First ().NameToken, id1, id2, id3); } }
public ISymbolValue Visit(IdentifierExpression id) { var ImplicitlyExecute = this.ImplicitlyExecute; this.ImplicitlyExecute = true; if (id.IsIdentifier) { var o = ExpressionTypeEvaluation.EvaluateTypes(id, ctxt); if (o == null || o.Length == 0) { EvalError(id, "Symbol could not be found"); return null; } return TryDoCTFEOrGetValueRefs(o, id, ImplicitlyExecute); } byte tt; switch (id.Format) { case Parser.LiteralFormat.CharLiteral: var tk = id.Subformat == LiteralSubformat.Utf32 ? DTokens.Dchar : id.Subformat == LiteralSubformat.Utf16 ? DTokens.Wchar : DTokens.Char; return new PrimitiveValue(tk, Convert.ToDecimal((int)(char)id.Value), id); case LiteralFormat.FloatingPoint | LiteralFormat.Scalar: var im = id.Subformat.HasFlag(LiteralSubformat.Imaginary); tt = im ? DTokens.Idouble : DTokens.Double; if (id.Subformat.HasFlag(LiteralSubformat.Float)) tt = im ? DTokens.Ifloat : DTokens.Float; else if (id.Subformat.HasFlag(LiteralSubformat.Real)) tt = im ? DTokens.Ireal : DTokens.Real; var v = Convert.ToDecimal(id.Value); return new PrimitiveValue(tt, im ? 0 : v, id, im ? v : 0); case LiteralFormat.Scalar: var unsigned = id.Subformat.HasFlag(LiteralSubformat.Unsigned); if (id.Subformat.HasFlag(LiteralSubformat.Long)) tt = unsigned ? DTokens.Ulong : DTokens.Long; else tt = unsigned ? DTokens.Uint : DTokens.Int; return new PrimitiveValue(tt, Convert.ToDecimal(id.Value), id); case Parser.LiteralFormat.StringLiteral: case Parser.LiteralFormat.VerbatimStringLiteral: return new ArrayValue(GetStringType(id.Subformat), id); default: return null; } }
/// <summary> /// String constructor. /// Given result stores both type and idenfitierexpression whose Value is used as content /// </summary> public ArrayValue(ArrayType stringLiteralResult, IdentifierExpression stringLiteral=null) : base(ExpressionValueType.Array, stringLiteralResult, stringLiteral) { if (stringLiteralResult.DeclarationOrExpressionBase is IdentifierExpression) StringValue = ((IdentifierExpression)stringLiteralResult.DeclarationOrExpressionBase).Value as string; else StringValue = stringLiteral.Value as string; }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { if (startLocation.IsEmpty || startLocation <= identifierExpression.StartLocation && identifierExpression.EndLocation <= endLocation) { var result = context.Resolve(identifierExpression); var local = result as LocalResolveResult; if (local != null && !UsedVariables.Contains(local.Variable)) UsedVariables.Add(local.Variable); } }
public void CastAndInvoke() { Expression expr = new IdentifierExpression("a") .CastTo(new PrimitiveType("string")) .Member("Length"); Assert.AreEqual("((string)a).Length", InsertRequired(expr)); Assert.AreEqual("((string)a).Length", InsertReadable(expr)); }
AstNode GeneratePropertyDeclaration (RefactoringContext context, IdentifierExpression identifier) { return new PropertyDeclaration () { ReturnType = CreateField.GuessType (context, identifier), Name = identifier.Identifier, Getter = new Accessor (), Setter = new Accessor () }; }
internal static AstType GuessType (RefactoringContext context, IdentifierExpression identifier) { if (identifier.Parent is AssignmentExpression) { var assign = (AssignmentExpression)identifier.Parent; var other = assign.Left == identifier ? assign.Right : assign.Left; return context.Resolve (other).Type.ConvertToAstType (); } return null; }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { base.VisitIdentifierExpression (identifierExpression); int length = identifierExpression.EndLocation.Column - identifierExpression.StartLocation.Column; int offset = identifierExpression.StartLocation.Column - 1; ReplaceType (identifierExpression.Identifier, offset, length); }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { if (!IsTargetOfInvocation(identifierExpression)) { var mgr = ctx.Resolve (identifierExpression) as MethodGroupResolveResult; if (mgr != null) UsedMethods.AddRange (mgr.Methods); } base.VisitIdentifierExpression(identifierExpression); }
public void IdentifierExpressionRefusesInvalidIdentifiers() { var id = new IdentifierExpression("Classname"); Assert.AreEqual("Classname", id.Name); id.Name = "Namespace"; Assert.AreEqual("Namespace", id.Name); Expect.Throw<ArgumentException>(() => id.Name = "Namespace.Classname"); }
public ISymbolValue this[IdentifierExpression id] { get { return this[GetLocal(id)]; } set { this[GetLocal(id)] = value; } }
CodeAction GetAction (RefactoringContext context, AstNode node, MethodDeclaration method) { return new CodeAction (context.TranslateString ("Extract anonymous method"), script => { var identifier = new IdentifierExpression ("Method"); script.Replace (node, identifier); script.InsertBefore (node.GetParent<EntityDeclaration> (), method); script.Link (method.NameToken, identifier); }); }
static VariableInitializer GetControlVariable(VariableDeclarationStatement variableDecl, UnaryOperatorExpression condition) { var controlVariables = variableDecl.Variables.Where ( v => { var identifier = new IdentifierExpression (v.Name); return condition.Expression.Match (identifier).Success; }).ToList (); return controlVariables.Count == 1 ? controlVariables [0] : null; }
/// <summary> /// String constructor. /// Given result stores both type and idenfitierexpression whose Value is used as content /// </summary> public ArrayValue(ArrayType stringLiteralResult, IdentifierExpression stringLiteral = null) : base(stringLiteralResult) { StringFormat = LiteralSubformat.Utf8; if (stringLiteralResult.DeclarationOrExpressionBase is IdentifierExpression) { StringFormat = ((IdentifierExpression)stringLiteralResult.DeclarationOrExpressionBase).Subformat; StringValue = ((IdentifierExpression)stringLiteralResult.DeclarationOrExpressionBase).StringValue; } else StringValue = stringLiteral.StringValue; }
public static AbstractType[] GetOverloads(IdentifierExpression id, ResolutionContext ctxt, bool deduceParameters = true) { var raw=TypeDeclarationResolver.ResolveIdentifier(id.ValueStringHash, ctxt, id, id.ModuleScoped); var f = DResolver.FilterOutByResultPriority(ctxt, raw); if(f==null) return null; return (ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0 && deduceParameters ? TemplateInstanceHandler.DeduceParamsAndFilterOverloads(f, null, false, ctxt) : f.ToArray(); }
public override IEnumerable<CodeAction> GetActions(RefactoringContext context) { var property = context.GetNode<PropertyDeclaration> (); if (property == null || !property.NameToken.Contains(context.Location)) yield break; if (!IsNotImplemented (context, property.Getter.Body) || !IsNotImplemented (context, property.Setter.Body)) { yield break; } yield return new CodeAction(context.TranslateString("Implement property"), script => { string backingStoreName = context.GetNameProposal (property.Name); // create field var backingStore = new FieldDeclaration (); if (property.Modifiers.HasFlag (Modifiers.Static)) backingStore.Modifiers |= Modifiers.Static; if (property.Setter.IsNull) backingStore.Modifiers |= Modifiers.Readonly; backingStore.ReturnType = property.ReturnType.Clone (); var initializer = new VariableInitializer (backingStoreName); backingStore.Variables.Add (initializer); // create new property & implement the get/set bodies var newProperty = (PropertyDeclaration)property.Clone (); Expression id1; if (backingStoreName == "value") id1 = new ThisReferenceExpression().Member("value"); else id1 = new IdentifierExpression (backingStoreName); Expression id2 = id1.Clone(); newProperty.Getter.Body = new BlockStatement () { new ReturnStatement (id1) }; if (!property.Setter.IsNull) { newProperty.Setter.Body = new BlockStatement () { new AssignmentExpression (id2, AssignmentOperatorType.Assign, new IdentifierExpression ("value")) }; } script.Replace (property, newProperty); script.InsertBefore (property, backingStore); if (!property.Setter.IsNull) script.Link (initializer, id1, id2); else script.Link (initializer, id1); }, property.NameToken); }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { var resolveResult = context.Resolve(identifierExpression); if (resolveResult is MemberResolveResult) { var memberResult = (MemberResolveResult)resolveResult; if (!memberResult.Member.IsStatic) UsesNonStaticMember = true; } else if (resolveResult is MethodGroupResolveResult) { var methodGroupResolveResult = (MethodGroupResolveResult)resolveResult; if (methodGroupResolveResult.Methods.Any(m => !m.IsStatic)) UsesNonStaticMember = true; } }
public IEnumerable<CodeAction> GetActions(RefactoringContext context) { var pexpr = context.GetNode<PrimitiveExpression>(); if (pexpr == null) yield break; var statement = context.GetNode<Statement>(); if (statement == null) { yield break; } var resolveResult = context.Resolve(pexpr); yield return new CodeAction(context.TranslateString("Create local constant"), script => { string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type); var service = (NamingConventionService)context.GetService(typeof(NamingConventionService)); if (service != null) name = service.CheckName(context, name, AffectedEntity.LocalConstant); var initializer = new VariableInitializer(name, pexpr.Clone()); var decl = new VariableDeclarationStatement() { Type = context.CreateShortType(resolveResult.Type), Modifiers = Modifiers.Const, Variables = { initializer } }; script.InsertBefore(statement, decl); var variableUsage = new IdentifierExpression(name); script.Replace(pexpr, variableUsage); script.Link(initializer.NameToken, variableUsage); }); yield return new CodeAction(context.TranslateString("Create constant field"), script => { string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type); var service = (NamingConventionService)context.GetService(typeof(NamingConventionService)); if (service != null) name = service.CheckName(context, name, AffectedEntity.ConstantField); var initializer = new VariableInitializer(name, pexpr.Clone()); var decl = new FieldDeclaration() { ReturnType = context.CreateShortType(resolveResult.Type), Modifiers = Modifiers.Const, Variables = { initializer } }; var variableUsage = new IdentifierExpression(name); script.Replace(pexpr, variableUsage); // script.Link(initializer.NameToken, variableUsage); script.InsertWithCursor(context.TranslateString("Create constant"), Script.InsertPosition.Before, decl); }); }
/// <summary> /// Visits an identifier expression. /// </summary> public virtual void Visit(IdentifierExpression expression) { }
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) { return(symbols.Contains(identifierExpression.Identifier)); }
/// <summary> /// Applies the transformation /// </summary> /// <returns>The transformed item.</returns> /// <param name="el">The item to visit.</param> public ASTItem Transform(ASTItem el) { var ss = el as SwitchStatement; if (ss == null) return el; var exptype = State.VHDLType(ss.SwitchExpression); // Extract expression types var targets = ss .Cases .SelectMany(x => x.Item1) .Where(x => x != null && !(x is EmptyExpression)) .Select(x => State.VHDLType(x)) .Distinct() .ToArray(); // Case where the expressions are all integer literals, // but the source is some numeric if (targets.Length == 1 && targets.First() != exptype) { var mp = ss.GetNearestParent<Method>(); if (mp != null) { var targettype = ss .Cases .SelectMany(x => x.Item1) .First(x => x != null && !(x is EmptyExpression)) .SourceResultType; // Create a variable the same type as the cases // and set it to the switch expression var nvar = State.RegisterTemporaryVariable(mp, targettype); State.TypeLookup[nvar] = targets.First(); var nvexp = new IdentifierExpression() { Name = nvar.Name, SourceExpression = ss.SwitchExpression.SourceExpression, SourceResultType = nvar.CecilType, Target = nvar }; var asss = new AST.ExpressionStatement() { Expression = new AST.AssignmentExpression() { Left = nvexp, Operator = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign, Right = ss.SwitchExpression, SourceExpression = ss.SwitchExpression.SourceExpression, SourceResultType = nvar.CecilType } }; ss.SwitchExpression = nvexp.Clone(); ss.SwitchExpression.Parent = ss; asss.UpdateParents(); ss.PrependStatement(asss); return null; } } return el; }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) { if (!IsTransparentIdentifier(fromClause.Identifier)) { return(false); } Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) { return(false); } QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); NamedExpression nae1 = match.Get <NamedExpression>("nae1").SingleOrDefault(); NamedExpression nae2 = match.Get <NamedExpression>("nae2").SingleOrDefault(); if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier) { return(false); } Expression nae2Expr = match.Get <Expression>("nae2Expr").Single(); IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression; if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) { // from * in (from x in ... select new { x = x, y = y }) ... // => // from x in ... ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause)); } } else { // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause)); } string ident; if (nae2 != null) { ident = nae2.Name; } else if (nae2Expr is MemberReferenceExpression) { ident = ((MemberReferenceExpression)nae2Expr).MemberName; } else { throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression"); } query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = ident, Expression = Detach(nae2Expr) }); } return(true); }
void ITreeWalker.Visit(IdentifierExpression expression) { expression.Validate(this); }
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(); IMethod method = methodIdent.Annotation <IMethod>(); if (method != null) { if (HandleAnonymousMethod(objectCreateExpression, obj, method)) { return(null); } var ilRanges = objectCreateExpression.GetAllRecursiveILRanges(); // 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.ResolveTypeDef() != context.CurrentType) { obj = new BaseReferenceExpression().WithAnnotation(method.DeclaringType); } } if (!annotation.IsVirtual && obj is NullReferenceExpression && method.MethodSig != null && !method.MethodSig.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; ITypeDefOrRef delegateType = objectCreateExpression.Type.Annotation <ITypeDefOrRef>(); if (delegateType != null) { TypeDef delegateTypeDef = delegateType.ResolveTypeDef(); if (delegateTypeDef != null) { MethodDef invokeMethod = delegateTypeDef.Methods.FirstOrDefault(m => m.Name == "Invoke"); if (invokeMethod != null) { isExtensionMethod = (invokeMethod.Parameters.GetNumberOfNormalParameters() + 1 == method.MethodSig.GetParameters().Count); } } } if (!isExtensionMethod) { obj = new TypeReferenceExpression { Type = AstBuilder.ConvertType(method.DeclaringType, stringBuilder) }; } } // now transform the identifier into a member reference MemberReferenceExpression mre = new MemberReferenceExpression(); mre.Target = obj; mre.MemberNameToken = (Identifier)methodIdent.IdentifierToken.Clone(); methodIdent.TypeArguments.MoveTo(mre.TypeArguments); mre.AddAnnotation(method); objectCreateExpression.Arguments.Clear(); objectCreateExpression.Arguments.Add(mre); objectCreateExpression.AddAnnotation(ilRanges); return(null); } } } return(base.VisitObjectCreateExpression(objectCreateExpression, data)); }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { HandleExpressionNode(identifierExpression); }
void ConvertForStatement(ForStatement forStatement) { // ForStatement -> ForNextStatement when for-loop is simple // only the following forms of the for-statement are allowed: // for (TypeReference name = start; name < oneAfterEnd; name += step) // for (name = start; name < oneAfterEnd; name += step) // for (TypeReference name = start; name <= end; name += step) // for (name = start; name <= end; name += step) // for (TypeReference name = start; name > oneAfterEnd; name -= step) // for (name = start; name > oneAfterEnd; name -= step) // for (TypeReference name = start; name >= end; name -= step) // for (name = start; name >= end; name -= step) // check if the form is valid and collect TypeReference, name, start, end and step if (forStatement.Initializers.Count != 1) { return; } if (forStatement.Iterator.Count != 1) { return; } ExpressionStatement statement = forStatement.Iterator[0] as ExpressionStatement; if (statement == null) { return; } AssignmentExpression iterator = statement.Expression as AssignmentExpression; if (iterator == null || (iterator.Op != AssignmentOperatorType.Add && iterator.Op != AssignmentOperatorType.Subtract)) { return; } IdentifierExpression iteratorIdentifier = iterator.Left as IdentifierExpression; if (iteratorIdentifier == null) { return; } PrimitiveExpression stepExpression = iterator.Right as PrimitiveExpression; if (stepExpression == null || !(stepExpression.Value is int)) { return; } int step = (int)stepExpression.Value; if (iterator.Op == AssignmentOperatorType.Subtract) { step = -step; } BinaryOperatorExpression condition = forStatement.Condition as BinaryOperatorExpression; if (condition == null || !(condition.Left is IdentifierExpression)) { return; } if ((condition.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier) { return; } Expression end; if (iterator.Op == AssignmentOperatorType.Subtract) { if (condition.Op == BinaryOperatorType.GreaterThanOrEqual) { end = condition.Right; } else if (condition.Op == BinaryOperatorType.GreaterThan) { end = Expression.AddInteger(condition.Right, 1); } else { return; } } else { if (condition.Op == BinaryOperatorType.LessThanOrEqual) { end = condition.Right; } else if (condition.Op == BinaryOperatorType.LessThan) { end = Expression.AddInteger(condition.Right, -1); } else { return; } } Expression start; TypeReference typeReference = null; LocalVariableDeclaration varDecl = forStatement.Initializers[0] as LocalVariableDeclaration; if (varDecl != null) { if (varDecl.Variables.Count != 1 || varDecl.Variables[0].Name != iteratorIdentifier.Identifier || varDecl.Variables[0].Initializer == null) { return; } typeReference = varDecl.GetTypeForVariable(0); start = varDecl.Variables[0].Initializer; } else { statement = forStatement.Initializers[0] as ExpressionStatement; if (statement == null) { return; } AssignmentExpression assign = statement.Expression as AssignmentExpression; if (assign == null || assign.Op != AssignmentOperatorType.Assign) { return; } if (!(assign.Left is IdentifierExpression)) { return; } if ((assign.Left as IdentifierExpression).Identifier != iteratorIdentifier.Identifier) { return; } start = assign.Right; } ReplaceCurrentNode(new ForNextStatement(typeReference, iteratorIdentifier.Identifier, start, end, (step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)), forStatement.EmbeddedStatement, null)); }
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; } TypeDef type = variable.Type.ToTypeDefOrRef().ResolveWithinSameModule(); if (!IsPotentialClosure(context, type)) { continue; } if (displayClassAssignmentMatch.Get <AstType>("type").Single().Annotation <ITypeDefOrRef>().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 <IField>() != null && identExpr.Parent.Annotation <IField>().IsField)) { ok = false; } } } if (!ok) { continue; } Dictionary <IField, AstNode> dict = new Dictionary <IField, AstNode>(); // Delete the variable declaration statement: VariableDeclarationStatement displayClassVarDecl = PatternStatementTransform.FindVariableDeclaration(stmt, variable.Name); if (displayClassVarDecl != null) { displayClassVarDecl.Remove(); //TODO: Save ILRanges } // Delete the assignment statement: AstNode cur = stmt.NextSibling; stmt.Remove(); //TODO: Save ILRanges // 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 = IdentifierExpression.Create(variable.Name, variable.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local), MemberName = Pattern.AnyString }), new AnyNode("right") ) ); Match m = closureFieldAssignmentPattern.Match(cur); if (m.Success) { FieldDef fieldDef = m.Get <MemberReferenceExpression>("left").Single().Annotation <IField>().ResolveFieldWithinSameModule(); 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.ToTypeDefOrRef().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 FieldDef fieldDef2 = mre.Annotation <FieldDef>().ResolveFieldWithinSameModule(); if (fieldDef2 == null || !IsPotentialClosure(context, fieldDef2.FieldType.ToTypeDefOrRef().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) { if (fieldDef != null) { dict[fieldDef] = right; } cur.Remove(); //TODO: Save ILRanges } 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 (FieldDef 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 { GeneratedByDecompiler = true, Name = capturedVariableName, Type = field.FieldType, }; variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, stringBuilder, field), ilVar)); dict[field] = IdentifierExpression.Create(capturedVariableName, TextTokenKind.Local).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; var fieldDef = mre.Annotation <IField>().ResolveFieldWithinSameModule(); if (fieldDef != null && dict.TryGetValue(fieldDef, out replacement)) { var newReplacement = replacement.Clone(); newReplacement.AddAnnotation(mre.GetAllRecursiveILRanges()); mre.ReplaceWith(newReplacement); } } } // 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.Item2.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local, tuple.Item1, tuple.Item2.Name); newVarDecl.Variables.Single().AddAnnotation(CapturedVariableAnnotation.Instance); newVarDecl.Variables.Single().AddAnnotation(tuple.Item2); blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl); } } currentlyUsedVariableNames.RemoveRange(numberOfVariablesOutsideBlock, currentlyUsedVariableNames.Count - numberOfVariablesOutsideBlock); return(null); }
string WhereString(OqlExpression thisExpression) { StringBuilder sb = new StringBuilder(); if (thisExpression.IsTerminating || thisExpression is IdentifierExpression) { if (thisExpression.UnaryOp != null) { sb.Append(thisExpression.UnaryOp); sb.Append(' '); } if (thisExpression.Value.GetType().IsPrimitive) { sb.Append(Convert.ToString(thisExpression.Value, CultureInfo.InvariantCulture)); } else { IdentifierExpression iexp = thisExpression as IdentifierExpression; if (iexp != null) { sb.Append(iexp.GetAnnotation <string>(anKey)); } else { sb.Append(thisExpression.Value.ToString()); } } } else { if (thisExpression.UnaryOp != null) { sb.Append(thisExpression.UnaryOp); sb.Append(' '); } if (thisExpression is FunctionExpression) { sb.Append(thisExpression.Value); } if (thisExpression.HasBrackets) { sb.Append('('); } string op1 = thisExpression.Operator; int childExpEndIndex = thisExpression.Children.Count - 1; for (int i = 0; i <= childExpEndIndex; i++) { OqlExpression child = thisExpression.Children[i]; sb.Append(WhereString(child)); if (i < childExpEndIndex) { if (op1 != ",") { sb.Append(' '); } sb.Append(op1); if (op1 == "BETWEEN") { op1 = "AND"; } sb.Append(' '); } } if (thisExpression.HasBrackets) { sb.Append(')'); } } return(sb.ToString()); }
public override IEnumerable <CodeAction> GetActions(RefactoringContext context) { bool hasIndexAccess; var foreachStatement = GetForeachStatement(context, out hasIndexAccess); if (foreachStatement == null || foreachStatement.EmbeddedStatement == null) { yield break; } var state = context.GetResolverStateBefore(foreachStatement.EmbeddedStatement); string name = GetName(state, VariableNames); if (name == null) // very unlikely, but just in case ... { yield break; } yield return(new CodeAction(context.TranslateString("Convert 'foreach' loop to 'for'"), script => { var result = context.Resolve(foreachStatement.InExpression); var countProperty = GetCountProperty(result.Type); var inExpression = foreachStatement.InExpression; var initializer = hasIndexAccess ? new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0)) : new VariableDeclarationStatement(new SimpleType("var"), name, new InvocationExpression(new MemberReferenceExpression(inExpression.Clone(), "GetEnumerator"))); var id1 = new IdentifierExpression(name); var id2 = id1.Clone(); var id3 = id1.Clone(); Statement declarationStatement = null; if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression) { string listName = GetName(state, CollectionNames) ?? "col"; declarationStatement = new VariableDeclarationStatement( new PrimitiveType("var"), listName, inExpression.Clone() ); inExpression = new IdentifierExpression(listName); } var variableDeclarationStatement = new VariableDeclarationStatement( foreachStatement.VariableType.Clone(), foreachStatement.VariableName, hasIndexAccess ? (Expression) new IndexerExpression(inExpression.Clone(), id3) : new MemberReferenceExpression(id1, "Current") ); var forStatement = new ForStatement { Initializers = { initializer }, Condition = hasIndexAccess ? (Expression) new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new MemberReferenceExpression(inExpression.Clone(), countProperty)) : new InvocationExpression(new MemberReferenceExpression(id2, "MoveNext")), EmbeddedStatement = new BlockStatement { variableDeclarationStatement } }; if (hasIndexAccess) { forStatement.Iterators.Add(new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2)); } if (foreachStatement.EmbeddedStatement is BlockStatement) { variableDeclarationStatement.Remove(); var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone(); if (oldBlock.Statements.Any()) { oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement); } else { oldBlock.Statements.Add(variableDeclarationStatement); } forStatement.EmbeddedStatement = oldBlock; } else { forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole); } if (declarationStatement != null) { script.InsertBefore(foreachStatement, declarationStatement); } script.Replace(foreachStatement, forStatement); if (hasIndexAccess) { script.Link(initializer.Variables.First().NameToken, id1, id2, id3); } else { script.Link(initializer.Variables.First().NameToken, id1, id2); } }, foreachStatement)); if (!hasIndexAccess) { yield break; } yield return(new CodeAction(context.TranslateString("Convert 'foreach' loop to optimized 'for'"), script => { var result = context.Resolve(foreachStatement.InExpression); var countProperty = GetCountProperty(result.Type); var initializer = new VariableDeclarationStatement(new PrimitiveType("int"), name, new PrimitiveExpression(0)); var id1 = new IdentifierExpression(name); var id2 = id1.Clone(); var id3 = id1.Clone(); var inExpression = foreachStatement.InExpression; Statement declarationStatement = null; if (inExpression is ObjectCreateExpression || inExpression is ArrayCreateExpression) { string listName = GetName(state, CollectionNames) ?? "col"; declarationStatement = new VariableDeclarationStatement( new PrimitiveType("var"), listName, inExpression.Clone() ); inExpression = new IdentifierExpression(listName); } var variableDeclarationStatement = new VariableDeclarationStatement( foreachStatement.VariableType.Clone(), foreachStatement.VariableName, new IndexerExpression(inExpression.Clone(), id3) ); string optimizedUpperBound = GetBoundName(inExpression) + countProperty; initializer.Variables.Add(new VariableInitializer(optimizedUpperBound, new MemberReferenceExpression(inExpression.Clone(), countProperty))); var forStatement = new ForStatement { Initializers = { initializer }, Condition = new BinaryOperatorExpression(id1, BinaryOperatorType.LessThan, new IdentifierExpression(optimizedUpperBound)), Iterators = { new UnaryOperatorExpression(UnaryOperatorType.PostIncrement, id2) }, EmbeddedStatement = new BlockStatement { variableDeclarationStatement } }; if (foreachStatement.EmbeddedStatement is BlockStatement) { variableDeclarationStatement.Remove(); var oldBlock = (BlockStatement)foreachStatement.EmbeddedStatement.Clone(); if (oldBlock.Statements.Any()) { oldBlock.Statements.InsertBefore(oldBlock.Statements.First(), variableDeclarationStatement); } else { oldBlock.Statements.Add(variableDeclarationStatement); } forStatement.EmbeddedStatement = oldBlock; } else { forStatement.EmbeddedStatement.AddChild(foreachStatement.EmbeddedStatement.Clone(), BlockStatement.StatementRole); } if (declarationStatement != null) { script.InsertBefore(foreachStatement, declarationStatement); } script.Replace(foreachStatement, forStatement); script.Link(initializer.Variables.First().NameToken, id1, id2, id3); }, foreachStatement)); }