string GetValue(ResolveResult value) { var astBuilder = new TypeSystemAstBuilder(); Expression ast = astBuilder.ConvertConstantValue(value); return(ast.ToString()); }
public static void WriteResolveResult(ResolveResult rr, AbstractEmitterBlock block) { if (rr is ConversionResolveResult) { rr = ((ConversionResolveResult)rr).Input; } if (rr is TypeOfResolveResult) { block.Write(H5Types.ToJsName(((TypeOfResolveResult)rr).ReferencedType, block.Emitter)); } else if (rr is ArrayCreateResolveResult) { TypeSystemAstBuilder typeBuilder = new TypeSystemAstBuilder(new CSharpResolver(block.Emitter.Resolver.Compilation)); var expression = typeBuilder.ConvertConstantValue(rr) as ArrayCreateExpression; new ArrayCreateBlock(block.Emitter, expression, (ArrayCreateResolveResult)rr).Emit(); } else if (rr is MemberResolveResult mrr) { if (mrr.IsCompileTimeConstant && mrr.Member.DeclaringType.Kind == TypeKind.Enum) { if (mrr.Member.DeclaringType is DefaultResolvedTypeDefinition typeDef) { var enumMode = Helpers.EnumEmitMode(typeDef); if ((block.Emitter.Validator.IsExternalType(typeDef) && enumMode == -1) || enumMode == 2) { block.WriteScript(mrr.ConstantValue); return; } if (enumMode >= 3 && enumMode < 7) { string enumStringName = mrr.Member.Name; var attr = Helpers.GetInheritedAttribute(mrr.Member, Translator.H5_ASSEMBLY + ".NameAttribute"); if (attr != null) { enumStringName = block.Emitter.GetEntityName(mrr.Member); } else { switch (enumMode) { case 3: enumStringName = Object.Net.Utilities.StringUtils.ToLowerCamelCase(mrr.Member.Name); break; case 4: break; case 5: enumStringName = enumStringName.ToLowerInvariant(); break; case 6: enumStringName = enumStringName.ToUpperInvariant(); break; } } block.WriteScript(enumStringName); } else { block.WriteScript(rr.ConstantValue); } } } else { block.WriteScript(rr.ConstantValue); } } else { block.WriteScript(rr.ConstantValue); } }
public void ConvertSymbol(ISymbol symbol, TokenWriter writer, CSharpFormattingOptions formattingPolicy) { if (symbol == null) { throw new ArgumentNullException(nameof(symbol)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (formattingPolicy == null) { throw new ArgumentNullException(nameof(formattingPolicy)); } TypeSystemAstBuilder astBuilder = CreateAstBuilder(); AstNode node = astBuilder.ConvertSymbol(symbol); writer.StartNode(node); EntityDeclaration entityDecl = node as EntityDeclaration; if (entityDecl != null) { PrintModifiers(entityDecl.Modifiers, writer); } if ((ConversionFlags & ConversionFlags.ShowDefinitionKeyword) == ConversionFlags.ShowDefinitionKeyword) { if (node is TypeDeclaration) { switch (((TypeDeclaration)node).ClassType) { case ClassType.Class: writer.WriteKeyword(Roles.ClassKeyword, "class"); break; case ClassType.Struct: writer.WriteKeyword(Roles.StructKeyword, "struct"); break; case ClassType.Interface: writer.WriteKeyword(Roles.InterfaceKeyword, "interface"); break; case ClassType.Enum: writer.WriteKeyword(Roles.EnumKeyword, "enum"); break; case ClassType.RecordClass: writer.WriteKeyword(Roles.RecordKeyword, "record"); break; default: throw new Exception("Invalid value for ClassType"); } writer.Space(); } else if (node is DelegateDeclaration) { writer.WriteKeyword(Roles.DelegateKeyword, "delegate"); writer.Space(); } else if (node is EventDeclaration) { writer.WriteKeyword(EventDeclaration.EventKeywordRole, "event"); writer.Space(); } else if (node is NamespaceDeclaration) { writer.WriteKeyword(Roles.NamespaceKeyword, "namespace"); writer.Space(); } } if ((ConversionFlags & ConversionFlags.PlaceReturnTypeAfterParameterList) != ConversionFlags.PlaceReturnTypeAfterParameterList && (ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType) { var rt = node.GetChildByRole(Roles.Type); if (!rt.IsNull) { rt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); writer.Space(); } } if (symbol is ITypeDefinition) { WriteTypeDeclarationName((ITypeDefinition)symbol, writer, formattingPolicy); } else if (symbol is IMember) { WriteMemberDeclarationName((IMember)symbol, writer, formattingPolicy); } else { writer.WriteIdentifier(Identifier.Create(symbol.Name)); } if ((ConversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList && HasParameters(symbol)) { writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.LBracket : Roles.LPar, symbol.SymbolKind == SymbolKind.Indexer ? "[" : "("); bool first = true; foreach (var param in node.GetChildrenByRole(Roles.Parameter)) { if ((ConversionFlags & ConversionFlags.ShowParameterModifiers) == 0) { param.ParameterModifier = ParameterModifier.None; } if ((ConversionFlags & ConversionFlags.ShowParameterDefaultValues) == 0) { param.DefaultExpression.Detach(); } if (first) { first = false; } else { writer.WriteToken(Roles.Comma, ","); writer.Space(); } param.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); } writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.RBracket : Roles.RPar, symbol.SymbolKind == SymbolKind.Indexer ? "]" : ")"); } if ((ConversionFlags & ConversionFlags.PlaceReturnTypeAfterParameterList) == ConversionFlags.PlaceReturnTypeAfterParameterList && (ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType) { var rt = node.GetChildByRole(Roles.Type); if (!rt.IsNull) { writer.Space(); writer.WriteToken(Roles.Colon, ":"); writer.Space(); if (symbol is IField f && CSharpDecompiler.IsFixedField(f, out var type, out int elementCount)) { rt = astBuilder.ConvertType(type); new IndexerExpression(new TypeReferenceExpression(rt), astBuilder.ConvertConstantValue(f.Compilation.FindType(KnownTypeCode.Int32), elementCount)) .AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); } else { rt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); } } }
/// <summary> Get the value of the node and update the UI text fields. </summary> /// <remarks> This should be only called once so the Value is not cached. </remarks> void GetValueAndUpdateUI() { try { Stopwatch watch = new Stopwatch(); watch.Start(); // Do not keep permanent reference Value val = this.getValue(); if (val == null) { Value = string.Empty; Type = string.Empty; GetChildren = null; VisualizerCommands = null; return; } // Note that the child collections are lazy-evaluated if (val.IsNull) { this.GetChildren = null; } else if (val.Type.IsPrimitiveType() || val.Type.IsKnownType(KnownTypeCode.String)) // Must be before IsClass { this.GetChildren = null; } else if (val.Type.Kind == TypeKind.Array) // Must be before IsClass { var dimBase = val.ArrayBaseIndicies; // Eval now var dimSize = val.ArrayDimensions; // Eval now if (val.ArrayLength > 0) { this.GetChildren = () => GetArrayChildren(dimBase, dimSize); } } else if (val.Type.Kind == TypeKind.Class || val.Type.Kind == TypeKind.Struct) { if (val.Type.IsKnownType(typeof(List <>))) { if ((int)val.GetFieldValue("_size").PrimitiveValue > 0) { this.GetChildren = () => GetIListChildren(this.GetValue); } } else { this.GetChildren = () => GetObjectChildren(val.Type); } } else if (val.Type.Kind == TypeKind.Pointer) { if (val.Dereference() != null) { this.GetChildren = () => new[] { new ValueNode(ClassBrowserIconService.LocalVariable, "*" + this.Name, () => GetValue().Dereference()) }; } } // Do last since it may expire the object if (val.IsNull) { fullValue = "null"; } else if (val.Type.IsInteger()) { var i = val.PrimitiveValue; if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Decimal) { fullValue = i.ToString(); } else { string hex = string.Format("0x{0:X4}", i); if (hex.Length > 6) { hex = string.Format("0x{0:X8}", i); } if (hex.Length > 10) { hex = string.Format("0x{0:X16}", i); } if (DebuggingOptions.Instance.ShowIntegersAs == ShowIntegersAs.Hexadecimal) { fullValue = hex; } else { fullValue = string.Format("{0} ({1})", i, hex); } } } else if (val.Type.Kind == TypeKind.Pointer) { fullValue = String.Format("0x{0:X}", val.PointerAddress); } else if (val.Type.IsKnownType(KnownTypeCode.String)) { fullValue = '"' + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + '"'; } else if (val.Type.IsKnownType(KnownTypeCode.Char)) { fullValue = "'" + val.InvokeToString(WindowsDebugger.EvalThread).Replace("\n", "\\n").Replace("\t", "\\t").Replace("\r", "\\r").Replace("\0", "\\0").Replace("\b", "\\b").Replace("\a", "\\a").Replace("\f", "\\f").Replace("\v", "\\v").Replace("\"", "\\\"") + "'"; } else if ((val.Type.Kind == TypeKind.Class || val.Type.Kind == TypeKind.Struct)) { fullValue = val.FormatByDebuggerDisplayAttribute(WindowsDebugger.EvalThread); if (fullValue == null) { fullValue = val.InvokeToString(WindowsDebugger.EvalThread); } } else if (val.Type.Kind == TypeKind.Enum) { var primitiveValue = val.PrimitiveValue; var builder = new TypeSystemAstBuilder(); builder.AlwaysUseShortTypeNames = true; AstNode node = builder.ConvertConstantValue(val.Type, primitiveValue); fullValue = node + "=" + primitiveValue; } else { fullValue = val.AsString(); } this.error = null; this.Value = (fullValue.Length > 256) ? fullValue.Substring(0, 256) + "..." : fullValue; this.Type = val.Type.Name; if (!val.IsNull) { this.VisualizerCommands = VisualizerDescriptors.GetAllDescriptors() .Where(descriptor => descriptor.IsVisualizerAvailable(val.Type)) .Select(descriptor => descriptor.CreateVisualizerCommand(this.Name, this.GetValue)) .ToList(); } LoggingService.InfoFormatted("Evaluated node '{0}' in {1} ms", this.Name, watch.ElapsedMilliseconds); } catch (GetValueException e) { error = e; this.Value = e.Message; this.Type = string.Empty; this.GetChildren = null; this.VisualizerCommands = null; } finally { if (error == null) { ContextMenuAddInTreeEntry = "/AddIns/Debugger/Tooltips/ContextMenu/ValueNode"; } else { ContextMenuAddInTreeEntry = "/AddIns/Debugger/Tooltips/ContextMenu/ErrorNode"; } } }