[closes gh-124] Moved IL comments to a tooltip + base work for MirrorSharp infotips.
This commit is contained in:
Родитель
20bee87b2b
Коммит
1f37f4a282
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using Mono.Cecil;
|
||||
|
@ -15,7 +12,7 @@ namespace SharpLab.Server.Decompilation {
|
|||
var output = new CustomizableIndentPlainTextOutput(codeWriter) {
|
||||
IndentationString = " "
|
||||
};
|
||||
var disassembler = new ReflectionDisassembler(new ILCommentingTextOutput(output, 30), false, new CancellationToken());
|
||||
var disassembler = new ReflectionDisassembler(output, false, CancellationToken.None);
|
||||
disassembler.WriteModuleContents(assembly.MainModule);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,305 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AshMind.Extensions;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.NRefactory;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
namespace SharpLab.Server.Decompilation.Internal {
|
||||
public class ILCommentingTextOutput : ITextOutput {
|
||||
private readonly ITextOutput _inner;
|
||||
private readonly int _commentMinColumn;
|
||||
|
||||
private int _currentLineLength;
|
||||
private string _curentComment;
|
||||
|
||||
public ILCommentingTextOutput(ITextOutput inner, int commentMinColumn) {
|
||||
if (inner == null)
|
||||
throw new ArgumentNullException(nameof(inner));
|
||||
|
||||
_inner = inner;
|
||||
_commentMinColumn = commentMinColumn;
|
||||
}
|
||||
|
||||
public TextLocation Location => _inner.Location;
|
||||
|
||||
public void Indent() {
|
||||
_inner.Indent();
|
||||
}
|
||||
|
||||
public void Unindent() {
|
||||
_inner.Unindent();
|
||||
}
|
||||
|
||||
public void Write(char ch) {
|
||||
_inner.Write(ch);
|
||||
_currentLineLength += 1;
|
||||
}
|
||||
|
||||
public void Write(string text) {
|
||||
_inner.Write(text);
|
||||
_currentLineLength += text.Length;
|
||||
}
|
||||
|
||||
public void WriteLine() {
|
||||
WriteComment();
|
||||
_inner.WriteLine();
|
||||
_currentLineLength = 0;
|
||||
}
|
||||
|
||||
public void WriteDefinition(string text, object definition, bool isLocal = true) {
|
||||
_inner.WriteDefinition(text, definition, isLocal);
|
||||
_currentLineLength += text.Length;
|
||||
}
|
||||
|
||||
public void WriteReference(string text, object reference, bool isLocal = false) {
|
||||
UpdateCurrentCommentFrom(reference);
|
||||
_inner.WriteReference(text, reference, isLocal);
|
||||
_currentLineLength += text.Length;
|
||||
}
|
||||
|
||||
void ITextOutput.MarkFoldStart(string collapsedText, bool defaultCollapsed) => _inner.MarkFoldStart(collapsedText, defaultCollapsed);
|
||||
void ITextOutput.MarkFoldEnd() => _inner.MarkFoldEnd();
|
||||
void ITextOutput.AddDebuggerMemberMapping(MemberMapping memberMapping) => _inner.AddDebuggerMemberMapping(memberMapping);
|
||||
|
||||
private void UpdateCurrentCommentFrom(object reference) {
|
||||
if (!(reference is OpCode))
|
||||
return;
|
||||
|
||||
var comment = Comments.GetValueOrDefault((OpCode)reference);
|
||||
if (comment != null)
|
||||
_curentComment = comment;
|
||||
}
|
||||
|
||||
private void WriteComment() {
|
||||
if (_curentComment == null)
|
||||
return;
|
||||
|
||||
_inner.Write(new string(' ', Math.Max(_commentMinColumn - _currentLineLength, 1)));
|
||||
_inner.Write($"// {_curentComment}");
|
||||
_curentComment = null;
|
||||
}
|
||||
|
||||
private static readonly IReadOnlyDictionary<OpCode, string> Comments = new Dictionary<OpCode, string> {
|
||||
[OpCodes.Add] = "Add two values, returning a new value",
|
||||
[OpCodes.Add_Ovf] = "Add signed integer values with overflow check",
|
||||
[OpCodes.Add_Ovf_Un] = "Add unsigned integer values with overflow check",
|
||||
[OpCodes.And] = "Bitwise AND of two integral values, returns an integral value",
|
||||
[OpCodes.Arglist] = "Return argument list handle for the current method",
|
||||
[OpCodes.Beq] = "Branch to target if equal",
|
||||
[OpCodes.Beq_S] = "Branch to target if equal, short form",
|
||||
[OpCodes.Bge] = "Branch to target if greater than or equal to",
|
||||
[OpCodes.Bge_S] = "Branch to target if greater than or equal to, short form",
|
||||
[OpCodes.Bge_Un] = "Branch to target if greater than or equal to (unsigned or unordered)",
|
||||
[OpCodes.Bge_Un_S] = "Branch to target if greater than or equal to (unsigned or unordered), short form",
|
||||
[OpCodes.Bgt] = "Branch to target if greater than",
|
||||
[OpCodes.Bgt_S] = "Branch to target if greater than, short form",
|
||||
[OpCodes.Bgt_Un] = "Branch to target if greater than (unsigned or unordered)",
|
||||
[OpCodes.Bgt_Un_S] = "Branch to target if greater than (unsigned or unordered), short form",
|
||||
[OpCodes.Ble] = "Branch to target if less than or equal to",
|
||||
[OpCodes.Ble_S] = "Branch to target if less than or equal to, short form",
|
||||
[OpCodes.Ble_Un] = "Branch to target if less than or equal to (unsigned or unordered)",
|
||||
[OpCodes.Ble_Un_S] = "Branch to target if less than or equal to (unsigned or unordered), short form",
|
||||
[OpCodes.Blt] = "Branch to target if less than",
|
||||
[OpCodes.Blt_S] = "Branch to target if less than, short form",
|
||||
[OpCodes.Blt_Un] = "Branch to target if less than (unsigned or unordered)",
|
||||
[OpCodes.Blt_Un_S] = "Branch to target if less than (unsigned or unordered), short form",
|
||||
[OpCodes.Bne_Un] = "Branch to target if unequal or unordered",
|
||||
[OpCodes.Bne_Un_S] = "Branch to target if unequal or unordered, short form",
|
||||
[OpCodes.Box] = "Convert a boxable value to its boxed form",
|
||||
[OpCodes.Br] = "Branch to target",
|
||||
[OpCodes.Br_S] = "Branch to target, short form",
|
||||
[OpCodes.Break] = "Inform a debugger that a breakpoint has been reached",
|
||||
[OpCodes.Brfalse] = "Branch to target if value is zero (false)",
|
||||
[OpCodes.Brfalse_S] = "Branch to target if value is zero (false), short form",
|
||||
[OpCodes.Brtrue] = "Branch to target if value is non-zero (true)",
|
||||
[OpCodes.Brtrue_S] = "Branch to target if value is non-zero (true), short form",
|
||||
[OpCodes.Call] = "Call method",
|
||||
[OpCodes.Call] = "Call method indicated on the stack with arguments",
|
||||
[OpCodes.Callvirt] = "Call a method associated with an object",
|
||||
[OpCodes.Castclass] = "Cast obj to class",
|
||||
[OpCodes.Ceq] = "Push 1 (of type int32) if value1 equals value2, else push 0",
|
||||
[OpCodes.Cgt] = "Push 1 (of type int32) if value1 > value2, else push 0",
|
||||
[OpCodes.Cgt_Un] = "Push 1 (of type int32) if value1 > value2, unsigned or unordered, else push 0",
|
||||
[OpCodes.Ckfinite] = "Throw ArithmeticException if value is not a finite number",
|
||||
[OpCodes.Clt] = "Push 1 (of type int32) if value1 < value2, else push 0",
|
||||
[OpCodes.Clt_Un] = "Push 1 (of type int32) if value1 < value2, unsigned or unordered, else push 0",
|
||||
[OpCodes.Constrained] = "Call a virtual method on a type constrained to be type T",
|
||||
[OpCodes.Conv_I] = "Convert to native int, pushing native int on stack",
|
||||
[OpCodes.Conv_I1] = "Convert to int8, pushing int32 on stack",
|
||||
[OpCodes.Conv_I2] = "Convert to int16, pushing int32 on stack",
|
||||
[OpCodes.Conv_I4] = "Convert to int32, pushing int32 on stack",
|
||||
[OpCodes.Conv_I8] = "Convert to int64, pushing int64 on stack",
|
||||
[OpCodes.Conv_Ovf_I] = "Convert to a native int (on the stack as native int) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I_Un] = "Convert unsigned to a native int (on the stack as native int) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I1] = "Convert to an int8 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I1_Un] = "Convert unsigned to an int8 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I2] = "Convert to an int16 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I2_Un] = "Convert unsigned to an int16 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I4] = "Convert to an int32 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I4_Un] = "Convert unsigned to an int32 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I8] = "Convert to an int64 (on the stack as int64) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_I8_Un] = "Convert unsigned to an int64 (on the stack as int64) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U] = "Convert to a native unsigned int (on the stack as native int) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U_Un] = "Convert unsigned to a native unsigned int (on the stack as native int) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U1] = "Convert to an unsigned int8 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U1_Un] = "Convert unsigned to an unsigned int8 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U2] = "Convert to an unsigned int16 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U2_Un] = "Convert unsigned to an unsigned int16 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U4] = "Convert to an unsigned int32 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U4_Un] = "Convert unsigned to an unsigned int32 (on the stack as int32) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U8] = "Convert to an unsigned int64 (on the stack as int64) and throw an exception on overflow",
|
||||
[OpCodes.Conv_Ovf_U8_Un] = "Convert unsigned to an unsigned int64 (on the stack as int64) and throw an exception on overflow",
|
||||
[OpCodes.Conv_R_Un] = "Convert unsigned integer to floating-point, pushing F on stack",
|
||||
[OpCodes.Conv_R4] = "Convert to float32, pushing F on stack",
|
||||
[OpCodes.Conv_R8] = "Convert to float64, pushing F on stack",
|
||||
[OpCodes.Conv_U] = "Convert to native unsigned int, pushing native int on stack",
|
||||
[OpCodes.Conv_U1] = "Convert to unsigned int8, pushing int32 on stack",
|
||||
[OpCodes.Conv_U2] = "Convert to unsigned int16, pushing int32 on stack",
|
||||
[OpCodes.Conv_U4] = "Convert to unsigned int32, pushing int32 on stack",
|
||||
[OpCodes.Conv_U8] = "Convert to unsigned int64, pushing int64 on stack",
|
||||
[OpCodes.Cpblk] = "Copy data from memory to memory",
|
||||
[OpCodes.Cpobj] = "Copy a value type from src to dest",
|
||||
[OpCodes.Div] = "Divide two values to return a quotient or floating-point result",
|
||||
[OpCodes.Div_Un] = "Divide two values, unsigned, returning a quotient",
|
||||
[OpCodes.Dup] = "Duplicate the value on the top of the stack",
|
||||
[OpCodes.Endfilter] = "End an exception handling filter clause",
|
||||
[OpCodes.Endfinally] = "End finally clause of an exception block",
|
||||
[OpCodes.Initblk] = "Set all bytes in a block of memory to a given byte value",
|
||||
[OpCodes.Initobj] = "Initialize the value at address dest",
|
||||
[OpCodes.Isinst] = "Test if obj is an instance of class, returning null or an instance of that class or interface",
|
||||
[OpCodes.Jmp] = "Exit current method and jump to the specified method",
|
||||
[OpCodes.Ldarg] = "Load argument numbered num onto the stack",
|
||||
[OpCodes.Ldarg_0] = "Load argument 0 onto the stack",
|
||||
[OpCodes.Ldarg_1] = "Load argument 1 onto the stack",
|
||||
[OpCodes.Ldarg_2] = "Load argument 2 onto the stack",
|
||||
[OpCodes.Ldarg_3] = "Load argument 3 onto the stack",
|
||||
[OpCodes.Ldarg_S] = "Load argument numbered num onto the stack, short form",
|
||||
[OpCodes.Ldarga] = "Fetch the address of argument argNum",
|
||||
[OpCodes.Ldarga_S] = "Fetch the address of argument argNum, short form",
|
||||
[OpCodes.Ldc_I4] = "Push num of type int32 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_0] = "Push 0 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_1] = "Push 1 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_2] = "Push 2 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_3] = "Push 3 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_4] = "Push 4 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_5] = "Push 5 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_6] = "Push 6 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_7] = "Push 7 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_8] = "Push 8 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_M1] = "Push -1 onto the stack as int32",
|
||||
[OpCodes.Ldc_I4_S] = "Push num onto the stack as int32, short form",
|
||||
[OpCodes.Ldc_I8] = "Push num of type int64 onto the stack as int64",
|
||||
[OpCodes.Ldc_R4 ] = "Push num of type float32 onto the stack as F",
|
||||
[OpCodes.Ldc_R8] = "Push num of type float64 onto the stack as F",
|
||||
[OpCodes.Ldelem_Any] = "Load the element at index onto the top of the stack",
|
||||
[OpCodes.Ldelem_I] = "Load the element with type native int at index onto the top of the stack as a native int",
|
||||
[OpCodes.Ldelem_I1] = "Load the element with type int8 at index onto the top of the stack as an int32",
|
||||
[OpCodes.Ldelem_I2] = "Load the element with type int16 at index onto the top of the stack as an int32",
|
||||
[OpCodes.Ldelem_I4] = "Load the element with type int32 at index onto the top of the stack as an int32",
|
||||
[OpCodes.Ldelem_I8] = "Load the element with type int64 at index onto the top of the stack as an int64",
|
||||
[OpCodes.Ldelem_R4] = "Load the element with type float32 at index onto the top of the stack as an F",
|
||||
[OpCodes.Ldelem_R8] = "Load the element with type float64 at index onto the top of the stack as an F",
|
||||
[OpCodes.Ldelem_Ref] = "Load the element at index onto the top of the stack as an O. The type of the O is the same as the element type of the array pushed on the CIL stack",
|
||||
[OpCodes.Ldelem_U1] = "Load the element with type unsigned int8 at index onto the top of the stack as an int32",
|
||||
[OpCodes.Ldelem_U2] = "Load the element with type unsigned int16 at index onto the top of the stack as an int32",
|
||||
[OpCodes.Ldelem_U4] = "Load the element with type unsigned int32 at index onto the top of the stack as an int32",
|
||||
[OpCodes.Ldelema] = "Load the address of element at index onto the top of the stack",
|
||||
[OpCodes.Ldfld] = "Push the value of field of object (or value type) obj, onto the stack",
|
||||
[OpCodes.Ldflda] = "Push the address of field of object obj on the stack",
|
||||
[OpCodes.Ldftn] = "Push a pointer to a method referenced by method, on the stack",
|
||||
[OpCodes.Ldind_I] = "Indirect load value of type native int as native int on the stack",
|
||||
[OpCodes.Ldind_I1] = "Indirect load value of type int8 as int32 on the stack",
|
||||
[OpCodes.Ldind_I2] = "Indirect load value of type int16 as int32 on the stack",
|
||||
[OpCodes.Ldind_I4] = "Indirect load value of type int32 as int32 on the stack",
|
||||
[OpCodes.Ldind_I8] = "Indirect load value of type int64 as int64 on the stack",
|
||||
[OpCodes.Ldind_R4] = "Indirect load value of type float32 as F on the stack",
|
||||
[OpCodes.Ldind_R8] = "Indirect load value of type float64 as F on the stack",
|
||||
[OpCodes.Ldind_Ref] = "Indirect load value of type object ref as O on the stack",
|
||||
[OpCodes.Ldind_U1] = "Indirect load value of type unsigned int8 as int32 on the stack",
|
||||
[OpCodes.Ldind_U2] = "Indirect load value of type unsigned int16 as int32 on the stack",
|
||||
[OpCodes.Ldind_U4] = "Indirect load value of type unsigned int32 as int32 on the stack",
|
||||
[OpCodes.Ldlen] = "Push the length (of type native unsigned int) of array on the stack",
|
||||
[OpCodes.Ldloc] = "Load local variable of index indx onto stack",
|
||||
[OpCodes.Ldloc_0] = "Load local variable 0 onto stack",
|
||||
[OpCodes.Ldloc_1] = "Load local variable 1 onto stack",
|
||||
[OpCodes.Ldloc_2] = "Load local variable 2 onto stack",
|
||||
[OpCodes.Ldloc_3] = "Load local variable 3 onto stack",
|
||||
[OpCodes.Ldloc_S] = "Load local variable of index indx onto stack, short form",
|
||||
[OpCodes.Ldloca] = "Load address of local variable with index indx",
|
||||
[OpCodes.Ldloca_S] = "Load address of local variable with index indx, short form",
|
||||
[OpCodes.Ldnull] = "Push a null reference on the stack",
|
||||
[OpCodes.Ldobj] = "Copy the value stored at address src to the stack",
|
||||
[OpCodes.Ldsfld] = "Push the value of field on the stack",
|
||||
[OpCodes.Ldsflda] = "Push the address of the static field, field, on the stack",
|
||||
[OpCodes.Ldstr] = "Push a string object for the literal string",
|
||||
[OpCodes.Ldtoken] = "Convert metadata token to its runtime representation",
|
||||
[OpCodes.Ldvirtftn] = "Push address of virtual method on the stack",
|
||||
[OpCodes.Leave] = "Exit a protected region of code",
|
||||
[OpCodes.Leave_S] = "Exit a protected region of code, short form",
|
||||
[OpCodes.Localloc] = "Allocate space from the local memory pool",
|
||||
[OpCodes.Mkrefany] = "Push a typed reference to ptr of type class onto the stack",
|
||||
[OpCodes.Mul] = "Multiply values",
|
||||
[OpCodes.Mul_Ovf] = "Multiply signed integer values. Signed result shall fit in same size",
|
||||
[OpCodes.Mul_Ovf_Un] = "Multiply unsigned integer values. Unsigned result shall fit in same size",
|
||||
[OpCodes.Neg] = "Negate value",
|
||||
[OpCodes.Newarr] = "Create a new array with elements of type etype",
|
||||
[OpCodes.Newobj] = "Allocate an uninitialized object or value type and call ctor",
|
||||
[OpCodes.No] = "The specified fault check(s) normally performed as part of the execution of the subsequent instruction can/shall be skipped",
|
||||
[OpCodes.Nop] = "Do nothing (No operation)",
|
||||
[OpCodes.Not] = "Bitwise complement (logical not)",
|
||||
[OpCodes.Or] = "Bitwise OR of two integer values, returns an integer",
|
||||
[OpCodes.Pop] = "Pop value from the stack",
|
||||
[OpCodes.Readonly] = "Specify that the subsequent array address operation performs no type check at runtime, and that it returns a controlled-mutability managed pointer",
|
||||
[OpCodes.Refanytype] = "Push the type token stored in a typed reference",
|
||||
[OpCodes.Refanyval] = "Push the address stored in a typed reference",
|
||||
[OpCodes.Rem] = "Remainder when dividing one value by another",
|
||||
[OpCodes.Rem_Un] = "Remainder when dividing one unsigned value by another",
|
||||
[OpCodes.Ret] = "Return from method, possibly with a value",
|
||||
[OpCodes.Rethrow] = "Rethrow the current exception",
|
||||
[OpCodes.Shl] = "Shift an integer left (shifting in zeros), return an integer",
|
||||
[OpCodes.Shr] = "Shift an integer right (shift in sign), return an integer",
|
||||
[OpCodes.Shr_Un] = "Shift an integer right (shift in zero), return an integer",
|
||||
[OpCodes.Sizeof] = "Push the size, in bytes, of a type as an unsigned int32",
|
||||
[OpCodes.Starg] = "Store value to the argument numbered num",
|
||||
[OpCodes.Starg_S] = "Store value to the argument numbered num, short form",
|
||||
[OpCodes.Stelem_Any] = "Replace array element at index with the value on the stack",
|
||||
[OpCodes.Stelem_I] = "Replace array element at index with the i value on the stack",
|
||||
[OpCodes.Stelem_I1] = "Replace array element at index with the int8 value on the stack",
|
||||
[OpCodes.Stelem_I2] = "Replace array element at index with the int16 value on the stack",
|
||||
[OpCodes.Stelem_I4] = "Replace array element at index with the int32 value on the stack",
|
||||
[OpCodes.Stelem_I8] = "Replace array element at index with the int64 value on the stack",
|
||||
[OpCodes.Stelem_R4] = "Replace array element at index with the float32 value on the stack",
|
||||
[OpCodes.Stelem_R8] = "Replace array element at index with the float64 value on the stack",
|
||||
[OpCodes.Stelem_Ref] = "Replace array element at index with the ref value on the stack",
|
||||
[OpCodes.Stfld] = "Replace the value of field of the object obj with value",
|
||||
[OpCodes.Stind_I] = "Store value of type native int into memory at address",
|
||||
[OpCodes.Stind_I1] = "Store value of type int8 into memory at address",
|
||||
[OpCodes.Stind_I2] = "Store value of type int16 into memory at address",
|
||||
[OpCodes.Stind_I4] = "Store value of type int32 into memory at address",
|
||||
[OpCodes.Stind_I8] = "Store value of type int64 into memory at address",
|
||||
[OpCodes.Stind_R4] = "Store value of type float32 into memory at address",
|
||||
[OpCodes.Stind_R8] = "Store value of type float64 into memory at address",
|
||||
[OpCodes.Stind_Ref] = "Store value of type object ref (type O) into memory at address",
|
||||
[OpCodes.Stloc] = "Pop a value from stack into local variable indx",
|
||||
[OpCodes.Stloc_0] = "Pop a value from stack into local variable 0",
|
||||
[OpCodes.Stloc_1] = "Pop a value from stack into local variable 1",
|
||||
[OpCodes.Stloc_2] = "Pop a value from stack into local variable 2",
|
||||
[OpCodes.Stloc_3] = "Pop a value from stack into local variable 3",
|
||||
[OpCodes.Stloc_S] = "Pop a value from stack into local variable indx, short form",
|
||||
[OpCodes.Stobj] = "Store a value of type typeTok at an address",
|
||||
[OpCodes.Stsfld] = "Replace the value of field with val",
|
||||
[OpCodes.Sub] = "Subtract value2 from value1, returning a new value",
|
||||
[OpCodes.Sub_Ovf] = "Subtract native int from a native int. Signed result shall fit in same size",
|
||||
[OpCodes.Sub_Ovf_Un] = "Subtract native unsigned int from a native unsigned int. Unsigned result shall fit in same size",
|
||||
[OpCodes.Switch] = "Jump to one of n values",
|
||||
[OpCodes.Tail] = "Subsequent call terminates current method",
|
||||
[OpCodes.Throw] = "Throw an exception",
|
||||
[OpCodes.Unaligned] = "Subsequent pointer instruction might be unaligned",
|
||||
[OpCodes.Unbox] = "Extract a value-type from obj, its boxed representation",
|
||||
[OpCodes.Unbox_Any] = "Extract a value-type from obj, its boxed representation",
|
||||
[OpCodes.Volatile] = "Subsequent pointer reference is volatile",
|
||||
[OpCodes.Xor] = "Bitwise XOR of integer values, returns an integer"
|
||||
};
|
||||
}
|
||||
}
|
|
@ -18,9 +18,9 @@
|
|||
// Code size 7 (0x7)
|
||||
.maxstack 8
|
||||
|
||||
IL_0000: ldarg.0 // Load argument 0 onto the stack
|
||||
IL_0001: call instance void [mscorlib]System.Object::.ctor() // Call method indicated on the stack with arguments
|
||||
IL_0006: ret // Return from method, possibly with a value
|
||||
IL_0000: ldarg.0
|
||||
IL_0001: call instance void [mscorlib]System.Object::.ctor()
|
||||
IL_0006: ret
|
||||
} // end of method Simple::.ctor
|
||||
|
||||
} // end of class Simple
|
|
@ -0,0 +1,248 @@
|
|||
(function(mod) {
|
||||
if (typeof exports === "object" && typeof module === "object") // CommonJS
|
||||
mod(require("codemirror"));
|
||||
else if (typeof define === "function" && define.amd) // AMD
|
||||
define(["codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(window.CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var instructions = {
|
||||
"add": "Add two values, returning a new value",
|
||||
"add.ovf": "Add signed integer values with overflow check",
|
||||
"add.ovf.un": "Add unsigned integer values with overflow check",
|
||||
"and": "Bitwise AND of two integral values, returns an integral value",
|
||||
"arglist": "Return argument list handle for the current method",
|
||||
"beq": "Branch to target if equal",
|
||||
"beq.s": "Branch to target if equal, short form",
|
||||
"bge": "Branch to target if greater than or equal to",
|
||||
"bge.s": "Branch to target if greater than or equal to, short form",
|
||||
"bge.un": "Branch to target if greater than or equal to (unsigned or unordered)",
|
||||
"bge.un.s": "Branch to target if greater than or equal to (unsigned or unordered), short form",
|
||||
"bgt": "Branch to target if greater than",
|
||||
"bgt.s": "Branch to target if greater than, short form",
|
||||
"bgt.un": "Branch to target if greater than (unsigned or unordered)",
|
||||
"bgt.un.s": "Branch to target if greater than (unsigned or unordered), short form",
|
||||
"ble": "Branch to target if less than or equal to",
|
||||
"ble.s": "Branch to target if less than or equal to, short form",
|
||||
"ble.un": "Branch to target if less than or equal to (unsigned or unordered)",
|
||||
"ble.un.s": "Branch to target if less than or equal to (unsigned or unordered), short form",
|
||||
"blt": "Branch to target if less than",
|
||||
"blt.s": "Branch to target if less than, short form",
|
||||
"blt.un": "Branch to target if less than (unsigned or unordered)",
|
||||
"blt.un.s": "Branch to target if less than (unsigned or unordered), short form",
|
||||
"bne.un": "Branch to target if unequal or unordered",
|
||||
"bne.un.s": "Branch to target if unequal or unordered, short form",
|
||||
"box": "Convert a boxable value to its boxed form",
|
||||
"br": "Branch to target",
|
||||
"br.s": "Branch to target, short form",
|
||||
"break": "Inform a debugger that a breakpoint has been reached",
|
||||
"brfalse": "Branch to target if value is zero (false)",
|
||||
"brfalse.s": "Branch to target if value is zero (false), short form",
|
||||
"brinst": "Branch to target if value is a non-null object reference (alias for brtrue)",
|
||||
"brinst.s": "Branch to target if value is a non-null object reference, short form (alias for brtrue.s)",
|
||||
"brnull": "Branch to target if value is null (alias for brfalse)",
|
||||
"brnull.s": "Branch to target if value is null (alias for brfalse.s), short form",
|
||||
"brtrue": "Branch to target if value is non-zero (true)",
|
||||
"brtrue.s": "Branch to target if value is non-zero (true), short form",
|
||||
"brzero": "Branch to target if value is zero (alias for brfalse)",
|
||||
"brzero.s": "Branch to target if value is zero (alias for brfalse.s), short form",
|
||||
"call": "Call method indicated on the stack with arguments",
|
||||
"callvirt": "Call a late-bound method on an object",
|
||||
"castclass": "Cast obj to class",
|
||||
"ceq": "Push 1 (of type int32) if value1 equals value2, else push 0",
|
||||
"cgt": "Push 1 (of type int32) if value1 > value2, else push 0",
|
||||
"cgt.un": "Push 1 (of type int32) if value1 > value2, unsigned or unordered, else push 0",
|
||||
"ckfinite": "Throw ArithmeticException if value is not a finite number",
|
||||
"clt": "Push 1 (of type int32) if value1 < value2, else push 0",
|
||||
"clt.un": "Push 1 (of type int32) if value1 < value2, unsigned or unordered, else push 0",
|
||||
"constrained": "Call a virtual method on a type constrained to be type T",
|
||||
"conv.i": "Convert to native int, pushing native int on stack",
|
||||
"conv.i1": "Convert to int8, pushing int32 on stack",
|
||||
"conv.i2": "Convert to int16, pushing int32 on stack",
|
||||
"conv.i4": "Convert to int32, pushing int32 on stack",
|
||||
"conv.i8": "Convert to int64, pushing int64 on stack",
|
||||
"conv.ovf.i": "Convert to a native int (on the stack as native int) and throw an exception on overflow",
|
||||
"conv.ovf.i.un": "Convert unsigned to a native int (on the stack as native int) and throw an exception on overflow",
|
||||
"conv.ovf.i1": "Convert to an int8 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.i1.un": "Convert unsigned to an int8 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.i2": "Convert to an int16 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.i2.un": "Convert unsigned to an int16 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.i4": "Convert to an int32 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.i4.un": "Convert unsigned to an int32 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.i8": "Convert to an int64 (on the stack as int64) and throw an exception on overflow",
|
||||
"conv.ovf.i8.un": "Convert unsigned to an int64 (on the stack as int64) and throw an exception on overflow",
|
||||
"conv.ovf.u": "Convert to a native unsigned int (on the stack as native int) and throw an exception on overflow",
|
||||
"conv.ovf.u.un": "Convert unsigned to a native unsigned int (on the stack as native int) and throw an exception on overflow",
|
||||
"conv.ovf.u1": "Convert to an unsigned int8 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.u1.un": "Convert unsigned to an unsigned int8 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.u2": "Convert to an unsigned int16 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.u2.un": "Convert unsigned to an unsigned int16 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.u4": "Convert to an unsigned int32 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.u4.un": "Convert unsigned to an unsigned int32 (on the stack as int32) and throw an exception on overflow",
|
||||
"conv.ovf.u8": "Convert to an unsigned int64 (on the stack as int64) and throw an exception on overflow",
|
||||
"conv.ovf.u8.un": "Convert unsigned to an unsigned int64 (on the stack as int64) and throw an exception on overflow",
|
||||
"conv.r.un": "Convert unsigned integer to floating-point, pushing F on stack",
|
||||
"conv.r4": "Convert to float32, pushing F on stack",
|
||||
"conv.r8": "Convert to float64, pushing F on stack",
|
||||
"conv.u": "Convert to native unsigned int, pushing native int on stack",
|
||||
"conv.u1": "Convert to unsigned int8, pushing int32 on stack",
|
||||
"conv.u2": "Convert to unsigned int16, pushing int32 on stack",
|
||||
"conv.u4": "Convert to unsigned int32, pushing int32 on stack",
|
||||
"conv.u8": "Convert to unsigned int64, pushing int64 on stack",
|
||||
"cpblk": "Copy data from memory to memory",
|
||||
"cpobj": "Copy a value type from src to dest",
|
||||
"div": "Divide two values to return a quotient or floating-point result",
|
||||
"div.un": "Divide two values, unsigned, returning a quotient",
|
||||
"dup": "Duplicate the value on the top of the stack",
|
||||
"endfault": "End fault clause of an exception block",
|
||||
"endfilter": "End an exception handling filter clause",
|
||||
"endfinally": "End finally clause of an exception block",
|
||||
"initblk": "Set all bytes in a block of memory to a given byte value",
|
||||
"initobj": "Initialize the value at address dest",
|
||||
"isinst": "Test if obj is an instance of class, returning null or an instance of that class or interface",
|
||||
"jmp": "Exit current method and jump to the specified method",
|
||||
"ldarg": "Load argument numbered num onto the stack",
|
||||
"ldarg.0": "Load argument 0 onto the stack",
|
||||
"ldarg.1": "Load argument 1 onto the stack",
|
||||
"ldarg.2": "Load argument 2 onto the stack",
|
||||
"ldarg.3": "Load argument 3 onto the stack",
|
||||
"ldarg.s": "Load argument numbered num onto the stack, short form",
|
||||
"ldarga": "Fetch the address of argument argNum",
|
||||
"ldarga.s": "Fetch the address of argument argNum, short form",
|
||||
"ldc.i4": "Push num of type int32 onto the stack as int32",
|
||||
"ldc.i4.0": "Push 0 onto the stack as int32",
|
||||
"ldc.i4.1": "Push 1 onto the stack as int32",
|
||||
"ldc.i4.2": "Push 2 onto the stack as int32",
|
||||
"ldc.i4.3": "Push 3 onto the stack as int32",
|
||||
"ldc.i4.4": "Push 4 onto the stack as int32",
|
||||
"ldc.i4.5": "Push 5 onto the stack as int32",
|
||||
"ldc.i4.6": "Push 6 onto the stack as int32",
|
||||
"ldc.i4.7": "Push 7 onto the stack as int32",
|
||||
"ldc.i4.8": "Push 8 onto the stack as int32",
|
||||
"ldc.i4.m1": "Push -1 onto the stack as int32",
|
||||
"ldc.i4.M1": "Push -1 of type int32 onto the stack as int32 (alias for ldc.i4.m1)",
|
||||
"ldc.i4.s": "Push num onto the stack as int32, short form",
|
||||
"ldc.i8": "Push num of type int64 onto the stack as int64",
|
||||
"ldc.r4 ": "Push num of type float32 onto the stack as F",
|
||||
"ldc.r8": "Push num of type float64 onto the stack as F",
|
||||
"ldelem": "Load the element at index onto the top of the stack",
|
||||
"ldelem.i": "Load the element with type native int at index onto the top of the stack as a native int",
|
||||
"ldelem.i1": "Load the element with type int8 at index onto the top of the stack as an int32",
|
||||
"ldelem.i2": "Load the element with type int16 at index onto the top of the stack as an int32",
|
||||
"ldelem.i4": "Load the element with type int32 at index onto the top of the stack as an int32",
|
||||
"ldelem.i8": "Load the element with type int64 at index onto the top of the stack as an int64",
|
||||
"ldelem.r4": "Load the element with type float32 at index onto the top of the stack as an F",
|
||||
"ldelem.r8": "Load the element with type float64 at index onto the top of the stack as an F",
|
||||
"ldelem.ref": "Load the element at index onto the top of the stack as an O. The type of the O is the same as the element type of the array pushed on the CIL stack",
|
||||
"ldelem.u1": "Load the element with type unsigned int8 at index onto the top of the stack as an int32",
|
||||
"ldelem.u2": "Load the element with type unsigned int16 at index onto the top of the stack as an int32",
|
||||
"ldelem.u4": "Load the element with type unsigned int32 at index onto the top of the stack as an int32",
|
||||
"ldelem.u8": "Load the element with type unsigned int64 at index onto the top of the stack as an int64 (alias for ldelem.i8)",
|
||||
"ldelema": "Load the address of element at index onto the top of the stack",
|
||||
"ldfld": "Push the value of field of object (or value type) obj, onto the stack",
|
||||
"ldflda": "Push the address of field of object obj on the stack",
|
||||
"ldftn": "Push a pointer to a method referenced by method, on the stack",
|
||||
"ldind.i": "Indirect load value of type native int as native int on the stack",
|
||||
"ldind.i1": "Indirect load value of type int8 as int32 on the stack",
|
||||
"ldind.i2": "Indirect load value of type int16 as int32 on the stack",
|
||||
"ldind.i4": "Indirect load value of type int32 as int32 on the stack",
|
||||
"ldind.i8": "Indirect load value of type int64 as int64 on the stack",
|
||||
"ldind.r4": "Indirect load value of type float32 as F on the stack",
|
||||
"ldind.r8": "Indirect load value of type float64 as F on the stack",
|
||||
"ldind.ref": "Indirect load value of type object ref as O on the stack",
|
||||
"ldind.u1": "Indirect load value of type unsigned int8 as int32 on the stack",
|
||||
"ldind.u2": "Indirect load value of type unsigned int16 as int32 on the stack",
|
||||
"ldind.u4": "Indirect load value of type unsigned int32 as int32 on the stack",
|
||||
"ldind.u8": "Indirect load value of type unsigned int64 as int64 on the stack (alias for ldind.i8)",
|
||||
"ldlen": "Push the length (of type native unsigned int) of array on the stack",
|
||||
"ldloc": "Load local variable of index indx onto stack",
|
||||
"ldloc.0": "Load local variable 0 onto stack",
|
||||
"ldloc.1": "Load local variable 1 onto stack",
|
||||
"ldloc.2": "Load local variable 2 onto stack",
|
||||
"ldloc.3": "Load local variable 3 onto stack",
|
||||
"ldloc.s": "Load local variable of index indx onto stack, short form",
|
||||
"ldloca": "Load address of local variable with index indx",
|
||||
"ldloca.s": "Load address of local variable with index indx, short form",
|
||||
"ldnull": "Push a null reference on the stack",
|
||||
"ldobj": "Copy the value stored at address src to the stack",
|
||||
"ldsfld": "Push the value of field on the stack",
|
||||
"ldsflda": "Push the address of the static field, field, on the stack",
|
||||
"ldstr": "Push a string object for the literal string",
|
||||
"ldtoken": "Convert metadata token to its runtime representation",
|
||||
"ldvirtftn": "Push address of virtual method on the stack",
|
||||
"leave": "Exit a protected region of code",
|
||||
"leave.s": "Exit a protected region of code, short form",
|
||||
"localloc": "Allocate space from the local memory pool",
|
||||
"mkrefany": "Push a typed reference to ptr of type class onto the stack",
|
||||
"mul": "Multiply values",
|
||||
"mul.ovf": "Multiply signed integer values. Signed result shall fit in same size",
|
||||
"mul.ovf.un": "Multiply unsigned integer values. Unsigned result shall fit in same size",
|
||||
"neg": "Negate value",
|
||||
"newarr": "Create a new array with elements of type etype",
|
||||
"newobj": "Allocate an uninitialized object or value type and call ctor",
|
||||
"no": "The specified fault check(s) normally performed as part of the execution of the subsequent instruction can/shall be skipped",
|
||||
"nop": "Do nothing (No operation)",
|
||||
"not": "Bitwise complement (logical not)",
|
||||
"or": "Bitwise OR of two integer values, returns an integer",
|
||||
"pop": "Pop value from the stack",
|
||||
"readonly": "Specify that the subsequent array address operation performs no type check at runtime, and that it returns a controlled-mutability managed pointer",
|
||||
"refanytype": "Push the type token stored in a typed reference",
|
||||
"refanyval": "Push the address stored in a typed reference",
|
||||
"rem": "Remainder when dividing one value by another",
|
||||
"rem.un": "Remainder when dividing one unsigned value by another",
|
||||
"ret": "Return from method, possibly with a value",
|
||||
"rethrow": "Rethrow the current exception",
|
||||
"shl": "Shift an integer left (shifting in zeros), return an integer",
|
||||
"shr": "Shift an integer right (shift in sign), return an integer",
|
||||
"shr.un": "Shift an integer right (shift in zero), return an integer",
|
||||
"sizeof": "Push the size, in bytes, of a type as an unsigned int32",
|
||||
"starg": "Store value to the argument numbered num",
|
||||
"starg.s": "Store value to the argument numbered num, short form",
|
||||
"stelem": "Replace array element at index with the value on the stack",
|
||||
"stelem.i": "Replace array element at index with the i value on the stack",
|
||||
"stelem.i1": "Replace array element at index with the int8 value on the stack",
|
||||
"stelem.i2": "Replace array element at index with the int16 value on the stack",
|
||||
"stelem.i4": "Replace array element at index with the int32 value on the stack",
|
||||
"stelem.i8": "Replace array element at index with the int64 value on the stack",
|
||||
"stelem.r4": "Replace array element at index with the float32 value on the stack",
|
||||
"stelem.r8": "Replace array element at index with the float64 value on the stack",
|
||||
"stelem.ref": "Replace array element at index with the ref value on the stack",
|
||||
"stfld": "Replace the value of field of the object obj with value",
|
||||
"stind.i": "Store value of type native int into memory at address",
|
||||
"stind.i1": "Store value of type int8 into memory at address",
|
||||
"stind.i2": "Store value of type int16 into memory at address",
|
||||
"stind.i4": "Store value of type int32 into memory at address",
|
||||
"stind.i8": "Store value of type int64 into memory at address",
|
||||
"stind.r4": "Store value of type float32 into memory at address",
|
||||
"stind.r8": "Store value of type float64 into memory at address",
|
||||
"stind.ref": "Store value of type object ref (type O) into memory at address",
|
||||
"stloc": "Pop a value from stack into local variable indx",
|
||||
"stloc.0": "Pop a value from stack into local variable 0",
|
||||
"stloc.1": "Pop a value from stack into local variable 1",
|
||||
"stloc.2": "Pop a value from stack into local variable 2",
|
||||
"stloc.3": "Pop a value from stack into local variable 3",
|
||||
"stloc.s": "Pop a value from stack into local variable indx, short form",
|
||||
"stobj": "Store a value of type typeTok at an address",
|
||||
"stsfld": "Replace the value of field with val",
|
||||
"sub": "Subtract value2 from value1, returning a new value",
|
||||
"sub.ovf": "Subtract native int from a native int. Signed result shall fit in same size",
|
||||
"sub.ovf.un": "Subtract native unsigned int from a native unsigned int. Unsigned result shall fit in same size",
|
||||
"switch": "Jump to one of n values",
|
||||
"tail": "Subsequent call terminates current method",
|
||||
"throw": "Throw an exception",
|
||||
"unaligned": "Subsequent pointer instruction might be unaligned",
|
||||
"unbox": "Extract a value-type from obj, its boxed representation",
|
||||
"unbox.any": "Extract a value-type from obj, its boxed representation",
|
||||
"volatile": "Subsequent pointer reference is volatile",
|
||||
"xor": "Bitwise XOR of integer values, returns an integer"
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("infotip", "cil", function(cm, token) {
|
||||
if (!token || token.type !== "builtin")
|
||||
return null;
|
||||
return "<span class='cm-builtin'>" + token.string + "</span>" +
|
||||
"<div class='CodeMirror-infotip-description'>" + instructions[token.string] + "</div>";
|
||||
});
|
||||
});
|
|
@ -0,0 +1,114 @@
|
|||
(function(mod) {
|
||||
if (typeof exports === "object" && typeof module === "object") // CommonJS
|
||||
mod(require("codemirror"));
|
||||
else if (typeof define === "function" && define.amd) // AMD
|
||||
define(["codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(window.CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var tooltip = (function() {
|
||||
var element;
|
||||
var ensureElement = function() {
|
||||
if (element)
|
||||
return;
|
||||
element = document.createElement("div");
|
||||
element.className = "CodeMirror-infotip cm-s-default"; // TODO: dynamic theme based on current cm
|
||||
element.setAttribute("hidden", "hidden");
|
||||
CodeMirror.on(element, "click", function() { tooltip.hide(); });
|
||||
document.getElementsByTagName("body")[0].appendChild(element);
|
||||
};
|
||||
|
||||
return {
|
||||
show: function(content, x, y) {
|
||||
if (!this.active) {
|
||||
ensureElement();
|
||||
element.removeAttribute("hidden");
|
||||
}
|
||||
element.innerHTML = content;
|
||||
element.style.transform = "translate(" + x + "px, " + y + "px)";
|
||||
this.active = true;
|
||||
this.content = content;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (!this.active || !element)
|
||||
return;
|
||||
element.setAttribute("hidden", "hidden");
|
||||
this.active = false;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
var activeTimeout;
|
||||
function mousemove(e) {
|
||||
/* eslint-disable no-invalid-this */
|
||||
if (activeTimeout) {
|
||||
clearTimeout(activeTimeout);
|
||||
}
|
||||
|
||||
var wrapper = this;
|
||||
activeTimeout = setTimeout(function() {
|
||||
processMoveOrClick.call(wrapper, e);
|
||||
activeTimeout = null;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function mouseout(e) {
|
||||
var cm = this.CodeMirror;
|
||||
if (e.target !== cm.getWrapperElement())
|
||||
return;
|
||||
tooltip.hide();
|
||||
}
|
||||
|
||||
function click(e) {
|
||||
processMoveOrClick.call(this, e);
|
||||
}
|
||||
|
||||
function processMoveOrClick(e) {
|
||||
/* eslint-disable no-invalid-this */
|
||||
var cm = this.CodeMirror;
|
||||
|
||||
var coords = cm.coordsChar({ left: e.x, top: e.y });
|
||||
var getTipContent = cm.state.infotip.getTipContent || cm.getHelper(coords, "infotip");
|
||||
if (!getTipContent) {
|
||||
tooltip.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var token = cm.getTokenAt(coords);
|
||||
var content = getTipContent(cm, token);
|
||||
if (content == null) {
|
||||
tooltip.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tooltip.active && content === tooltip.content)
|
||||
return;
|
||||
const tokenStart = cm.cursorCoords(CodeMirror.Pos(coords.line, token.start));
|
||||
tooltip.show(content, tokenStart.left, tokenStart.bottom);
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("infotip", null, function(cm, options, old) {
|
||||
var wrapper = cm.getWrapperElement();
|
||||
var state = cm.state.infotip;
|
||||
if (old && old !== CodeMirror.Init && state) {
|
||||
CodeMirror.off(wrapper, "click", click);
|
||||
CodeMirror.off(wrapper, "mousemove", mousemove);
|
||||
CodeMirror.off(wrapper, "mouseout", mouseout);
|
||||
delete cm.state.infotip;
|
||||
}
|
||||
|
||||
if (!options)
|
||||
return;
|
||||
|
||||
state = {
|
||||
getTipContent: options.getTipContent
|
||||
};
|
||||
cm.state.infotip = state;
|
||||
CodeMirror.on(wrapper, "click", click);
|
||||
CodeMirror.on(wrapper, "mousemove", mousemove);
|
||||
CodeMirror.on(wrapper, "mouseout", mouseout);
|
||||
});
|
||||
});
|
|
@ -124,7 +124,8 @@
|
|||
}
|
||||
|
||||
for (var key in grammar) {
|
||||
if (stream.match(grammar[key])) {
|
||||
if (stream.match(grammar[key], false)) {
|
||||
stream.match(/\S+/);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import 'codemirror/mode/clike/clike';
|
|||
import 'codemirror/mode/vb/vb';
|
||||
import '../codemirror/mode-cil.js';
|
||||
import '../codemirror/mode-asm.js';
|
||||
import '../codemirror/addon-infotip.js';
|
||||
import '../codemirror/addon-cil-infotip.js';
|
||||
|
||||
Vue.component('app-mirrorsharp-readonly', {
|
||||
props: {
|
||||
|
@ -25,7 +27,8 @@ Vue.component('app-mirrorsharp-readonly', {
|
|||
const options = {
|
||||
readOnly: true,
|
||||
indentUnit: 4,
|
||||
mode: modeMap[this.language]
|
||||
mode: modeMap[this.language],
|
||||
infotip: {}
|
||||
};
|
||||
const cm = CodeMirror.fromTextArea(textarea, options);
|
||||
this.cm = cm;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
@import (inline) '../../node_modules/codemirror/addon/hint/show-hint.css';
|
||||
@import (inline) '../../node_modules/codemirror-addon-lint-fix/dist/lint-fix.css';
|
||||
@import (inline) '../../node_modules/mirrorsharp/mirrorsharp.css';
|
||||
@import (inline) 'codemirror/addon-infotip.css';
|
||||
|
||||
textarea, .CodeMirror {
|
||||
.code-text();
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
.CodeMirror-infotip {
|
||||
position: absolute;
|
||||
z-index: 5000;
|
||||
padding: 2px 5px;
|
||||
background: #eee;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
}
|
Загрузка…
Ссылка в новой задаче