mirror of
https://gitee.com/openharmony/third_party_typescript
synced 2024-11-22 22:40:30 +00:00
Add support for vscode-js-debug's customDescriptionGenerators (#40308)
This commit is contained in:
parent
38cedc5b5f
commit
d89635381a
14
.vscode/launch.template.json
vendored
14
.vscode/launch.template.json
vendored
@ -47,14 +47,24 @@
|
||||
"console": "integratedTerminal",
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/built/local/run.js"
|
||||
]
|
||||
],
|
||||
|
||||
// NOTE: To use this, you must switch the "type" above to "pwa-node". You may also need to follow the instructions
|
||||
// here: https://github.com/microsoft/vscode-js-debug#nightly-extension to use the js-debug nightly until
|
||||
// this feature is shipping in insiders or to a release:
|
||||
// "customDescriptionGenerator": "'__tsDebuggerDisplay' in this ? this.__tsDebuggerDisplay(defaultValue) : defaultValue"
|
||||
},
|
||||
{
|
||||
// See: https://github.com/microsoft/TypeScript/wiki/Debugging-Language-Service-in-VS-Code
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"name": "Attach to VS Code TS Server via Port",
|
||||
"processId": "${command:PickProcess}"
|
||||
"processId": "${command:PickProcess}",
|
||||
|
||||
// NOTE: To use this, you must switch the "type" above to "pwa-node". You may also need to follow the instructions
|
||||
// here: https://github.com/microsoft/vscode-js-debug#nightly-extension to use the js-debug nightly until
|
||||
// this feature is shipping in insiders or to a release:
|
||||
// "customDescriptionGenerator": "'__tsDebuggerDisplay' in this ? this.__tsDebuggerDisplay(defaultValue) : defaultValue"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -371,6 +371,10 @@ namespace ts {
|
||||
return formatEnum(flags, (<any>ts).ObjectFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
export function formatFlowFlags(flags: FlowFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).FlowFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
let isDebugInfoEnabled = false;
|
||||
|
||||
interface ExtendedDebugModule {
|
||||
@ -396,13 +400,87 @@ namespace ts {
|
||||
return extendedDebug().formatControlFlowGraph(flowNode);
|
||||
}
|
||||
|
||||
export function attachFlowNodeDebugInfo(flowNode: FlowNode) {
|
||||
let flowNodeProto: FlowNodeBase | undefined;
|
||||
|
||||
function attachFlowNodeDebugInfoWorker(flowNode: FlowNodeBase) {
|
||||
if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line no-in-operator
|
||||
Object.defineProperties(flowNode, {
|
||||
// for use with vscode-js-debug's new customDescriptionGenerator in launch.json
|
||||
__tsDebuggerDisplay: {
|
||||
value(this: FlowNodeBase) {
|
||||
const flowHeader =
|
||||
this.flags & FlowFlags.Start ? "FlowStart" :
|
||||
this.flags & FlowFlags.BranchLabel ? "FlowBranchLabel" :
|
||||
this.flags & FlowFlags.LoopLabel ? "FlowLoopLabel" :
|
||||
this.flags & FlowFlags.Assignment ? "FlowAssignment" :
|
||||
this.flags & FlowFlags.TrueCondition ? "FlowTrueCondition" :
|
||||
this.flags & FlowFlags.FalseCondition ? "FlowFalseCondition" :
|
||||
this.flags & FlowFlags.SwitchClause ? "FlowSwitchClause" :
|
||||
this.flags & FlowFlags.ArrayMutation ? "FlowArrayMutation" :
|
||||
this.flags & FlowFlags.Call ? "FlowCall" :
|
||||
this.flags & FlowFlags.ReduceLabel ? "FlowReduceLabel" :
|
||||
this.flags & FlowFlags.Unreachable ? "FlowUnreachable" :
|
||||
"UnknownFlow";
|
||||
const remainingFlags = this.flags & ~(FlowFlags.Referenced - 1);
|
||||
return `${flowHeader}${remainingFlags ? ` (${formatFlowFlags(remainingFlags)})`: ""}`;
|
||||
}
|
||||
},
|
||||
__debugFlowFlags: { get(this: FlowNodeBase) { return formatEnum(this.flags, (ts as any).FlowFlags, /*isFlags*/ true); } },
|
||||
__debugToString: { value(this: FlowNodeBase) { return formatControlFlowGraph(this); } }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function attachFlowNodeDebugInfo(flowNode: FlowNodeBase) {
|
||||
if (isDebugInfoEnabled) {
|
||||
if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line no-in-operator
|
||||
Object.defineProperties(flowNode, {
|
||||
__debugFlowFlags: { get(this: FlowNode) { return formatEnum(this.flags, (ts as any).FlowFlags, /*isFlags*/ true); } },
|
||||
__debugToString: { value(this: FlowNode) { return formatControlFlowGraph(this); } }
|
||||
});
|
||||
if (typeof Object.setPrototypeOf === "function") {
|
||||
// if we're in es2015, attach the method to a shared prototype for `FlowNode`
|
||||
// so the method doesn't show up in the watch window.
|
||||
if (!flowNodeProto) {
|
||||
flowNodeProto = Object.create(Object.prototype) as FlowNodeBase;
|
||||
attachFlowNodeDebugInfoWorker(flowNodeProto);
|
||||
}
|
||||
Object.setPrototypeOf(flowNode, flowNodeProto);
|
||||
}
|
||||
else {
|
||||
// not running in an es2015 environment, attach the method directly.
|
||||
attachFlowNodeDebugInfoWorker(flowNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let nodeArrayProto: NodeArray<Node> | undefined;
|
||||
|
||||
function attachNodeArrayDebugInfoWorker(array: NodeArray<Node>) {
|
||||
if (!("__tsDebuggerDisplay" in array)) { // eslint-disable-line no-in-operator
|
||||
Object.defineProperties(array, {
|
||||
__tsDebuggerDisplay: {
|
||||
value(this: NodeArray<Node>, defaultValue: string) {
|
||||
// An `Array` with extra properties is rendered as `[A, B, prop1: 1, prop2: 2]`. Most of
|
||||
// these aren't immediately useful so we trim off the `prop1: ..., prop2: ...` part from the
|
||||
// formatted string.
|
||||
defaultValue = String(defaultValue).replace(/(?:,[\s\w\d_]+:[^,]+)+\]$/, "]");
|
||||
return `NodeArray ${defaultValue}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function attachNodeArrayDebugInfo(array: NodeArray<Node>) {
|
||||
if (isDebugInfoEnabled) {
|
||||
if (typeof Object.setPrototypeOf === "function") {
|
||||
// if we're in es2015, attach the method to a shared prototype for `NodeArray`
|
||||
// so the method doesn't show up in the watch window.
|
||||
if (!nodeArrayProto) {
|
||||
nodeArrayProto = Object.create(Array.prototype) as NodeArray<Node>;
|
||||
attachNodeArrayDebugInfoWorker(nodeArrayProto);
|
||||
}
|
||||
Object.setPrototypeOf(array, nodeArrayProto);
|
||||
}
|
||||
else {
|
||||
// not running in an es2015 environment, attach the method directly.
|
||||
attachNodeArrayDebugInfoWorker(array);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -434,10 +512,51 @@ namespace ts {
|
||||
|
||||
// Add additional properties in debug mode to assist with debugging.
|
||||
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
|
||||
// for use with vscode-js-debug's new customDescriptionGenerator in launch.json
|
||||
__tsDebuggerDisplay: {
|
||||
value(this: Symbol) {
|
||||
const symbolHeader =
|
||||
this.flags & SymbolFlags.Transient ? "TransientSymbol" :
|
||||
"Symbol";
|
||||
const remainingSymbolFlags = this.flags & ~SymbolFlags.Transient;
|
||||
return `${symbolHeader} '${symbolName(this)}'${remainingSymbolFlags ? ` (${formatSymbolFlags(remainingSymbolFlags)})` : ""}`;
|
||||
}
|
||||
},
|
||||
__debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
|
||||
});
|
||||
|
||||
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
|
||||
// for use with vscode-js-debug's new customDescriptionGenerator in launch.json
|
||||
__tsDebuggerDisplay: {
|
||||
value(this: Type) {
|
||||
const typeHeader =
|
||||
this.flags & TypeFlags.Nullable ? "NullableType" :
|
||||
this.flags & TypeFlags.StringOrNumberLiteral ? `LiteralType ${JSON.stringify((this as LiteralType).value)}` :
|
||||
this.flags & TypeFlags.BigIntLiteral ? `LiteralType ${(this as BigIntLiteralType).value.negative ? "-" : ""}${(this as BigIntLiteralType).value.base10Value}n` :
|
||||
this.flags & TypeFlags.UniqueESSymbol ? "UniqueESSymbolType" :
|
||||
this.flags & TypeFlags.Enum ? "EnumType" :
|
||||
this.flags & TypeFlags.Intrinsic ? `IntrinsicType ${(this as IntrinsicType).intrinsicName}` :
|
||||
this.flags & TypeFlags.Union ? "UnionType" :
|
||||
this.flags & TypeFlags.Intersection ? "IntersectionType" :
|
||||
this.flags & TypeFlags.Index ? "IndexType" :
|
||||
this.flags & TypeFlags.IndexedAccess ? "IndexedAccessType" :
|
||||
this.flags & TypeFlags.Conditional ? "ConditionalType" :
|
||||
this.flags & TypeFlags.Substitution ? "SubstitutionType" :
|
||||
this.flags & TypeFlags.TypeParameter ? "TypeParameter" :
|
||||
this.flags & TypeFlags.Object ?
|
||||
(this as ObjectType).objectFlags & ObjectFlags.ClassOrInterface ? "InterfaceType" :
|
||||
(this as ObjectType).objectFlags & ObjectFlags.Reference ? "TypeReference" :
|
||||
(this as ObjectType).objectFlags & ObjectFlags.Tuple ? "TupleType" :
|
||||
(this as ObjectType).objectFlags & ObjectFlags.Anonymous ? "AnonymousType" :
|
||||
(this as ObjectType).objectFlags & ObjectFlags.Mapped ? "MappedType" :
|
||||
(this as ObjectType).objectFlags & ObjectFlags.ReverseMapped ? "ReverseMappedType" :
|
||||
(this as ObjectType).objectFlags & ObjectFlags.EvolvingArray ? "EvolvingArrayType" :
|
||||
"ObjectType" :
|
||||
"Type";
|
||||
const remainingObjectFlags = this.flags & TypeFlags.Object ? (this as ObjectType).objectFlags & ~ObjectFlags.ObjectTypeKindMask : 0;
|
||||
return `${typeHeader}${this.symbol ? ` '${symbolName(this.symbol)}'` : ""}${remainingObjectFlags ? ` (${formatObjectFlags(remainingObjectFlags)})` : ""}`;
|
||||
}
|
||||
},
|
||||
__debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } },
|
||||
__debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
|
||||
__debugTypeToString: {
|
||||
@ -464,6 +583,50 @@ namespace ts {
|
||||
for (const ctor of nodeConstructors) {
|
||||
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
|
||||
Object.defineProperties(ctor.prototype, {
|
||||
// for use with vscode-js-debug's new customDescriptionGenerator in launch.json
|
||||
__tsDebuggerDisplay: {
|
||||
value(this: Node) {
|
||||
const nodeHeader =
|
||||
isGeneratedIdentifier(this) ? "GeneratedIdentifier" :
|
||||
isIdentifier(this) ? `Identifier '${idText(this)}'` :
|
||||
isPrivateIdentifier(this) ? `PrivateIdentifier '${idText(this)}'` :
|
||||
isStringLiteral(this) ? `StringLiteral ${JSON.stringify(this.text.length < 10 ? this.text : this.text.slice(10) + "...")}` :
|
||||
isNumericLiteral(this) ? `NumericLiteral ${this.text}` :
|
||||
isBigIntLiteral(this) ? `BigIntLiteral ${this.text}n` :
|
||||
isTypeParameterDeclaration(this) ? "TypeParameterDeclaration" :
|
||||
isParameter(this) ? "ParameterDeclaration" :
|
||||
isConstructorDeclaration(this) ? "ConstructorDeclaration" :
|
||||
isGetAccessorDeclaration(this) ? "GetAccessorDeclaration" :
|
||||
isSetAccessorDeclaration(this) ? "SetAccessorDeclaration" :
|
||||
isCallSignatureDeclaration(this) ? "CallSignatureDeclaration" :
|
||||
isConstructSignatureDeclaration(this) ? "ConstructSignatureDeclaration" :
|
||||
isIndexSignatureDeclaration(this) ? "IndexSignatureDeclaration" :
|
||||
isTypePredicateNode(this) ? "TypePredicateNode" :
|
||||
isTypeReferenceNode(this) ? "TypeReferenceNode" :
|
||||
isFunctionTypeNode(this) ? "FunctionTypeNode" :
|
||||
isConstructorTypeNode(this) ? "ConstructorTypeNode" :
|
||||
isTypeQueryNode(this) ? "TypeQueryNode" :
|
||||
isTypeLiteralNode(this) ? "TypeLiteralNode" :
|
||||
isArrayTypeNode(this) ? "ArrayTypeNode" :
|
||||
isTupleTypeNode(this) ? "TupleTypeNode" :
|
||||
isOptionalTypeNode(this) ? "OptionalTypeNode" :
|
||||
isRestTypeNode(this) ? "RestTypeNode" :
|
||||
isUnionTypeNode(this) ? "UnionTypeNode" :
|
||||
isIntersectionTypeNode(this) ? "IntersectionTypeNode" :
|
||||
isConditionalTypeNode(this) ? "ConditionalTypeNode" :
|
||||
isInferTypeNode(this) ? "InferTypeNode" :
|
||||
isParenthesizedTypeNode(this) ? "ParenthesizedTypeNode" :
|
||||
isThisTypeNode(this) ? "ThisTypeNode" :
|
||||
isTypeOperatorNode(this) ? "TypeOperatorNode" :
|
||||
isIndexedAccessTypeNode(this) ? "IndexedAccessTypeNode" :
|
||||
isMappedTypeNode(this) ? "MappedTypeNode" :
|
||||
isLiteralTypeNode(this) ? "LiteralTypeNode" :
|
||||
isNamedTupleMember(this) ? "NamedTupleMember" :
|
||||
isImportTypeNode(this) ? "ImportTypeNode" :
|
||||
formatSyntaxKind(this.kind);
|
||||
return `${nodeHeader}${this.flags ? ` (${formatNodeFlags(this.flags)})` : ""}`;
|
||||
}
|
||||
},
|
||||
__debugKind: { get(this: Node) { return formatSyntaxKind(this.kind); } },
|
||||
__debugNodeFlags: { get(this: Node) { return formatNodeFlags(this.flags); } },
|
||||
__debugModifierFlags: { get(this: Node) { return formatModifierFlags(getEffectiveModifierFlagsNoCache(this)); } },
|
||||
|
@ -509,6 +509,7 @@ namespace ts {
|
||||
if (elements.transformFlags === undefined) {
|
||||
aggregateChildrenFlags(elements as MutableNodeArray<T>);
|
||||
}
|
||||
Debug.attachNodeArrayDebugInfo(elements);
|
||||
return elements;
|
||||
}
|
||||
|
||||
@ -520,6 +521,7 @@ namespace ts {
|
||||
setTextRangePosEnd(array, -1, -1);
|
||||
array.hasTrailingComma = !!hasTrailingComma;
|
||||
aggregateChildrenFlags(array);
|
||||
Debug.attachNodeArrayDebugInfo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
@ -5021,7 +5021,11 @@ namespace ts {
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,
|
||||
/* @internal */
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectOrArrayLiteral | NonInferrableType
|
||||
PropagatingFlags = ContainsWideningType | ContainsObjectOrArrayLiteral | NonInferrableType,
|
||||
|
||||
// Object flags that uniquely identify the kind of ObjectType
|
||||
/* @internal */
|
||||
ObjectTypeKindMask = ClassOrInterface | Reference | Tuple | Anonymous | Mapped | ReverseMapped | EvolvingArray,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
Loading…
Reference in New Issue
Block a user