From 1bef65687ffb7a578ded639549453a881fb0e554 Mon Sep 17 00:00:00 2001 From: lixingchi1 Date: Sat, 16 Aug 2025 21:06:23 +0800 Subject: [PATCH] update the noninterop plugin Signed-off-by: lixingchi1 --- build-tools/process_global_import.js | 744 ++++++----- build-tools/process_label_noninterop.js | 1632 +++++++++++------------ 2 files changed, 1209 insertions(+), 1167 deletions(-) diff --git a/build-tools/process_global_import.js b/build-tools/process_global_import.js index 0618531b43..3cc160bdc0 100644 --- a/build-tools/process_global_import.js +++ b/build-tools/process_global_import.js @@ -19,13 +19,14 @@ const ts = require('typescript'); const commander = require('commander'); class HandleUIImports { - constructor(program, context, outPath, path) { + constructor(program, context, outPath, path, exportFlag) { this.context = context; this.typeChecker = program.getTypeChecker(); this.printer = ts.createPrinter(); this.outPath = outPath; this.inputDir = path; + this.exportFlag = exportFlag; this.insertPosition = 0; this.importedInterfaces = new Set(); @@ -43,7 +44,7 @@ class HandleUIImports { if (this.outPath) { this.writeSourceFileToOutPut(sourceFile); } - if (exportFlag) { + if (this.exportFlag) { return ts.visitNode(sourceFile, this.visitGlobalESValueNode.bind(this)); } return sourceFile; @@ -584,7 +585,7 @@ class HandleUIImports { } const fileName = rootNode.fileName; - if (!fileName.includes('node_modules') && fileName.includes(inputDir)) { + if (!fileName.includes('node_modules') && fileName.includes(this.inputDir)) { return true; } @@ -615,18 +616,21 @@ class HandleUIImports { } } -function processInteropUI(path, outPath = '') { - const filePaths = getDeclgenFiles(path); +function processInteropUI(inputPath, exportFlag, outputPath = '') { + const filePaths = getDeclgenFiles(inputPath); const program = ts.createProgram(filePaths, defaultCompilerOptions()); const sourceFiles = getSourceFiles(program, filePaths); const createTransformer = (ctx) => { return (sourceFile) => { - const handleUIImports = new HandleUIImports(program, ctx, outPath, path); + const handleUIImports = new HandleUIImports(program, ctx, outputPath, inputPath, exportFlag); return handleUIImports.createCustomTransformer(sourceFile); }; }; - return ts.transform(sourceFiles, [createTransformer]); + const res = ts.transform(sourceFiles, [createTransformer]); + + writeAnnotationFile(inputPath, outputPath); + return res; } function getDeclgenFiles(dir, filePaths = []) { @@ -677,174 +681,297 @@ class ImportType { exports.processInteropUI = processInteropUI; -let outputPath = ''; -let inputDir = ''; -let exportFlag = false; +function writeAnnotationFile(inputPath, outputPath) { + if (!outputPath) { + outputPath = inputPath; + } + + fs.writeFileSync(path.resolve(outputPath, ANNOTATION_FILENAME), ANNOTATION, 'utf8'); +} + +const ANNOTATION_FILENAME = '@ohos.arkui.GlobalAnnotation.d.ets'; + +const ANNOTATION = ` +@Retention({policy: "SOURCE"}) +export declare @interface State {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Prop {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Link {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Observed {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Track {}; + +@Retention({policy: "SOURCE"}) +export declare @interface ObjectLink {}; + +@Retention({policy: "SOURCE"}) +export declare @interface StorageProp { + property: string; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface StorageLink { + property: string; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface LocalStorageProp { + property: string; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface LocalStorageLink { + property: string; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Provide { + alias: string = ""; + allowOverride: boolean = false; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Consume { + alias: string = ""; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Watch { + callback: string; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Require {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Local {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Param {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Once {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Event {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Provider { + alias: string = ""; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Consumer { + alias: string = ""; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Monitor { + path: string[]; +}; + +@Retention({policy: "SOURCE"}) +export declare @interface Computed {}; + +@Retention({policy: "SOURCE"}) +export declare @interface ObservedV2 {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Trace {}; + +@Retention({policy: "SOURCE"}) +export declare @interface Builder {} + +@Retention({policy: "SOURCE"}) +export declare @interface BuilderParam {} + +@Retention({policy: "SOURCE"}) +export declare @interface AnimatableExtend {} + +@Retention({policy: "SOURCE"}) +export declare @interface Styles {} + +@Retention({policy: "SOURCE"}) +export declare @interface Extend { + extend: Any +} + +@Retention({policy: "SOURCE"}) +export declare @interface Type { + type: Any +} + +@Retention({policy: "SOURCE"}) +export @interface Reusable {} + +@Retention({policy: "SOURCE"}) +export @interface ReusableV2 {} + +@Retention({policy: "SOURCE"}) +export @interface Entry { + routeName: string = ""; + storage: string = ""; + useSharedStorage: boolean = false; +} + +@Retention({policy: "SOURCE"}) +export @interface Component {} + +@Retention({policy: "SOURCE"}) +export @interface ComponentV2 {} + +@Retention({policy: "SOURCE"}) +export @interface CustomDialog {} +`; const whiteList = new Set([ - 'ASTCResource', 'AbilityComponent', 'AbilityComponentAttribute', 'AbstractProperty', - 'AccelerationOptions', 'AccessibilityAction', 'AccessibilityActionInterceptResult', - 'AccessibilityCallback', 'AccessibilityHoverEvent', 'AccessibilityHoverType', - 'AccessibilityOptions', 'AccessibilityRoleType', 'AccessibilitySamePageMode', 'ActionSheet', - 'ActionSheetButtonOptions', 'ActionSheetOffset', 'ActionSheetOptions', 'AdaptiveColor', - 'AdsBlockedDetails', 'Affinity', 'AlertDialog', 'AlertDialogButtonBaseOptions', - 'AlertDialogButtonOptions', 'AlertDialogParam', 'AlertDialogParamWithButtons', - 'AlertDialogParamWithConfirm', 'AlertDialogParamWithOptions', 'AlignRuleOption', 'Alignment', - 'AlphabetIndexer', 'AlphabetIndexerAttribute', 'AlphabetIndexerOptions', 'AnchoredColorMode', + 'ASTCResource', 'AbstractProperty', 'AccelerationOptions', 'AccessibilityAction', + 'AccessibilityActionInterceptResult', 'AccessibilityCallback', 'AccessibilityHoverEvent', + 'AccessibilityHoverType', 'AccessibilityOptions', 'AccessibilityRoleType', + 'AccessibilitySamePageMode', 'ActionSheet', 'ActionSheetButtonOptions', 'ActionSheetOffset', + 'ActionSheetOptions', 'AdaptiveColor', 'AdsBlockedDetails', 'Affinity', 'AlertDialog', + 'AlertDialogButtonBaseOptions', 'AlertDialogButtonOptions', 'AlertDialogParam', + 'AlertDialogParamWithButtons', 'AlertDialogParamWithConfirm', 'AlertDialogParamWithOptions', + 'AlignRuleOption', 'Alignment', 'AlphabetIndexerOptions', 'AnchoredColorMode', 'AnimatableArithmetic', 'AnimatableExtend', 'AnimateParam', 'AnimationExtender', - 'AnimationMode', 'AnimationPropertyType', 'AnimationRange', 'AnimationStatus', 'Animator', - 'AnimatorAttribute', 'AnimatorInterface', 'AppRotation', 'AppStorage', 'AppearSymbolEffect', - 'Area', 'ArrowPointPosition', 'ArrowPosition', 'ArrowStyle', 'AttributeModifier', - 'AutoCapitalizationMode', 'AutoPlayOptions', 'AvailableLayoutArea', 'AvoidanceMode', 'Axis', - 'AxisAction', 'AxisEvent', 'AxisModel', 'BackgroundBlurStyleOptions', - 'BackgroundBrightnessOptions', 'BackgroundColorStyle', 'BackgroundEffectOptions', - 'BackgroundImageOptions', 'Badge', 'BadgeAttribute', 'BadgeParam', 'BadgeParamWithNumber', - 'BadgeParamWithString', 'BadgePosition', 'BadgeStyle', 'BarGridColumnOptions', 'BarMode', - 'BarPosition', 'BarState', 'BarStyle', 'BarrierDirection', 'BarrierStyle', 'BaseCustomComponent', - 'BaseEvent', 'BaseGestureEvent', 'BaseHandlerOptions', 'BaseShape', 'BaseSpan', - 'BaselineOffsetStyle', 'Bias', 'BindOptions', 'Blank', 'BlankAttribute', 'BlendApplyType', - 'BlendMode', 'Blender', 'BlurOptions', 'BlurStyle', 'BlurStyleActivePolicy', - 'BlurStyleOptions', 'BoardStyle', 'BorderImageOption', 'BorderOptions', 'BorderRadiuses', - 'BorderStyle', 'BottomTabBarStyle', 'BounceSymbolEffect', 'BreakPoints', 'BreakpointsReference', - 'Builder', 'BuilderAttachment', 'BuilderAttachmentInterface', 'BuilderParam', 'BusinessError', - 'Button', 'ButtonAttribute', 'ButtonConfiguration', 'ButtonIconOptions', 'ButtonOptions', - 'ButtonRole', 'ButtonStyle', 'ButtonStyleMode', 'ButtonTriggerClickCallback', 'ButtonType', - 'CacheMode', 'Calendar', 'CalendarAlign', 'CalendarAttribute', 'CalendarController', - 'CalendarDay', 'CalendarDialogOptions', 'CalendarOptions', 'CalendarPicker', - 'CalendarPickerAttribute', 'CalendarPickerDialog', 'CalendarRequestedData', - 'CalendarSelectedDate', 'Callback', 'CallbackBuffer', 'CallbackKind', 'CallbackResource', - 'CallbackResourceHolder', 'CancelButtonOptions', 'CancelButtonStyle', - 'CancelButtonSymbolOptions', 'Canvas', 'CanvasAttribute', 'CanvasDirection', 'CanvasFillRule', - 'CanvasGradient', 'CanvasLineCap', 'CanvasLineJoin', 'CanvasOptions', 'CanvasPath', - 'CanvasPattern', 'CanvasRenderer', 'CanvasRenderingContext2D', 'CanvasTextAlign', - 'CanvasTextBaseline', 'CapsuleStyleOptions', 'CaretOffset', 'CaretStyle', 'ChainAnimationOptions', - 'ChainEdgeEffect', 'ChainStyle', 'ChainWeightOptions', 'CheckBoxConfiguration', - 'CheckBoxShape', 'Checkbox', 'CheckboxAttribute', 'CheckboxGroup', 'CheckboxGroupAttribute', - 'CheckboxGroupOptions', 'CheckboxGroupResult', 'CheckboxOptions', 'ChildHitFilterOption', - 'ChildrenMainSize', 'Circle', 'CircleAttribute', 'CircleOptions', 'CircleShape', - 'CircleStyleOptions', 'ClickEffect', 'ClickEffectLevel', 'ClickEvent', + 'AnimationMode', 'AnimationPropertyType', 'AnimationRange', 'AnimationStatus', + 'AnimatorInterface', 'AppRotation', 'AppStorage', 'AppearSymbolEffect', 'Area', + 'ArrowPointPosition', 'ArrowPosition', 'ArrowStyle', 'AutoCapitalizationMode', + 'AutoPlayOptions', 'AvailableLayoutArea', 'AvoidanceMode', 'Axis', 'AxisAction', + 'AxisEvent', 'AxisModel', 'BackgroundBlurStyleOptions', 'BackgroundBrightnessOptions', + 'BackgroundColorStyle', 'BackgroundEffectOptions', 'BackgroundImageOptions', 'BadgeParam', + 'BadgeParamWithNumber', 'BadgeParamWithString', 'BadgePosition', 'BadgeStyle', + 'BarGridColumnOptions', 'BarMode', 'BarPosition', 'BarState', 'BarStyle', + 'BarrierDirection', 'BarrierStyle', 'BaseCustomComponent', 'BaseEvent', 'BaseGestureEvent', + 'BaseHandlerOptions', 'BaseShape', 'BaseSpan', 'BaselineOffsetStyle', 'Bias', 'BindOptions', + 'BlendApplyType', 'BlendMode', 'Blender', 'BlurOptions', 'BlurStyle', + 'BlurStyleActivePolicy', 'BlurStyleOptions', 'BoardStyle', 'BorderImageOption', + 'BorderOptions', 'BorderRadiuses', 'BorderStyle', 'BottomTabBarStyle', 'BounceSymbolEffect', + 'BreakPoints', 'BreakpointsReference', 'Builder', 'BuilderAttachment', + 'BuilderAttachmentInterface', 'BuilderParam', 'BusinessError', 'ButtonConfiguration', + 'ButtonIconOptions', 'ButtonOptions', 'ButtonRole', 'ButtonStyle', 'ButtonStyleMode', + 'ButtonTriggerClickCallback', 'ButtonType', 'CacheMode', 'CalendarAlign', + 'CalendarController', 'CalendarDay', 'CalendarDialogOptions', 'CalendarOptions', + 'CalendarPickerDialog', 'CalendarRequestedData', 'CalendarSelectedDate', 'Callback', + 'CallbackBuffer', 'CallbackKind', 'CallbackResource', 'CallbackResourceHolder', + 'CancelButtonOptions', 'CancelButtonStyle', 'CancelButtonSymbolOptions', 'CanvasDirection', + 'CanvasFillRule', 'CanvasGradient', 'CanvasLineCap', 'CanvasLineJoin', 'CanvasOptions', + 'CanvasPath', 'CanvasPattern', 'CanvasRenderer', 'CanvasRenderingContext2D', + 'CanvasTextAlign', 'CanvasTextBaseline', 'CapsuleStyleOptions', 'CaretOffset', 'CaretStyle', + 'ChainAnimationOptions', 'ChainEdgeEffect', 'ChainStyle', 'ChainWeightOptions', + 'CheckBoxConfiguration', 'CheckBoxShape', 'CheckboxGroupOptions', 'CheckboxGroupResult', + 'CheckboxOptions', 'ChildHitFilterOption', 'ChildrenMainSize', 'CircleOptions', + 'CircleShape', 'CircleStyleOptions', 'ClickEffect', 'ClickEffectLevel', 'ClickEvent', 'ClientAuthenticationHandler', 'CloseSwipeActionOptions', 'Color', 'ColorContent', - 'ColorFilter', 'ColorMetrics', 'ColorMode', 'ColorSpace', 'ColorStop', 'ColoringStrategy', 'Column', - 'ColumnAttribute', 'ColumnOptions', 'ColumnOptionsV2', 'ColumnSplit', 'ColumnSplitAttribute', - 'ColumnSplitDividerStyle', 'CommonAttribute', 'CommonConfiguration', 'CommonMethod', + 'ColorFilter', 'ColorMetrics', 'ColorMode', 'ColorSpace', 'ColorStop', 'ColoringStrategy', + 'ColumnOptions', 'ColumnOptionsV2', 'ColumnSplitDividerStyle', 'CommonConfiguration', 'CommonProgressStyleOptions', 'CommonShape', 'CommonShapeMethod', 'CommonTransition', - 'Component', 'Component3D', 'Component3DAttribute', 'ComponentContent', 'ComponentOptions', - 'ComponentRoot', 'ComponentV2', 'Computed', 'ComputedBarAttribute', 'Concurrent', - 'Configuration', 'ConsoleMessage', 'ConstraintSizeOptions', 'Consume', 'Consumer', - 'ContainerSpan', 'ContainerSpanAttribute', 'Content', 'ContentClipMode', 'ContentCoverOptions', - 'ContentDidScrollCallback', 'ContentModifier', 'ContentSlot', 'ContentSlotAttribute', - 'ContentType', 'Context', 'ContextMenu', 'ContextMenuAnimationOptions', - 'ContextMenuEditStateFlags', 'ContextMenuInputFieldType', 'ContextMenuMediaType', - 'ContextMenuOptions', 'ContextMenuSourceType', 'ControlSize', 'ControllerHandler', - 'CopyEvent', 'CopyOptions', 'Counter', 'CounterAttribute', 'CrownAction', 'CrownEvent', + 'ComponentContent', 'ComponentOptions', 'ComponentRoot', 'Configuration', + 'ConsoleMessage', 'ConstraintSizeOptions', 'Content', 'ContentClipMode', 'ContentCoverOptions', + 'ContentDidScrollCallback', 'ContentType', 'Context', 'ContextMenu', + 'ContextMenuAnimationOptions', 'ContextMenuEditStateFlags', 'ContextMenuInputFieldType', + 'ContextMenuMediaType', 'ContextMenuOptions', 'ContextMenuSourceType', 'ControlSize', + 'ControllerHandler', 'CopyEvent', 'CopyOptions', 'CrownAction', 'CrownEvent', 'CrownSensitivity', 'CurrentDayStyle', 'Curve', 'CustomBuilder', 'CustomComponent', - 'CustomComponentV2', 'CustomDialog', 'CustomDialogController', 'CustomDialogControllerOptions', + 'CustomComponentV2', 'CustomDialogController', 'CustomDialogControllerOptions', 'CustomNodeBuilder', 'CustomPopupOptions', 'CustomSpan', 'CustomSpanDrawInfo', - 'CustomSpanMeasureInfo', 'CustomSpanMetrics', 'CustomTheme', 'CutEvent', 'DataAddOperation', - 'DataChangeListener', 'DataChangeOperation', 'DataDeleteOperation', 'DataExchangeOperation', - 'DataMoveOperation', 'DataOperation', 'DataOperationType', 'DataPanel', 'DataPanelAttribute', + 'CustomSpanMeasureInfo', 'CustomSpanMetrics', 'CustomTheme', 'CutEvent', + 'DataAddOperation', 'DataChangeListener', 'DataChangeOperation', 'DataDeleteOperation', + 'DataExchangeOperation', 'DataMoveOperation', 'DataOperation', 'DataOperationType', 'DataPanelConfiguration', 'DataPanelOptions', 'DataPanelShadowOptions', 'DataPanelType', - 'DataReloadOperation', 'DataResubmissionHandler', 'DatePicker', 'DatePickerAttribute', - 'DatePickerDialog', 'DatePickerDialogOptions', 'DatePickerMode', 'DatePickerOptions', - 'DatePickerResult', 'DateRange', 'DateTimeOptions', 'DecorationStyle', - 'DecorationStyleInterface', 'DecorationStyleResult', 'Degree', 'DeleteValue', 'Deserializer', - 'DialogAlignment', 'DialogButtonDirection', 'DialogButtonStyle', 'DialogDisplayMode', - 'DigitIndicator', 'Dimension', 'Direction', 'DirectionalEdgesT', 'DisableSymbolEffect', - 'DisappearSymbolEffect', 'DismissContentCoverAction', 'DismissContinueReason', - 'DismissDialogAction', 'DismissFollowUpAction', 'DismissMenuAction', 'DismissPopupAction', - 'DismissReason', 'DismissSheetAction', 'DistributionType', 'DisturbanceFieldOptions', - 'DisturbanceFieldShape', 'Divider', 'DividerAttribute', 'DividerMode', 'DividerOptions', - 'DividerStyle', 'DividerStyleOptions', 'DotIndicator', 'DoubleAnimationParam', - 'DpiFollowStrategy', 'DragBehavior', 'DragEvent', 'DragInteractionOptions', 'DragItemInfo', - 'DragPointCoordinate', 'DragPreviewLiftingScale', 'DragPreviewMode', 'DragPreviewOptions', - 'DragResult', 'DraggingSizeChangeEffect', 'DrawContext', 'DrawModifier', 'DrawableDescriptor', - 'DrawingCanvas', 'DrawingColorFilter', 'DrawingLattice', 'DrawingRenderingContext', - 'DropOptions', 'DynamicNode', 'DynamicRangeMode', 'EclipseStyleOptions', 'Edge', 'EdgeColors', - 'EdgeEffect', 'EdgeEffectOptions', 'EdgeOutlineStyles', 'EdgeOutlineWidths', 'EdgeStyles', - 'EdgeWidth', 'EdgeWidths', 'Edges', 'EditMenuOptions', 'EditMode', 'EditableTextChangeValue', - 'EditableTextOnChangeCallback', 'EffectComponent', 'EffectComponentAttribute', - 'EffectDirection', 'EffectEdge', 'EffectFillStyle', 'EffectScope', 'EffectType', 'Ellipse', - 'EllipseAttribute', 'EllipseOptions', 'EllipseShape', 'EllipsisMode', 'EmbeddedComponent', - 'EmbeddedComponentAttribute', 'EmbeddedDpiFollowStrategy', 'EmbeddedOptions', 'EmbeddedType', + 'DataReloadOperation', 'DataResubmissionHandler', 'DatePickerDialog', + 'DatePickerDialogOptions', 'DatePickerMode', 'DatePickerOptions', 'DatePickerResult', + 'DateRange', 'DateTimeOptions', 'DecorationStyle', 'DecorationStyleInterface', + 'DecorationStyleResult', 'Degree', 'DeleteValue', 'Deserializer', 'DialogAlignment', + 'DialogButtonDirection', 'DialogButtonStyle', 'DialogDisplayMode', 'DigitIndicator', + 'Dimension', 'Direction', 'DirectionalEdgesT', 'DisableSymbolEffect', 'DisappearSymbolEffect', + 'DismissContentCoverAction', 'DismissContinueReason', 'DismissDialogAction', + 'DismissFollowUpAction', 'DismissMenuAction', 'DismissPopupAction', 'DismissReason', + 'DismissSheetAction', 'DistributionType', 'DisturbanceFieldOptions', 'DisturbanceFieldShape', + 'DividerMode', 'DividerOptions', 'DividerStyle', 'DividerStyleOptions', 'DotIndicator', + 'DoubleAnimationParam', 'DpiFollowStrategy', 'DragBehavior', 'DragEvent', + 'DragInteractionOptions', 'DragItemInfo', 'DragPointCoordinate', 'DragPreviewLiftingScale', + 'DragPreviewMode', 'DragPreviewOptions', 'DragResult', 'DraggingSizeChangeEffect', + 'DrawContext', 'DrawModifier', 'DrawableDescriptor', 'DrawingCanvas', 'DrawingColorFilter', + 'DrawingLattice', 'DrawingRenderingContext', 'DropOptions', 'DynamicNode', + 'DynamicRangeMode', 'EclipseStyleOptions', 'Edge', 'EdgeColors', 'EdgeEffect', + 'EdgeEffectOptions', 'EdgeOutlineStyles', 'EdgeOutlineWidths', 'EdgeStyles', 'EdgeWidth', + 'EdgeWidths', 'Edges', 'EditMenuOptions', 'EditMode', 'EditableTextChangeValue', + 'EditableTextOnChangeCallback', 'EffectDirection', 'EffectEdge', 'EffectFillStyle', + 'EffectScope', 'EffectType', 'EllipseOptions', 'EllipseShape', 'EllipsisMode', + 'EmbeddedDpiFollowStrategy', 'EmbeddedOptions', 'EmbeddedType', 'EmbeddedWindowModeFollowStrategy', 'EmitterOptions', 'EmitterParticleOptions', - 'EmitterProperty', 'EnterKeyType', 'Entry', 'EntryOptions', 'EnvPropsOptions', 'Environment', - 'ErrorCallback', 'Event', 'EventEmulator', 'EventLocationInfo', 'EventQueryType', 'EventResult', - 'EventTarget', 'EventTargetInfo', 'ExchangeIndex', 'ExchangeKey', 'ExpandedMenuItemOptions', - 'ExpectedFrameRateRange', 'Extend', 'FP', 'FadingEdgeOptions', 'FileSelectorMode', - 'FileSelectorParam', 'FileSelectorResult', 'FillMode', 'Filter', 'FingerInfo', - 'FinishCallbackType', 'FirstMeaningfulPaint', 'Flex', 'FlexAlign', 'FlexAttribute', - 'FlexDirection', 'FlexOptions', 'FlexSpaceOptions', 'FlexWrap', 'FlowItem', 'FlowItemAttribute', + 'EmitterProperty', 'EnterKeyType', 'Entry', 'EntryOptions', 'EnvPropsOptions', + 'Environment', 'ErrorCallback', 'Event', 'EventEmulator', 'EventLocationInfo', + 'EventQueryType', 'EventResult', 'EventTarget', 'EventTargetInfo', 'ExchangeIndex', + 'ExchangeKey', 'ExpandedMenuItemOptions', 'ExpectedFrameRateRange', 'Extend', 'FP', + 'FadingEdgeOptions', 'FileSelectorMode', 'FileSelectorParam', 'FileSelectorResult', + 'FillMode', 'Filter', 'FingerInfo', 'FinishCallbackType', 'FirstMeaningfulPaint', + 'FlexAlign', 'FlexDirection', 'FlexOptions', 'FlexSpaceOptions', 'FlexWrap', 'FocusAxisEvent', 'FocusBoxStyle', 'FocusController', 'FocusDrawLevel', 'FocusMovement', - 'FocusPriority', 'FocusWrapMode', 'FoldStatus', 'FolderStack', 'FolderStackAttribute', - 'FolderStackOptions', 'Font', 'FontInfo', 'FontOptions', 'FontSettingOptions', 'FontStyle', - 'FontWeight', 'ForEach', 'ForEachAttribute', 'ForegroundBlurStyleOptions', - 'ForegroundEffectOptions', 'FormCallbackInfo', 'FormComponent', 'FormComponentAttribute', - 'FormDimension', 'FormInfo', 'FormLink', 'FormLinkAttribute', 'FormLinkOptions', - 'FormRenderingMode', 'FormShape', 'FractionStop', 'FrameNode', 'FrictionMotion', - 'FullScreenEnterEvent', 'FullScreenExitHandler', 'FullscreenInfo', 'FunctionKey', 'Gauge', - 'GaugeAttribute', 'GaugeConfiguration', 'GaugeIndicatorOptions', 'GaugeOptions', - 'GaugeShadowOptions', 'GeometryInfo', 'GeometryTransitionOptions', 'Gesture', 'GestureControl', - 'GestureEvent', 'GestureGroup', 'GestureGroupGestureHandlerOptions', 'GestureGroupHandler', - 'GestureHandler', 'GestureInfo', 'GestureJudgeResult', 'GestureMask', 'GestureMode', - 'GestureModifier', 'GesturePriority', 'GestureRecognizer', - 'GestureRecognizerJudgeBeginCallback', 'GestureRecognizerState', 'GestureStyle', 'GestureType', - 'GetItemMainSizeByIndex', 'GradientDirection', 'Grid', 'GridAttribute', 'GridCol', - 'GridColAttribute', 'GridColColumnOption', 'GridColOptions', 'GridContainer', - 'GridContainerAttribute', 'GridContainerOptions', 'GridDirection', 'GridItem', - 'GridItemAlignment', 'GridItemAttribute', 'GridItemOptions', 'GridItemStyle', - 'GridLayoutOptions', 'GridRow', 'GridRowAttribute', 'GridRowColumnOption', 'GridRowDirection', - 'GridRowOptions', 'GridRowSizeOption', 'GuideLinePosition', 'GuideLineStyle', 'GutterOption', + 'FocusPriority', 'FocusWrapMode', 'FoldStatus', 'FolderStackOptions', 'Font', + 'FontInfo', 'FontOptions', 'FontSettingOptions', 'FontStyle', 'FontWeight', + 'ForegroundBlurStyleOptions', 'ForegroundEffectOptions', 'FormCallbackInfo', + 'FormDimension', 'FormInfo', 'FormLinkOptions', 'FormRenderingMode', 'FormShape', + 'FractionStop', 'FrameNode', 'FrictionMotion', 'FullScreenEnterEvent', + 'FullScreenExitHandler', 'FullscreenInfo', 'FunctionKey', 'GaugeConfiguration', + 'GaugeIndicatorOptions', 'GaugeOptions', 'GaugeShadowOptions', 'GeometryInfo', + 'GeometryTransitionOptions', 'Gesture', 'GestureControl', 'GestureEvent', 'GestureGroup', + 'GestureGroupGestureHandlerOptions', 'GestureGroupHandler', 'GestureHandler', + 'GestureInfo', 'GestureJudgeResult', 'GestureMask', 'GestureMode', 'GestureModifier', + 'GesturePriority', 'GestureRecognizer', 'GestureRecognizerJudgeBeginCallback', + 'GestureRecognizerState', 'GestureStyle', 'GestureType', 'GetItemMainSizeByIndex', + 'GradientDirection', 'GridColColumnOption', 'GridColOptions', 'GridContainerOptions', + 'GridDirection', 'GridItemAlignment', 'GridItemOptions', 'GridItemStyle', + 'GridLayoutOptions', 'GridRowColumnOption', 'GridRowDirection', 'GridRowOptions', + 'GridRowSizeOption', 'GuideLinePosition', 'GuideLineStyle', 'GutterOption', 'HapticFeedbackMode', 'Header', 'HeightBreakpoint', 'HierarchicalSymbolEffect', 'HistoricalPoint', 'HitTestMode', 'HitTestType', 'HorizontalAlign', 'HoverCallback', 'HoverEffect', 'HoverEvent', 'HoverEventParam', 'HoverModeAreaType', 'HttpAuthHandler', - 'Hyperlink', 'HyperlinkAttribute', 'ICurve', 'IDataSource', 'IMonitor', 'IMonitorValue', - 'IPropertySubscriber', 'ISinglePropertyChangeSubscriber', 'IconOptions', 'IlluminatedType', - 'Image', 'ImageAIOptions', 'ImageAnalyzerConfig', 'ImageAnalyzerController', - 'ImageAnalyzerType', 'ImageAnimator', 'ImageAnimatorAttribute', 'ImageAttachment', - 'ImageAttachmentInterface', 'ImageAttachmentLayoutStyle', 'ImageAttribute', 'ImageBitmap', + 'ICurve', 'IDataSource', 'IMonitor', 'IMonitorValue', 'IPropertySubscriber', + 'ISinglePropertyChangeSubscriber', 'IconOptions', 'IlluminatedType', 'ImageAIOptions', + 'ImageAnalyzerConfig', 'ImageAnalyzerController', 'ImageAnalyzerType', 'ImageAttachment', + 'ImageAttachmentInterface', 'ImageAttachmentLayoutStyle', 'ImageBitmap', 'ImageCompleteCallback', 'ImageContent', 'ImageData', 'ImageError', 'ImageErrorCallback', 'ImageFit', 'ImageFrameInfo', 'ImageInterpolation', 'ImageLoadResult', 'ImageModifier', 'ImageParticleParameters', 'ImageRenderMode', 'ImageRepeat', 'ImageRotateOrientation', - 'ImageSize', 'ImageSmoothingQuality', 'ImageSourceSize', 'ImageSpan', 'ImageSpanAlignment', - 'ImageSpanAttribute', 'IndexerAlign', 'Indicator', 'IndicatorComponent', - 'IndicatorComponentAttribute', 'IndicatorComponentController', 'IndicatorStyle', + 'ImageSize', 'ImageSmoothingQuality', 'ImageSourceSize', 'ImageSpanAlignment', + 'IndexerAlign', 'Indicator', 'IndicatorComponentController', 'IndicatorStyle', 'InputCounterOptions', 'InputType', 'InsertValue', 'IntelligentTrackingPreventionDetails', 'IntentionCode', 'InteractionHand', 'InterceptionModeCallback', 'InterceptionShowCallback', - 'Interop', 'InvertOptions', 'IsolatedComponent', 'IsolatedComponentAttribute', - 'IsolatedOptions', 'ItemAlign', 'ItemDragEventHandler', 'ItemDragInfo', 'ItemState', - 'JavaScriptProxy', 'JsGeolocation', 'JsResult', 'KVMContext', 'KeyEvent', 'KeyProcessingMode', - 'KeySource', 'KeyType', 'KeyboardAppearance', 'KeyboardAvoidMode', 'KeyboardOptions', - 'KeyframeAnimateParam', 'KeyframeState', 'LPX', 'LabelStyle', 'LargestContentfulPaint', - 'LaunchMode', 'LayoutBorderInfo', 'LayoutChild', 'LayoutDirection', 'LayoutInfo', - 'LayoutManager', 'LayoutMode', 'LayoutPolicy', 'LayoutSafeAreaEdge', 'LayoutSafeAreaType', - 'LayoutStyle', 'Layoutable', 'LazyForEach', 'LazyForEachAttribute', 'LazyForEachOps', - 'LazyGridLayoutAttribute', 'LazyVGridLayout', 'LazyVGridLayoutAttribute', + 'Interop', 'InvertOptions', 'IsolatedOptions', 'ItemAlign', 'ItemDragEventHandler', + 'ItemDragInfo', 'ItemState', 'JavaScriptProxy', 'JsGeolocation', 'JsResult', 'KVMContext', + 'KeyEvent', 'KeyProcessingMode', 'KeySource', 'KeyType', 'KeyboardAppearance', + 'KeyboardAvoidMode', 'KeyboardOptions', 'KeyframeAnimateParam', 'KeyframeState', 'LPX', + 'LabelStyle', 'LargestContentfulPaint', 'LaunchMode', 'LayoutBorderInfo', 'LayoutChild', + 'LayoutDirection', 'LayoutInfo', 'LayoutManager', 'LayoutMode', 'LayoutPolicy', + 'LayoutSafeAreaEdge', 'LayoutSafeAreaType', 'LayoutStyle', 'Layoutable', 'LazyForEachOps', 'LeadingMarginPlaceholder', 'Length', 'LengthConstrain', 'LengthMetrics', - 'LengthMetricsUnit', 'LengthUnit', 'LetterSpacingStyle', 'LightSource', 'Line', 'LineAttribute', + 'LengthMetricsUnit', 'LengthUnit', 'LetterSpacingStyle', 'LightSource', 'LineBreakStrategy', 'LineCapStyle', 'LineHeightStyle', 'LineJoinStyle', 'LineMetrics', 'LineOptions', 'LineSpacingOptions', 'LinearGradient', 'LinearGradientBlurOptions', - 'LinearGradientOptions', 'LinearIndicator', 'LinearIndicatorAttribute', - 'LinearIndicatorController', 'LinearIndicatorStartOptions', 'LinearIndicatorStyle', - 'LinearStyleOptions', 'Link', 'List', 'ListAttribute', 'ListDividerOptions', 'ListItem', - 'ListItemAlign', 'ListItemAttribute', 'ListItemGroup', 'ListItemGroupArea', - 'ListItemGroupAttribute', 'ListItemGroupOptions', 'ListItemGroupStyle', 'ListItemOptions', + 'LinearGradientOptions', 'LinearIndicatorController', 'LinearIndicatorStartOptions', + 'LinearIndicatorStyle', 'LinearStyleOptions', 'ListDividerOptions', 'ListItemAlign', + 'ListItemGroupArea', 'ListItemGroupOptions', 'ListItemGroupStyle', 'ListItemOptions', 'ListItemStyle', 'ListOptions', 'ListScroller', 'LoadCommittedDetails', 'Loader', - 'LoadingProgress', 'LoadingProgressAttribute', 'LoadingProgressConfiguration', - 'LoadingProgressStyle', 'Local', 'LocalBuilder', 'LocalStorage', 'LocalStorageLink', - 'LocalStorageProp', 'LocalizedAlignRuleOptions', 'LocalizedAlignment', - 'LocalizedBarrierDirection', 'LocalizedBarrierStyle', 'LocalizedBorderRadiuses', - 'LocalizedDragPointCoordinate', 'LocalizedEdgeColors', 'LocalizedEdgeWidths', - 'LocalizedEdges', 'LocalizedHorizontalAlignParam', 'LocalizedMargin', 'LocalizedPadding', - 'LocalizedPosition', 'LocalizedVerticalAlignParam', 'LocationButton', 'LocationButtonAttribute', - 'LocationButtonOnClickResult', 'LocationButtonOptions', 'LocationDescription', + 'LoadingProgressConfiguration', 'LoadingProgressStyle', 'LocalBuilder', 'LocalStorage', + 'LocalizedAlignRuleOptions', 'LocalizedAlignment', 'LocalizedBarrierDirection', + 'LocalizedBarrierStyle', 'LocalizedBorderRadiuses', 'LocalizedDragPointCoordinate', + 'LocalizedEdgeColors', 'LocalizedEdgeWidths', 'LocalizedEdges', + 'LocalizedHorizontalAlignParam', 'LocalizedMargin', 'LocalizedPadding', + 'LocalizedPosition', 'LocalizedVerticalAlignParam', 'LocationDescription', 'LocationIconStyle', 'LongPressGesture', 'LongPressGestureEvent', 'LongPressGestureHandler', 'LongPressGestureHandlerOptions', 'LongPressGestureParams', 'LongPressRecognizer', - 'LunarSwitchStyle', 'Margin', 'MarkStyle', 'Marquee', 'MarqueeAttribute', 'MarqueeOptions', - 'MarqueeStartPolicy', 'MarqueeState', 'MarqueeUpdateStrategy', 'Materialized', 'Matrix2D', - 'MaxLinesMode', 'MaxLinesOptions', 'Measurable', 'MeasureOptions', 'MeasureResult', - 'MediaCachedImage', 'MediaCachedImageAttribute', 'Memo', 'Menu', 'MenuAlignType', - 'MenuAttribute', 'MenuElement', 'MenuItem', 'MenuItemAttribute', 'MenuItemConfiguration', - 'MenuItemGroup', 'MenuItemGroupAttribute', 'MenuItemGroupOptions', 'MenuItemOptions', + 'LunarSwitchStyle', 'Margin', 'MarkStyle', 'MarqueeOptions', 'MarqueeStartPolicy', + 'MarqueeState', 'MarqueeUpdateStrategy', 'Materialized', 'Matrix2D', 'MaxLinesMode', + 'MaxLinesOptions', 'Measurable', 'MeasureOptions', 'MeasureResult', 'MenuAlignType', + 'MenuElement', 'MenuItemConfiguration', 'MenuItemGroupOptions', 'MenuItemOptions', 'MenuItemOptionsV2', 'MenuMaskType', 'MenuOnAppearCallback', 'MenuOptions', 'MenuOutlineOptions', 'MenuPolicy', 'MenuPreviewMode', 'MenuType', 'MessageLevel', 'MixedMode', 'ModalMode', 'ModalTransition', 'ModelType', 'ModifierKey', 'Monitor', @@ -853,21 +980,19 @@ const whiteList = new Set([ 'MultiShadowOptions', 'MutableStyledString', 'NativeEmbedDataInfo', 'NativeEmbedInfo', 'NativeEmbedStatus', 'NativeEmbedTouchInfo', 'NativeEmbedVisibilityInfo', 'NativeMediaPlayerConfig', 'NativeXComponentParameters', 'NavBar', 'NavBarPosition', - 'NavContentInfo', 'NavDestination', 'NavDestinationActiveReason', 'NavDestinationAttribute', - 'NavDestinationCommonTitle', 'NavDestinationContext', 'NavDestinationCustomTitle', - 'NavDestinationInfo', 'NavDestinationMode', 'NavDestinationTransition', 'NavExtender', - 'NavPathInfo', 'NavPathStack', 'NavRouteMode', 'NavRouter', 'NavRouterAttribute', - 'Navigation', 'NavigationAnimatedTransition', 'NavigationAttribute', 'NavigationCommonTitle', - 'NavigationCustomTitle', 'NavigationDividerStyle', 'NavigationInfo', 'NavigationInterception', - 'NavigationMenuItem', 'NavigationMenuOptions', 'NavigationMode', 'NavigationOperation', - 'NavigationOptions', 'NavigationSystemTransitionType', 'NavigationTitleMode', - 'NavigationTitleOptions', 'NavigationToolbarOptions', 'NavigationTransitionProxy', - 'NavigationType', 'Navigator', 'NavigatorAttribute', 'NestedScrollInfo', 'NestedScrollMode', - 'NestedScrollOptions', 'NestedScrollOptionsExt', 'Node', 'NodeContainer', - 'NodeContainerAttribute', 'NodeController', 'NonCurrentDayStyle', 'Nullable', 'ObjectLink', - 'ObscuredReasons', 'Observed', 'ObservedV2', 'OffscreenCanvas', - 'OffscreenCanvasRenderingContext2D', 'Offset', 'OffsetOptions', 'OffsetResult', - 'OnAdsBlockedCallback', 'OnAlertEvent', 'OnAlphabetIndexerPopupSelectCallback', + 'NavContentInfo', 'NavDestinationActiveReason', 'NavDestinationCommonTitle', + 'NavDestinationContext', 'NavDestinationCustomTitle', 'NavDestinationInfo', + 'NavDestinationMode', 'NavDestinationTransition', 'NavExtender', 'NavPathInfo', + 'NavPathStack', 'NavRouteMode', 'NavigationAnimatedTransition', 'NavigationCommonTitle', + 'NavigationCustomTitle', 'NavigationDividerStyle', 'NavigationInfo', + 'NavigationInterception', 'NavigationMenuItem', 'NavigationMenuOptions', + 'NavigationMode', 'NavigationOperation', 'NavigationOptions', + 'NavigationSystemTransitionType', 'NavigationTitleMode', 'NavigationTitleOptions', + 'NavigationToolbarOptions', 'NavigationTransitionProxy', 'NavigationType', + 'NestedScrollInfo', 'NestedScrollMode', 'NestedScrollOptions', 'NestedScrollOptionsExt', + 'Node', 'NodeController', 'NonCurrentDayStyle', 'Nullable', 'ObscuredReasons', + 'OffscreenCanvas', 'OffscreenCanvasRenderingContext2D', 'Offset', 'OffsetOptions', + 'OffsetResult', 'OnAdsBlockedCallback', 'OnAlertEvent', 'OnAlphabetIndexerPopupSelectCallback', 'OnAlphabetIndexerRequestPopupDataCallback', 'OnAlphabetIndexerSelectCallback', 'OnAudioStateChangedEvent', 'OnBeforeUnloadEvent', 'OnCheckboxChangeCallback', 'OnCheckboxGroupChangeCallback', 'OnClientAuthenticationEvent', 'OnConfirmEvent', @@ -897,166 +1022,159 @@ const whiteList = new Set([ 'OnViewportFitChangedCallback', 'OnWillScrollCallback', 'OnWindowNewEvent', 'Once', 'OptionWidthMode', 'Optional', 'OutlineOptions', 'OutlineRadiuses', 'OutlineStyle', 'OverScrollMode', 'OverlayOffset', 'OverlayOptions', 'PX', 'Padding', 'PageFlipMode', - 'PageTransitionCallback', 'PageTransitionEnter', 'PageTransitionExit', 'PageTransitionOptions', - 'PanDirection', 'PanGesture', 'PanGestureEvent', 'PanGestureHandler', - 'PanGestureHandlerOptions', 'PanGestureOptions', 'PanGestureParams', 'PanRecognizer', - 'Panel', 'PanelAttribute', 'PanelHeight', 'PanelMode', 'PanelType', 'ParagraphStyle', - 'ParagraphStyleInterface', 'Param', 'Particle', 'ParticleAnnulusRegion', 'ParticleAttribute', - 'ParticleColorOptions', 'ParticleColorPropertyOptions', - 'ParticleColorPropertyUpdaterConfigs', 'ParticleColorUpdaterOptions', 'ParticleConfigs', - 'ParticleEmitterShape', 'ParticleOptions', 'ParticlePropertyAnimation', - 'ParticlePropertyOptions', 'ParticlePropertyUpdaterConfigs', 'ParticleTuple', 'ParticleType', - 'ParticleUpdater', 'ParticleUpdaterOptions', 'Particles', 'PasswordIcon', 'PasteButton', - 'PasteButtonAttribute', 'PasteButtonOnClickResult', 'PasteButtonOptions', 'PasteDescription', - 'PasteEvent', 'PasteEventCallback', 'PasteIconStyle', 'Path', 'Path2D', 'PathAttribute', - 'PathOptions', 'PathShape', 'PathShapeOptions', 'PatternLock', 'PatternLockAttribute', - 'PatternLockChallengeResult', 'PatternLockController', 'Percentage', 'PerfMonitorActionType', - 'PerfMonitorSourceType', 'PermissionRequest', 'PersistPropsOptions', 'PersistentStorage', - 'PickerBackgroundStyle', 'PickerDialogButtonStyle', 'PickerTextStyle', 'PinchGesture', - 'PinchGestureEvent', 'PinchGestureHandler', 'PinchGestureHandlerOptions', 'PinchGestureParams', + 'PageTransitionCallback', 'PageTransitionEnter', 'PageTransitionExit', + 'PageTransitionOptions', 'PanDirection', 'PanGesture', 'PanGestureEvent', + 'PanGestureHandler', 'PanGestureHandlerOptions', 'PanGestureOptions', 'PanGestureParams', + 'PanRecognizer', 'PanelHeight', 'PanelMode', 'PanelType', 'ParagraphStyle', + 'ParagraphStyleInterface', 'ParticleAnnulusRegion', 'ParticleColorOptions', + 'ParticleColorPropertyOptions', 'ParticleColorPropertyUpdaterConfigs', + 'ParticleColorUpdaterOptions', 'ParticleConfigs', 'ParticleEmitterShape', + 'ParticleOptions', 'ParticlePropertyAnimation', 'ParticlePropertyOptions', + 'ParticlePropertyUpdaterConfigs', 'ParticleTuple', 'ParticleType', 'ParticleUpdater', + 'ParticleUpdaterOptions', 'Particles', 'PasswordIcon', 'PasteButtonOnClickResult', + 'PasteButtonOptions', 'PasteDescription', 'PasteEvent', 'PasteEventCallback', + 'PasteIconStyle', 'Path2D', 'PathOptions', 'PathShape', 'PathShapeOptions', + 'PatternLockChallengeResult', 'PatternLockController', 'Percentage', + 'PerfMonitorActionType', 'PerfMonitorSourceType', 'PermissionRequest', + 'PersistPropsOptions', 'PersistentStorage', 'PickerBackgroundStyle', + 'PickerDialogButtonStyle', 'PickerTextStyle', 'PinchGesture', 'PinchGestureEvent', + 'PinchGestureHandler', 'PinchGestureHandlerOptions', 'PinchGestureParams', 'PinchRecognizer', 'PixelMap', 'PixelMapMock', 'PixelRoundCalcPolicy', 'PixelRoundMode', - 'PixelRoundPolicy', 'PixelStretchEffectOptions', 'PlaceholderStyle', 'Placement', 'PlayMode', - 'PlaybackInfo', 'PlaybackSpeed', 'PluginComponent', 'PluginComponentAttribute', - 'PluginComponentOptions', 'PluginComponentTemplate', 'PluginErrorCallback', 'PluginErrorData', - 'Point', 'PointLightStyle', 'PointParticleParameters', 'PointerStyle', 'Polygon', - 'PolygonAttribute', 'PolygonOptions', 'Polyline', 'PolylineAttribute', 'PolylineOptions', - 'PopInfo', 'PopupBorderLinearGradient', 'PopupCommonOptions', 'PopupMaskType', - 'PopupMessageOptions', 'PopupOptions', 'PopupStateChangeParam', 'Position', 'PositionT', - 'PositionWithAffinity', 'PosterOptions', 'PreDragStatus', 'PreparedInfo', 'Preview', - 'PreviewConfiguration', 'PreviewMenuOptions', 'PreviewParams', 'PreviewText', 'Profiler', - 'Progress', 'ProgressAttribute', 'ProgressConfiguration', 'ProgressMask', 'ProgressOptions', - 'ProgressStatus', 'ProgressStyle', 'ProgressStyleMap', 'ProgressStyleOptions', 'ProgressType', - 'Prop', 'ProtectedResourceType', 'Provide', 'ProvideOptions', 'Provider', 'PulseSymbolEffect', - 'QRCode', 'QRCodeAttribute', 'QuickReplaceSymbolEffect', 'RRect', 'RadialGradientOptions', - 'Radio', 'RadioAttribute', 'RadioConfiguration', 'RadioIndicatorType', 'RadioOptions', - 'RadioStyle', 'Rating', 'RatingAttribute', 'RatingConfiguration', 'RatingOptions', - 'RawFileDescriptor', 'ReceiveCallback', 'Rect', 'RectAttribute', 'RectHeightStyle', - 'RectOptions', 'RectResult', 'RectShape', 'RectShapeOptions', 'RectWidthStyle', 'Rectangle', - 'Refresh', 'RefreshAttribute', 'RefreshOptions', 'RefreshStatus', 'RelateType', - 'RelativeContainer', 'RelativeContainerAttribute', 'RemoteWindow', 'RemoteWindowAttribute', - 'RenderExitReason', 'RenderFit', 'RenderMode', 'RenderProcessNotRespondingData', - 'RenderProcessNotRespondingReason', 'RenderingContextSettings', 'RepeatAttribute', - 'RepeatItem', 'RepeatMode', 'ReplaceSymbolEffect', 'Require', 'ResizableOptions', - 'ResolutionQuality', 'Resource', 'ResourceColor', 'ResourceImageAttachmentOptions', - 'ResourceStr', 'ResponseType', 'RestrictedWorker', 'Reusable', 'ReusableV2', 'ReuseOptions', - 'RichEditor', 'RichEditorAttribute', 'RichEditorBaseController', - 'RichEditorBuilderSpanOptions', 'RichEditorChangeValue', 'RichEditorController', - 'RichEditorDeleteDirection', 'RichEditorDeleteValue', 'RichEditorGesture', - 'RichEditorImageSpan', 'RichEditorImageSpanOptions', 'RichEditorImageSpanResult', - 'RichEditorImageSpanStyle', 'RichEditorImageSpanStyleResult', 'RichEditorInsertValue', - 'RichEditorLayoutStyle', 'RichEditorOptions', 'RichEditorParagraphResult', - 'RichEditorParagraphStyle', 'RichEditorParagraphStyleOptions', 'RichEditorRange', - 'RichEditorResponseType', 'RichEditorSelection', 'RichEditorSpan', 'RichEditorSpanPosition', + 'PixelRoundPolicy', 'PixelStretchEffectOptions', 'PlaceholderStyle', 'Placement', + 'PlayMode', 'PlaybackInfo', 'PlaybackSpeed', 'PluginComponentOptions', + 'PluginComponentTemplate', 'PluginErrorCallback', 'PluginErrorData', 'Point', + 'PointLightStyle', 'PointParticleParameters', 'PointerStyle', 'PolygonOptions', + 'PolylineOptions', 'PopInfo', 'PopupBorderLinearGradient', 'PopupCommonOptions', + 'PopupMaskType', 'PopupMessageOptions', 'PopupOptions', 'PopupStateChangeParam', + 'Position', 'PositionT', 'PositionWithAffinity', 'PosterOptions', 'PreDragStatus', + 'PreparedInfo', 'Preview', 'PreviewConfiguration', 'PreviewMenuOptions', 'PreviewParams', + 'PreviewText', 'Profiler', 'ProgressConfiguration', 'ProgressMask', 'ProgressOptions', + 'ProgressStatus', 'ProgressStyle', 'ProgressStyleMap', 'ProgressStyleOptions', + 'ProgressType', 'Prop', 'ProtectedResourceType', 'Provide', 'ProvideOptions', + 'Provider', 'PulseSymbolEffect', 'QuickReplaceSymbolEffect', 'RRect', + 'RadialGradientOptions', 'RadioConfiguration', 'RadioIndicatorType', 'RadioOptions', + 'RadioStyle', 'RatingConfiguration', 'RatingOptions', 'RawFileDescriptor', + 'ReceiveCallback', 'RectHeightStyle', 'RectOptions', 'RectResult', 'RectShape', + 'RectShapeOptions', 'RectWidthStyle', 'Rectangle', 'RefreshOptions', 'RefreshStatus', + 'RelateType', 'RenderExitReason', 'RenderFit', 'RenderMode', + 'RenderProcessNotRespondingData', 'RenderProcessNotRespondingReason', + 'RenderingContextSettings', 'RepeatItem', 'RepeatMode', 'ReplaceSymbolEffect', + 'ResizableOptions', 'ResolutionQuality', 'Resource', 'ResourceColor', + 'ResourceImageAttachmentOptions', 'ResourceStr', 'ResponseType', 'RestrictedWorker', + 'ReuseOptions', 'RichEditorBaseController', 'RichEditorBuilderSpanOptions', + 'RichEditorChangeValue', 'RichEditorController', 'RichEditorDeleteDirection', + 'RichEditorDeleteValue', 'RichEditorGesture', 'RichEditorImageSpan', + 'RichEditorImageSpanOptions', 'RichEditorImageSpanResult', 'RichEditorImageSpanStyle', + 'RichEditorImageSpanStyleResult', 'RichEditorInsertValue', 'RichEditorLayoutStyle', + 'RichEditorOptions', 'RichEditorParagraphResult', 'RichEditorParagraphStyle', + 'RichEditorParagraphStyleOptions', 'RichEditorRange', 'RichEditorResponseType', + 'RichEditorSelection', 'RichEditorSpan', 'RichEditorSpanPosition', 'RichEditorSpanStyleOptions', 'RichEditorSpanType', 'RichEditorStyledStringController', - 'RichEditorStyledStringOptions', 'RichEditorSymbolSpanOptions', 'RichEditorSymbolSpanStyle', - 'RichEditorSymbolSpanStyleResult', 'RichEditorTextSpan', 'RichEditorTextSpanOptions', - 'RichEditorTextSpanResult', 'RichEditorTextStyle', 'RichEditorTextStyleResult', - 'RichEditorUpdateImageSpanStyleOptions', 'RichEditorUpdateSymbolSpanStyleOptions', - 'RichEditorUpdateTextSpanStyleOptions', 'RichEditorUrlStyle', 'RichText', 'RichTextAttribute', - 'RingStyleOptions', 'Root', 'RootScene', 'RootSceneAttribute', 'RootSceneSession', - 'RotateOptions', 'RotationGesture', 'RotationGestureEvent', 'RotationGestureHandler', + 'RichEditorStyledStringOptions', 'RichEditorSymbolSpanOptions', + 'RichEditorSymbolSpanStyle', 'RichEditorSymbolSpanStyleResult', 'RichEditorTextSpan', + 'RichEditorTextSpanOptions', 'RichEditorTextSpanResult', 'RichEditorTextStyle', + 'RichEditorTextStyleResult', 'RichEditorUpdateImageSpanStyleOptions', + 'RichEditorUpdateSymbolSpanStyleOptions', 'RichEditorUpdateTextSpanStyleOptions', + 'RichEditorUrlStyle', 'RingStyleOptions', 'Root', 'RootSceneSession', 'RotateOptions', + 'RotationGesture', 'RotationGestureEvent', 'RotationGestureHandler', 'RotationGestureHandlerOptions', 'RotationGestureParams', 'RotationRecognizer', - 'RoundRectShapeOptions', 'RoundedRectOptions', 'RouteInfo', 'RouteMapConfig', 'RouteType', - 'RouterPageInfo', 'Row', 'RowAttribute', 'RowOptions', 'RowOptionsV2', 'RowSplit', - 'RowSplitAttribute', 'RuntimeType', 'SafeAreaEdge', 'SafeAreaType', 'SaveButton', - 'SaveButtonAttribute', 'SaveButtonOnClickResult', 'SaveButtonOptions', 'SaveDescription', - 'SaveIconStyle', 'ScaleOptions', 'ScaleRingStyleOptions', 'ScaleSymbolEffect', - 'ScanEffectOptions', 'Scene', 'SceneOptions', 'Screen', 'ScreenAttribute', - 'ScreenCaptureConfig', 'ScreenCaptureHandler', 'ScriptItem', 'Scroll', 'ScrollAlign', - 'ScrollAnimationOptions', 'ScrollAttribute', 'ScrollBar', 'ScrollBarAttribute', + 'RoundRectShapeOptions', 'RoundedRectOptions', 'RouteInfo', 'RouteMapConfig', + 'RouteType', 'RouterPageInfo', 'RowOptions', 'RowOptionsV2', 'RuntimeType', + 'SafeAreaEdge', 'SafeAreaType', 'SaveButtonOnClickResult', 'SaveButtonOptions', + 'SaveDescription', 'SaveIconStyle', 'ScaleOptions', 'ScaleRingStyleOptions', + 'ScaleSymbolEffect', 'ScanEffectOptions', 'Scene', 'SceneOptions', 'ScreenCaptureConfig', + 'ScreenCaptureHandler', 'ScriptItem', 'ScrollAlign', 'ScrollAnimationOptions', 'ScrollBarDirection', 'ScrollBarMargin', 'ScrollBarOptions', 'ScrollDirection', 'ScrollEdgeOptions', 'ScrollMotion', 'ScrollOnScrollCallback', 'ScrollOnWillScrollCallback', - 'ScrollOptions', 'ScrollPageOptions', 'ScrollResult', 'ScrollSizeMode', 'ScrollSnapAlign', - 'ScrollSnapOptions', 'ScrollSource', 'ScrollState', 'ScrollToIndexOptions', - 'ScrollableBarModeOptions', 'ScrollableCommonMethod', 'ScrollableTargetInfo', 'Scroller', - 'Search', 'SearchAttribute', 'SearchButtonOptions', 'SearchController', 'SearchOptions', - 'SearchSubmitCallback', 'SearchType', 'SectionOptions', 'SecurityComponentLayoutDirection', - 'SecurityComponentMethod', 'SeekMode', 'Select', 'SelectAttribute', 'SelectOption', - 'SelectStatus', 'SelectedMode', 'SelectionMenuOptions', 'SelectionMenuOptionsExt', - 'SelectionOptions', 'Serializer', 'ShadowOptions', 'ShadowStyle', 'ShadowType', - 'Shape', 'ShapeAttribute', 'ShapeSize', 'SharedTransitionEffectType', 'SheetDismiss', + 'ScrollOptions', 'ScrollPageOptions', 'ScrollResult', 'ScrollSizeMode', + 'ScrollSnapAlign', 'ScrollSnapOptions', 'ScrollSource', 'ScrollState', + 'ScrollToIndexOptions', 'ScrollableBarModeOptions', 'ScrollableCommonMethod', + 'ScrollableTargetInfo', 'Scroller', 'SearchButtonOptions', 'SearchController', + 'SearchOptions', 'SearchSubmitCallback', 'SearchType', 'SectionOptions', + 'SecurityComponentLayoutDirection', 'SecurityComponentMethod', 'SeekMode', + 'SelectOption', 'SelectStatus', 'SelectedMode', 'SelectionMenuOptions', + 'SelectionMenuOptionsExt', 'SelectionOptions', 'Serializer', 'ShadowOptions', + 'ShadowStyle', 'ShadowType', 'ShapeSize', 'SharedTransitionEffectType', 'SheetDismiss', 'SheetInfo', 'SheetKeyboardAvoidMode', 'SheetMode', 'SheetOptions', 'SheetSize', 'SheetTitleOptions', 'SheetType', 'ShouldBuiltInRecognizerParallelWithCallback', - 'SideBarContainer', 'SideBarContainerAttribute', 'SideBarContainerType', 'SideBarPosition', - 'Size', 'SizeChangeCallback', 'SizeOptions', 'SizeResult', 'SizeT', 'SizeType', 'SlideEffect', - 'SlideRange', 'Slider', 'SliderAttribute', 'SliderBlockStyle', 'SliderBlockType', - 'SliderChangeMode', 'SliderConfiguration', 'SliderCustomContentOptions', 'SliderInteraction', - 'SliderOptions', 'SliderPrefixOptions', 'SliderShowStepOptions', + 'SideBarContainerType', 'SideBarPosition', 'Size', 'SizeChangeCallback', 'SizeOptions', + 'SizeResult', 'SizeT', 'SizeType', 'SlideEffect', 'SlideRange', 'SliderBlockStyle', + 'SliderBlockType', 'SliderChangeMode', 'SliderConfiguration', 'SliderCustomContentOptions', + 'SliderInteraction', 'SliderOptions', 'SliderPrefixOptions', 'SliderShowStepOptions', 'SliderStepItemAccessibility', 'SliderStyle', 'SliderSuffixOptions', - 'SliderTriggerChangeCallback', 'SnapshotOptions', 'SourceTool', 'SourceType', 'Span', - 'SpanAttribute', 'SpanStyle', 'SpringBackAction', 'SpringMotion', 'SpringProp', 'SslError', - 'SslErrorEvent', 'SslErrorHandler', 'Stack', 'StackAttribute', 'StackOptions', - 'StarStyleOptions', 'State', 'StateStyles', 'Stepper', 'StepperAttribute', 'StepperItem', - 'StepperItemAttribute', 'Sticky', 'StickyStyle', 'Storage', 'StorageLink', 'StorageProp', - 'StyleOptions', 'StyledString', 'StyledStringChangeValue', 'StyledStringChangedListener', - 'StyledStringController', 'StyledStringKey', 'StyledStringValue', 'Styles', - 'SubMenuExpandingMode', 'SubTabBarStyle', 'SubmitCallback', 'SubmitEvent', - 'SubscribaleAbstract', 'SubscribedAbstractProperty', 'Summary', 'SuperscriptStyle', - 'SurfaceRect', 'SurfaceRotationOptions', 'SweepGradientOptions', 'SwipeActionItem', - 'SwipeActionOptions', 'SwipeActionState', 'SwipeDirection', 'SwipeEdgeEffect', 'SwipeGesture', - 'SwipeGestureEvent', 'SwipeGestureHandler', 'SwipeGestureHandlerOptions', 'SwipeGestureParams', - 'SwipeRecognizer', 'Swiper', 'SwiperAnimationEvent', 'SwiperAnimationMode', - 'SwiperAttribute', 'SwiperAutoFill', 'SwiperContentAnimatedTransition', + 'SliderTriggerChangeCallback', 'SnapshotOptions', 'SourceTool', 'SourceType', + 'SpanStyle', 'SpringBackAction', 'SpringMotion', 'SpringProp', 'SslError', + 'SslErrorEvent', 'SslErrorHandler', 'StackOptions', 'StarStyleOptions', 'State', + 'StateStyles', 'Sticky', 'StickyStyle', 'Storage', 'StyleOptions', 'StyledString', + 'StyledStringChangeValue', 'StyledStringChangedListener', 'StyledStringController', + 'StyledStringKey', 'StyledStringValue', 'Styles', 'SubMenuExpandingMode', + 'SubTabBarStyle', 'SubmitCallback', 'SubmitEvent', 'SubscribaleAbstract', + 'SubscribedAbstractProperty', 'Summary', 'SuperscriptStyle', 'SurfaceRect', + 'SurfaceRotationOptions', 'SweepGradientOptions', 'SwipeActionItem', 'SwipeActionOptions', + 'SwipeActionState', 'SwipeDirection', 'SwipeEdgeEffect', 'SwipeGesture', + 'SwipeGestureEvent', 'SwipeGestureHandler', 'SwipeGestureHandlerOptions', + 'SwipeGestureParams', 'SwipeRecognizer', 'Swiper', 'SwiperAnimationEvent', + 'SwiperAnimationMode', 'SwiperAutoFill', 'SwiperContentAnimatedTransition', 'SwiperContentTransitionProxy', 'SwiperContentWillScrollResult', 'SwiperController', 'SwiperDisplayMode', 'SwiperNestedScrollMode', 'SwitchStyle', 'SymbolEffect', - 'SymbolEffectStrategy', 'SymbolGlyph', 'SymbolGlyphAttribute', 'SymbolGlyphModifier', - 'SymbolRenderingStrategy', 'SymbolSpan', 'SymbolSpanAttribute', 'SyncedPropertyOneWay', - 'SyncedPropertyTwoWay', 'SystemAdaptiveOptions', 'SystemBarStyle', 'SystemOps', - 'TabBarIconStyle', 'TabBarOptions', 'TabBarSymbol', 'TabContent', - 'TabContentAnimatedTransition', 'TabContentAttribute', 'TabContentTransitionProxy', 'Tabs', - 'TabsAnimationEvent', 'TabsAttribute', 'TabsCacheMode', 'TabsController', - 'TabsCustomContentTransitionCallback', 'TabsOptions', 'Tag', 'TapGesture', 'TapGestureEvent', - 'TapGestureHandler', 'TapGestureHandlerOptions', 'TapGestureParameters', 'TapGestureParams', - 'TapRecognizer', 'TemplateOptions', 'TerminationInfo', 'Test', 'Text', 'TextAlign', 'TextArea', - 'TextAreaAttribute', 'TextAreaController', 'TextAreaOptions', 'TextAreaSubmitCallback', - 'TextAreaType', 'TextAttribute', 'TextBackgroundStyle', 'TextBaseController', 'TextBox', - 'TextCascadePickerRangeContent', 'TextCase', 'TextChangeOptions', 'TextChangeReason', - 'TextClock', 'TextClockAttribute', 'TextClockConfiguration', 'TextClockController', - 'TextClockOptions', 'TextContentControllerBase', 'TextContentControllerOptions', - 'TextContentStyle', 'TextController', 'TextDataDetectorConfig', 'TextDataDetectorType', - 'TextDecorationOptions', 'TextDecorationStyle', 'TextDecorationType', 'TextDeleteDirection', - 'TextEditControllerEx', 'TextHeightAdaptivePolicy', 'TextLayoutOptions', 'TextInput', - 'TextInputAttribute', 'TextInputController', 'TextInputOptions', 'TextInputStyle', - 'TextMarqueeOptions', 'TextMenuItem', 'TextMenuItemId', 'TextMenuOptions', 'TextMenuShowMode', - 'TextMetrics', 'TextModifier', 'TextOptions', 'TextOverflow', 'TextOverflowOptions', - 'TextPicker', 'TextPickerAttribute', 'TextPickerDialog', 'TextPickerDialogOptions', - 'TextPickerOptions', 'TextPickerRangeContent', 'TextPickerResult', 'TextPickerTextStyle', - 'TextRange', 'TextResponseType', 'TextSelectableMode', 'TextShadowStyle', 'TextSpanType', - 'TextStyle', 'TextTimer', 'TextTimerAttribute', 'TextTimerConfiguration', 'TextTimerController', - 'TextTimerOptions', 'Theme', 'ThemeColorMode', 'ThreatType', 'TimePicker', 'TimePickerAttribute', - 'TimePickerDialog', 'TimePickerDialogOptions', 'TimePickerFormat', 'TimePickerOptions', - 'TimePickerResult', 'TipsOptions', 'TitleHeight', 'TodayStyle', 'Toggle', 'ToggleAttribute', - 'ToggleConfiguration', 'ToggleOptions', 'ToggleType', 'ToolBarItemAttribute', + 'SymbolEffectStrategy', 'SymbolGlyphModifier', 'SymbolRenderingStrategy', + 'SyncedPropertyOneWay', 'SyncedPropertyTwoWay', 'SystemAdaptiveOptions', + 'SystemBarStyle', 'SystemOps', 'TabBarIconStyle', 'TabBarOptions', 'TabBarSymbol', + 'TabContentAnimatedTransition', 'TabContentTransitionProxy', 'TabsAnimationEvent', + 'TabsCacheMode', 'TabsController', 'TabsCustomContentTransitionCallback', + 'TabsOptions', 'Tag', 'TapGesture', 'TapGestureEvent', 'TapGestureHandler', + 'TapGestureHandlerOptions', 'TapGestureParameters', 'TapGestureParams', + 'TapRecognizer', 'TemplateOptions', 'TerminationInfo', 'Test', 'TextAlign', + 'TextAreaController', 'TextAreaOptions', 'TextAreaSubmitCallback', 'TextAreaType', + 'TextBackgroundStyle', 'TextBaseController', 'TextBox', 'TextCascadePickerRangeContent', + 'TextCase', 'TextChangeOptions', 'TextChangeReason', 'TextClockConfiguration', + 'TextClockController', 'TextClockOptions', 'TextContentControllerBase', + 'TextContentControllerOptions', 'TextContentStyle', 'TextController', + 'TextDataDetectorConfig', 'TextDataDetectorType', 'TextDecorationOptions', + 'TextDecorationStyle', 'TextDecorationType', 'TextDeleteDirection', + 'TextEditControllerEx', 'TextHeightAdaptivePolicy', 'TextLayoutOptions', + 'TextInputController', 'TextInputOptions', 'TextInputStyle', 'TextMarqueeOptions', + 'TextMenuItem', 'TextMenuItemId', 'TextMenuOptions', 'TextMenuShowMode', 'TextMetrics', + 'TextModifier', 'TextOptions', 'TextOverflow', 'TextOverflowOptions', + 'TextPickerDialog', 'TextPickerDialogOptions', 'TextPickerOptions', + 'TextPickerRangeContent', 'TextPickerResult', 'TextPickerTextStyle', 'TextRange', + 'TextResponseType', 'TextSelectableMode', 'TextShadowStyle', 'TextSpanType', + 'TextStyle', 'TextTimerConfiguration', 'TextTimerController', 'TextTimerOptions', + 'Theme', 'ThemeColorMode', 'ThreatType', 'TimePickerDialog', 'TimePickerDialogOptions', + 'TimePickerFormat', 'TimePickerOptions', 'TimePickerResult', 'TipsOptions', + 'TitleHeight', 'TodayStyle', 'ToggleConfiguration', 'ToggleOptions', 'ToggleType', 'ToolBarItemInterface', 'ToolBarItemOptions', 'ToolBarItemPlacement', 'ToolbarItem', - 'ToolbarItemStatus', 'TouchEvent', 'TouchObject', 'TouchPoint', 'TouchResult', 'TouchTestInfo', - 'TouchTestStrategy', 'TouchType', 'Trace', 'Track', 'TransitionEdge', 'TransitionEffect', - 'TransitionEffects', 'TransitionFinishCallback', 'TransitionHierarchyStrategy', - 'TransitionOptions', 'TransitionType', 'TranslateOptions', 'UICommonEvent', 'UIContext', - 'UIExtensionComponent', 'UIExtensionComponentAttribute', 'UIExtensionOptions', - 'UIExtensionProxy', 'UIGestureEvent', 'UnderlineColor', 'UnifiedData', 'UniformDataType', - 'UrlStyle', 'UserDataSpan', 'VMContext', 'VP', 'VelocityOptions', 'VerticalAlign', 'Video', - 'VideoAttribute', 'VideoController', 'VideoOptions', 'View', 'ViewportFit', 'ViewportRect', - 'VirtualScrollOptions', 'Visibility', 'VisibleAreaChangeCallback', 'VisibleAreaEventOptions', - 'VisibleListContentInfo', 'VisualEffect', 'VoiceButtonOptions', 'VoidCallback', 'Want', 'Watch', - 'WaterFlow', 'WaterFlowAttribute', 'WaterFlowLayoutMode', 'WaterFlowOptions', - 'WaterFlowSections', 'Web', 'WebAttribute', 'WebCaptureMode', 'WebContextMenuParam', - 'WebContextMenuResult', 'WebController', 'WebCookie', 'WebDarkMode', 'WebElementType', - 'WebHeader', 'WebKeyboardAvoidMode', 'WebKeyboardCallback', 'WebKeyboardCallbackInfo', + 'ToolbarItemStatus', 'TouchEvent', 'TouchObject', 'TouchPoint', 'TouchResult', + 'TouchTestInfo', 'TouchTestStrategy', 'TouchType', 'TransitionEdge', + 'TransitionEffect', 'TransitionEffects', 'TransitionFinishCallback', + 'TransitionHierarchyStrategy', 'TransitionOptions', 'TransitionType', + 'TranslateOptions', 'UICommonEvent', 'UIContext', 'UIExtensionOptions', + 'UIExtensionProxy', 'UIGestureEvent', 'UnderlineColor', 'UnifiedData', + 'UniformDataType', 'UrlStyle', 'UserDataSpan', 'VMContext', 'VP', 'VelocityOptions', + 'VerticalAlign', 'VideoController', 'VideoOptions', 'View', 'ViewportFit', + 'ViewportRect', 'VirtualScrollOptions', 'Visibility', 'VisibleAreaChangeCallback', + 'VisibleAreaEventOptions', 'VisibleListContentInfo', 'VisualEffect', 'VoiceButtonOptions', + 'VoidCallback', 'Want', 'Watch', 'WaterFlowLayoutMode', 'WaterFlowOptions', + 'WaterFlowSections', 'WebCaptureMode', 'WebContextMenuParam', 'WebContextMenuResult', + 'WebController', 'WebCookie', 'WebDarkMode', 'WebElementType', 'WebHeader', + 'WebKeyboardAvoidMode', 'WebKeyboardCallback', 'WebKeyboardCallbackInfo', 'WebKeyboardController', 'WebKeyboardOptions', 'WebLayoutMode', 'WebMediaOptions', 'WebNavigationType', 'WebOptions', 'WebResourceError', 'WebResourceRequest', 'WebResourceResponse', 'WebResponseType', 'WebviewController', 'Week', 'WeekStyle', - 'WidthBreakpoint', 'WindowAnimationTarget', 'WindowModeFollowStrategy', 'WindowScene', - 'WindowSceneAttribute', 'WindowStatusType', 'WithTheme', 'WithThemeAttribute', - 'WithThemeOptions', 'WordBreak', 'WorkStateStyle', 'WrappedBuilder', 'XComponent', - 'XComponentAttribute', 'XComponentController', 'XComponentOptions', 'XComponentType', - 'animateTo', 'animateToImmediately', 'cursorControl', 'focusControl', 'fp2px', 'getContext', - 'getInspectorNodeById', 'getInspectorNodes', 'lpx2px', 'postCardAction', 'px2fp', 'px2lpx', - 'px2vp', 'setAppBgColor', 'sharedTransitionOptions', 'vp2px' + 'WidthBreakpoint', 'WindowAnimationTarget', 'WindowModeFollowStrategy', + 'WindowStatusType', 'WithThemeOptions', 'WordBreak', 'WorkStateStyle', 'WrappedBuilder', + 'XComponentController', 'XComponentOptions', 'XComponentType', 'animateTo', + 'animateToImmediately', 'cursorControl', 'focusControl', 'fp2px', 'getContext', + 'getInspectorNodeById', 'getInspectorNodes', 'lpx2px', 'postCardAction', 'px2fp', + 'px2lpx', 'px2vp', 'setAppBgColor', 'sharedTransitionOptions', 'vp2px' ]); const decoratorsWhiteList = [ - 'State', 'Prop', 'Link', 'Observed', 'Track', 'ObjectLink', 'StorageProp', - 'StorageLink', 'LocalStorageProp', 'LocalStorageLink', 'Provide', 'Consume', 'Watch', 'Require' + 'State', 'Prop', 'Link', 'Observed', 'Track', 'ObjectLink', 'StorageProp', 'StorageLink', + 'LocalStorageProp', 'LocalStorageLink', 'Provide', 'Consume', 'Watch', + 'Local', 'Param', 'Once', 'Event', 'Provider', 'Consumer', 'Monitor', 'Computed', '@ObservedV2', 'Trace', + 'Builder', 'BuildParam', 'Styles', 'Extend', 'AnimatableExtend', 'Type', 'Require', + 'Reusable', 'ReusableV2', 'Entry', 'Component', 'ComponentV2', 'CustomDialog' ]; const whiteFileList = [ @@ -1112,10 +1230,10 @@ function start() { .option('--output ', 'output path') .option('--export ', 'export flag', false) .action((opts) => { - outputPath = opts.output; - inputDir = opts.input; - exportFlag = opts.export === 'true'; - processInteropUI(opts.input); + const outputPath = opts.output; + const inputDir = opts.input; + const exportFlag = opts.export === 'true'; + processInteropUI(inputDir, exportFlag); }); program.parse(process.argv); } diff --git a/build-tools/process_label_noninterop.js b/build-tools/process_label_noninterop.js index f01f3eea47..22291a8c44 100644 --- a/build-tools/process_label_noninterop.js +++ b/build-tools/process_label_noninterop.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,952 +12,876 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + const path = require('path'); const fs = require('fs'); -const ts = require('typescript'); const commander = require('commander'); -let sourceFile = null; -let componentEtsFiles = []; -let componentEtsDeleteFiles = []; -const kitFileNeedDeleteMap = new Map(); -const stmtReplacementMap = new Map(); - -const EXTNAME_TS = '.ts'; -const FRAMENODE = 'FrameNode'; -const TYPENODE = 'typeNode'; -const XCOMPONENT = 'XComponent'; -const ANY = 'Any'; +const ts = require('typescript'); -function start() { - const program = new commander.Command(); - program - .name('noninterop') - .version('0.0.1'); - program - .option('--input ', 'input path') - .option('--output ', 'output path') - .option('--export ', 'export flag', false) - .action((opts) => { - outputPath = opts.output; - inputDir = opts.input; - exportFlag = opts.export === 'true'; - transformFiles(opts.input); +function transformFiles(inputDir, outputPath, exportFlag) { + try { + if (exportFlag) { + initGlobalESValueFile(outputPath); + } + const utFiles = []; + readFile(inputDir, utFiles); + tsTransform(utFiles, deleteNonInteropApi, exportFlag, inputDir, outputPath); + } catch (error) { + // ignore + } +} + +function tsTransform(utFiles, callback, exportFlag, inputDir, + outputPath) { + utFiles.forEach((url) => { + const apiBaseName = path.basename(url); + let content = fs.readFileSync(url, 'utf-8'); + let isTransformer = /\.d\.ts/.test(apiBaseName) || /\.d\.ets/.test(apiBaseName); + if (/\.json/.test(url)) { + isTransformer = false; + } + if (!isTransformer) { + writeFile(url, content, inputDir, outputPath); + return; + } + + const fileName = processFileName(url); + ts.transpileModule(preprocessContent(fileName, content), { + compilerOptions: { + target: ts.ScriptTarget.ES2017, + }, + fileName: fileName, + transformers: { before: [callback(url, exportFlag, inputDir, outputPath)] }, + }); + }); +} + +function deleteNonInteropApi(url, exportFlag, inputDir, + outputPath) { + return (context) => { + return (node) => { + const fullText = String(node.getFullText()); + let fileAndKitComment = getFileAndKitComment(fullText); + const copyrightMessage = fullText.replace(node.getText(), '').split(/\/\*\*/)[0] + + fileAndKitComment + '\n'; + let kitName = ''; + if (fullText.match(/\@kit (.*)\r?\n/g)) { + kitName = RegExp.$1.replace(/\s/g, ''); + } + const fileName = processFileName(url); + sourceFile = node; + const deleteNode = processSourceFile(node, url); + node = processVisitEachChild(context, deleteNode.node, exportFlag); + if (needProcessLabelNonInterop(fileName, kitName, inputDir)) { + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + const result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); + ts.transpileModule(result, { + compilerOptions: { + target: ts.ScriptTarget.ES2017, + }, + fileName: fileName, + transformers: { + before: [formatImportDeclaration(url, exportFlag, inputDir, outputPath, + copyrightMessage, deleteNode.isCopyrightDeleted)] + }, }); - program.parse(process.argv); + } + return ts.factory.createSourceFile([], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), + ts.NodeFlags.None); + }; + }; +} + +function processVisitEachChild(context, node, + exportFlag) { + return ts.visitEachChild(node, processAllNodes, context); + + function processAllNodes(node) { + if (ts.isInterfaceDeclaration(node)) { + node = processInterfaceDeclaration(node, exportFlag); + } else if (ts.isClassDeclaration(node)) { + node = processClassDeclaration(node, exportFlag); + } else if (ts.isModuleDeclaration(node) && node.body && ts.isModuleBlock(node.body)) { + const newModuleBody = + ts.factory.updateModuleBlock(node.body, getNewStatements(node)); + node = ts.factory.updateModuleDeclaration(node, node.modifiers, node.name, newModuleBody); + } else if (ts.isEnumDeclaration(node)) { + node = processEnumDeclaration(node, exportFlag); + } else if (ts.isStructDeclaration(node)) { + node = processStructDeclaration(node); + } else if (ts.isTypeAliasDeclaration(node)) { + node = processTypeAliasDeclaration(node, exportFlag); + } + return ts.visitEachChild(node, processAllNodes, context); + } +} + +function getNewStatements(node) { + const newStatements = []; + (node.body).statements.forEach((statement) => { + if (!isNonInterop(statement)) { + newStatements.push(statement); + } + }); + return newStatements; +} + +function formatImportDeclaration(url, exportFlag, inputDir, + outputPath, copyrightMessage = '', isCopyrightDeleted = false) { + return (context) => { + return (node) => { + sourceFile = node; + const allIdentifierSet = collectAllIdentifier(node, context); + const formatValue = formatAllNodes(url, inputDir, node, allIdentifierSet); + node = formatValue.node; + const referencesMessage = formatValue.referencesMessage; + if (formatValue.isCopyrightDeleted) { + copyrightMessage = formatValue.copyrightMessage; + isCopyrightDeleted = formatValue.isCopyrightDeleted; + } + outputFile(url, exportFlag, inputDir, outputPath, node, sourceFile, referencesMessage, + copyrightMessage, isCopyrightDeleted); + return ts.factory.createSourceFile([], ts.factory.createToken(ts.SyntaxKind.EndOfFileToken), + ts.NodeFlags.None); + }; + }; } -function initGlobalESValueFile() { - fs.writeFileSync(`${path.resolve(outputPath, '../api')}/@ohos.arkui.GlobalESValue.d.ts`, '', undefined, (err) => { - if (err) { - console.error(`ERROR FOR CREATE FILE ${err}`); - } - }); -} +function formatAllNodes(url, inputDir, node, + allIdentifierSet, copyrightMessage = '', isCopyrightDeleted = false) { + let referencesMessage = ''; + let currReferencesModule = []; + if (!ts.isSourceFile(node) || !node.statements) { + return { node, referencesMessage, copyrightMessage, isCopyrightDeleted }; + } + const newStatements = []; + node.statements.forEach((statement) => { + if (ts.isImportDeclaration(statement)) { + const importInfo = formatAllNodesImportDeclaration(node, statement, url, inputDir, + currReferencesModule, allIdentifierSet); + if (importInfo.statement) { + newStatements.push(statement); + } else if (importInfo.isCopyrightDeleted) { + copyrightMessage = importInfo.copyrightMessage; + isCopyrightDeleted = importInfo.isCopyrightDeleted; + } + } else if (ts.isStructDeclaration(statement)) { + statement = ts.factory.updateStructDeclaration(statement, statement.modifiers, statement.name, + statement.typeParameters, statement.heritageClauses, statement.members.slice(1)); + newStatements.push(statement); + } else { + newStatements.push(statement); + } + }); -function writeGlobalESValueFile(content) { - content = content.replace("'use static';", '') - .replace(/\.\.\/api/g, '.'); - fs.appendFileSync(`${path.resolve(outputPath, '../api')}/@ohos.arkui.GlobalESValue.d.ts`, content, undefined, (err) => { - if (err) { - console.error(`ERROR FOR CREATE FILE ${err}`); - } - }); -} + addForSpecialFiles(node, newStatements); -function transformFiles(inputDir) { - // 入口 - try { - if (exportFlag) { - initGlobalESValueFile(); - } - const utFiles = []; - readFile(inputDir, utFiles); // 读取文件 - tsTransform(utFiles, deleteNonInteropApi); - } catch (error) { - console.error('DELETE_SYSTEM_PLUGIN ERROR: ', error); + currReferencesModule.forEach((item) => { + if (item.isUsed) { + referencesMessage += item.reference + '\n'; } + }); + node = ts.factory.updateSourceFile(node, newStatements); + return { node, referencesMessage, copyrightMessage, isCopyrightDeleted }; } -function getPureName(name) { - const pureName = path.basename(name) - .replace('.d.ts', '') - .replace('.d.ets', '') - .replace(/_/g, '') - .toLowerCase(); - return pureName; +function formatAllNodesImportDeclaration(node, statement, + url, inputDir, currReferencesModule, + allIdentifierSet) { + const clauseSet = getClauseSet(statement); + const importSpecifier = statement.moduleSpecifier.getText().replace(/[\'\"]/g, ''); + const fileDir = path.dirname(url); + const hasImportSpecifierFile = hasFileByImportPath(importSpecifier, fileDir, inputDir); + let hasImportSpecifierInModules = globalModules.has(importSpecifier); + if ((!hasImportSpecifierFile && !hasImportSpecifierInModules) || clauseSet.size === 0) { + if (hasCopyright(statement)) { + return { copyrightMessage: node.getFullText().replace(node.getText(), ''), isCopyrightDeleted: true }; + } else { + return { statement: undefined, copyrightMessage: '', isCopyrightDeleted: false }; + } + } + const clauseSetValue = getExsitClauseSet(hasImportSpecifierInModules, importSpecifier, + currReferencesModule, clauseSet, allIdentifierSet); + const hasExsitStatus = clauseSetValue.hasExsitStatus; + const hasNonExsitStatus = clauseSetValue.hasNonExsitStatus; + let exsitClauseSet = clauseSetValue.exsitClauseSet; + if (hasExsitStatus) { + return handleUsedImport(hasNonExsitStatus, statement, exsitClauseSet, + hasImportSpecifierInModules, currReferencesModule, importSpecifier); + } else if (hasCopyright(statement)) { + return { copyrightMessage: node.getFullText().replace(node.getText(), ''), isCopyrightDeleted: true }; + } else { + return { statement: undefined, copyrightMessage: '', isCopyrightDeleted: false }; + } } +function addForSpecialFiles(node, newStatements) { + const fileName = getCoreFilename(path.basename(node.fileName)); + if (fileName === FRAMENODE) { + newStatements.push(createFrameNodeTypeNode()); + } +} -/** - * 判断文件路径对应的文件是否存在 - * @param {string} importPath kit文件import - * @param {string} apiDir 引用接口所在目录 - * @returns {boolean} importPath是否存在 - */ -function hasFileByImportPath(importPath, apiDir) { - let fileDir = path.resolve(apiDir); - if (importPath.startsWith('@arkts')) { - fileDir = path.resolve(inputDir, '../arkts'); - } - return isExistArkUIFile(path.resolve(inputDir, 'arkui', 'component'), importPath) || - isExistImportFile(fileDir, importPath); +function initGlobalESValueFile(outputPath) { + const filePath = `${path.resolve(outputPath, '../api')}/${GLOBAL_ESVALUE_FILE}`; + const dir = path.dirname(filePath); + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(filePath, ''); } -function isExistArkUIFile(resolvedPath, importPath) { - const filePath = path.resolve(resolvedPath, importPath); - if ( - filePath.includes(path.resolve(inputDir, '@internal', 'component', 'ets')) || - filePath.includes(path.resolve(inputDir, 'arkui', 'component')) +function writeGlobalESValueFile(content, outputPath) { + content = content.replace("'use static';", '').replace(/\.\.\/api/g, '.'); + fs.appendFileSync(`${path.resolve(outputPath, '../api')}/${GLOBAL_ESVALUE_FILE}`, content); +} + +function readFile(dir, utFiles) { + try { + const files = fs.readdirSync(dir); + files.forEach((element) => { + const filePath = path.join(dir, element); + const status = fs.statSync(filePath); + if (status.isDirectory()) { + readFile(filePath, utFiles); + } else { + utFiles.push(filePath); + } + }); + } catch (e) { + // ignore + } +} + +function processSourceFile(node, url) { + let isCopyrightDeleted = false; + const newStatements = []; + const newStatementsWithoutExport = []; + const deleteNonInteropApiSet = new Set(); + let needDeleteExport = { + fileName: '', + default: '', + exportName: new Set(), + }; + isCopyrightDeleted = addNewStatements(node, newStatements, deleteNonInteropApiSet, needDeleteExport); + newStatements.forEach((statement) => { + const names = getExportIdentifierName(statement); + if (ts.isExportDeclaration(statement) && statement.moduleSpecifier && + ts.isStringLiteral(statement.moduleSpecifier) && + statement.moduleSpecifier.text.startsWith(`./${ARKUI}/${COMPONENT}/`)) { + const importPath = statement.moduleSpecifier.text.replace(`./${ARKUI}/${COMPONENT}/`, ''); + const isDeleteSystemFile = componentEtsDeleteFiles.includes(getPureName(importPath)); + const hasEtsFile = componentEtsFiles.includes(getPureName(importPath)); + const existFile = isExistImportFile(path.dirname(url), statement.moduleSpecifier.text.toString()); + if (isDeleteSystemFile || !hasEtsFile && !existFile) { + return; + } + } + if (names.length === 0) { + newStatementsWithoutExport.push(statement); + return; + } + if (names.length === 1 && !deleteNonInteropApiSet.has(names[0])) { + newStatementsWithoutExport.push(statement); + return; + } + processExportNode(statement, node, needDeleteExport, names, deleteNonInteropApiSet, + newStatementsWithoutExport); + }); + if (needDeleteExport.fileName !== '') { + kitFileNeedDeleteMap.set(needDeleteExport.fileName, needDeleteExport); + } + return { + node: ts.factory.updateSourceFile(node, newStatementsWithoutExport, node.isDeclarationFile, + node.referencedFiles), + isCopyrightDeleted, + }; +} + +function addNewStatements(node, newStatements, + deleteNonInteropApiSet, needDeleteExport) { + let isCopyrightDeleted = false; + node.statements.forEach((statement, index) => { + if (!isNonInterop(statement)) { + newStatements.push(statement); + return; + } + if (index === 0) { + isCopyrightDeleted = true; + } + if (ts.isVariableStatement(statement)) { + deleteNonInteropApiSet.add(variableStatementGetEscapedText(statement)); + } else if ( + ts.isModuleDeclaration(statement) || + ts.isInterfaceDeclaration(statement) || + ts.isClassDeclaration(statement) || + ts.isEnumDeclaration(statement) || + ts.isStructDeclaration(statement) || + ts.isTypeAliasDeclaration(statement) ) { - const fileName = getPureName(filePath); - return componentEtsFiles.includes(fileName); + if (statement && statement.name && (statement.name).escapedText) { + deleteNonInteropApiSet.add((statement.name).escapedText.toString()); + } + setDeleteExport(statement, node, needDeleteExport, deleteNonInteropApiSet); + } else if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { + setDeleteExport(statement, node, needDeleteExport, deleteNonInteropApiSet); + } + }); + + return isCopyrightDeleted; +} + +function processExportNode(statement, node, + needDeleteExport, names, deleteNonInteropApiSet, + newStatementsWithoutExport) { + if (ts.isExportAssignment(statement)) { + needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); + needDeleteExport.default = (statement.expression).escapedText.toString(); + } else if (ts.isExportDeclaration(statement)) { + let needExport = false; + const newSpecifiers = []; + names.forEach((name, index) => { + const exportSpecifier = + (statement.exportClause).elements[index]; + if (!deleteNonInteropApiSet.has(name)) { + newSpecifiers.push(exportSpecifier); + needExport = true; + } else { + needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); + needDeleteExport.exportName.add(exportSpecifier.name.escapedText.toString()); + } + }); + if (needExport) { + (statement.exportClause) = ts.factory.updateNamedExports( + statement.exportClause, newSpecifiers); + newStatementsWithoutExport.push(statement); } - return isExistImportFile(resolvedPath, importPath); + } } -function isExistImportFile(fileDir, importPath) { - return ['.d.ts', '.d.ets'].some(ext => { - return fs.existsSync(path.resolve(fileDir, `${importPath}${ext}`)); - }); +function getPureName(name) { + const pureName = path.basename(name) + .replace(EXTNAME_D_TS, '') + .replace(EXTNAME_D_ETS, '') + .replace(/_/g, '') + .toLowerCase(); + return pureName; } -/** - * 统一处理文件名称,修改后缀等 - * @param {string} filePath 文件路径 - * @returns {string} filename 文件名称 - */ function processFileName(filePath) { - return path - .basename(filePath) - .replace(/\.d\.ts$/g, '.ts') - .replace(/\.d\.ets$/g, '.ets'); + return path + .basename(filePath) + .replace(/\.d\.ts$/g, EXTNAME_TS) + .replace(/\.d\.ets$/g, EXTNAME_ETS); } function processFileNameWithoutExt(filePath) { - return path - .basename(filePath) - .replace(/\.d\.ts$/g, '') - .replace(/\.d\.ets$/g, '') - .replace(/\.ts$/g, '') - .replace(/\.ets$/g, ''); -} - -/** - * 对文件内容进行预处理,把下面的两行处理成符合1.1的语法: - * @Retention({policy: "SOURCE"}) - * export declare @interface State {}; - * - * 转成 - * /**@reserved @Retention({policy: "SOURCE"}) #/ - * export declare const State; - * @param {string} content - */ -function preprocessContent(content) { - stmtReplacementMap.clear(); - let result = content.replace(/^(\s*)(\@Retention\(\{[^\(\)\{\}]*\}\)$)/mg, '$1/**@reserved $2 */'); - const matches = result.match(/(^[^\*]*\s+\@interface\s+.*$)/mg); - if (matches) { - for (const match of matches) { - const transformedStmt = match.replace(/(?<=\s+)\@interface(\s+\w+)\s*\{\}/g, 'const$1'); - result = result.replace(match, transformedStmt); - stmtReplacementMap.set(match, transformedStmt); - } - } - return result; + return path + .basename(filePath) + .replace(/\.d\.ts$/g, '') + .replace(/\.d\.ets$/g, '') + .replace(/\.ts$/g, '') + .replace(/\.ets$/g, ''); +} + +function hasFileByImportPath(importPath, apiDir, inputDir) { + let fileDir = path.resolve(apiDir); + if (importPath.startsWith(`@${ARKTS}`)) { + fileDir = path.resolve(inputDir, `../${ARKTS}`); + } + return isExistArkUIFile(path.resolve(inputDir, ARKUI, COMPONENT), importPath, inputDir) || + isExistImportFile(fileDir, importPath); +} + +function isExistArkUIFile(resolvedPath, importPath, inputDir) { + const filePath = path.resolve(resolvedPath, importPath); + if (filePath.includes(path.resolve(inputDir, INTERNAL, COMPONENT, ETS)) || + filePath.includes(path.resolve(inputDir, ARKUI, COMPONENT)) + ) { + const fileName = getPureName(filePath); + return componentEtsFiles.includes(fileName); + } + return isExistImportFile(resolvedPath, importPath); } -/** - * 遍历所有文件进行处理 - * @param {Array} utFiles 所有文件 - * @param {deleteNonInteropApi} callback 回调函数 - */ -function tsTransform(utFiles, callback) { - utFiles.forEach((url) => { - const apiBaseName = path.basename(url); - let content = fs.readFileSync(url, 'utf-8'); // 文件内容 - let isTransformer = /\.d\.ts/.test(apiBaseName) || /\.d\.ets/.test(apiBaseName); - if (/\.json/.test(url)) { - isTransformer = false; - } - if (!isTransformer) { - writeFile(url, content); - return; - } - // dts文件处理 - const fileName = processFileName(url); - ts.transpileModule(preprocessContent(content), { - compilerOptions: { - target: ts.ScriptTarget.ES2017, - }, - fileName: fileName, - transformers: { before: [callback(url)] }, - }); - }); +function isExistImportFile(fileDir, importPath) { + return [EXTNAME_D_TS, EXTNAME_D_ETS].some(ext => { + return fs.existsSync(path.resolve(fileDir, `${importPath}${ext}`)); + }); } -/** - * 读取目录下所有文件 - * @param {string} dir 文件目录 - * @param {Array} utFiles 所有文件 - */ -function readFile(dir, utFiles) { - try { - const files = fs.readdirSync(dir); - files.forEach((element) => { - const filePath = path.join(dir, element); - const status = fs.statSync(filePath); - if (status.isDirectory()) { - readFile(filePath, utFiles); - } else { - utFiles.push(filePath); - } - }); - } catch (e) { - console.log('ETS ERROR: ' + e); +function preprocessContent(fileName, content) { + stmtReplacementMap.clear(); + let result = content.replace(/^(\s*)(\@Retention\(\{[^\(\)\{\}]*\}\)$)/mg, + '$1/**@reserved $2 */'); + const matches = result.match(/(^[^\*]*\s+\@interface\s+.*$)/mg); + if (matches) { + for (const match of matches) { + const transformedStmt = match.replace(/(?<=\s+)\@interface(\s+\w+)\s*\{\}/g, 'const$1'); + result = result.replace(match, transformedStmt); + stmtReplacementMap.set(match, transformedStmt); } + } + if (isSpecialFile(fileName)) { + result = processSpecialFileContext(fileName, result); + } + return result; } -function writeFile(url, data, option) { - const newFilePath = path.resolve(outputPath, path.relative(inputDir, url)); - fs.mkdir(path.dirname(newFilePath), { recursive: true }, (err) => { - if (err) { - console.log(`ERROR FOR CREATE PATH ${err}`); - } else { - if (data === '') { - fs.rmSync(newFilePath); - return; - } - fs.writeFileSync(newFilePath, data, option, (err) => { - if (err) { - console.log(`ERROR FOR CREATE FILE ${err}`); - } - }); - } - }); +function processSpecialFileContext(fileName, context) { + fileName = path.basename(fileName, EXTNAME_TS); + if (fileName === ALERT_DIALOG) { + context = context.replace(/\bTextStyle\b/g, ALERT_DIALOG_TEXT_STYLE); + } + if (fileName === COMMON) { + context = context.replace(/\bLinearGradient\b/g, COMMON_LINEAR_GRADIENT); + } + return context; } -const globalModules = new Map(); +function isSpecialFile(url) { + return specialFileList.includes(path.basename(url, EXTNAME_TS)); +} -function postProcessContent(content) { - for (const [originalStmt, transformedStmt] of stmtReplacementMap) { - content = content.replace(transformedStmt, originalStmt); - } - return content.replace(/^(\s*)\/\*\*\@reserved (.*) \*\/$/mg, '$1$2'); +function writeFile(url, data, inputDir, outputPath) { + const newFilePath = path.resolve(outputPath, path.relative(inputDir, url)); + fs.mkdirSync(path.dirname(newFilePath), { recursive: true }); + fs.writeFileSync(newFilePath, data); } -function outputFile(url, node, sourceFile, referencesMessage, copyrightMessage, isCopyrightDeleted) { - const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); - let result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); - if (isCopyrightDeleted) { - // 当第一个节点被删除时会同步删除整个文件jsdoc - result = copyrightMessage + '\n' + result; - } - copyrightMessage = node.getFullText().replace(node.getText(), ''); - if (referencesMessage) { - // 将references写入文件 - result = - result.substring(0, copyrightMessage.length) + - '\n' + - referencesMessage + - result.substring(copyrightMessage.length); - } - result = removeNonInteropDoc(result); - result = postProcessContent(result); - writeFile(url, result); - if (exportFlag) { - writeGlobalESValueFile(result); - } +function postProcessContent(content) { + for (const [originalStmt, transformedStmt] of stmtReplacementMap) { + content = content.replace(transformedStmt, originalStmt); + } + return content.replace(/^(\s*)\/\*\*\@reserved (.*) \*\/$/mg, '$1$2'); +} + +function outputFile(url, exportFlag, inputDir, outputPath, + node, sourceFile, referencesMessage, + copyrightMessage, isCopyrightDeleted) { + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + let result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); + if (isCopyrightDeleted) { + result = copyrightMessage + '\n' + result; + } + copyrightMessage = node.getFullText().replace(node.getText(), ''); + if (referencesMessage) { + result = result.substring(0, copyrightMessage.length) + '\n' + referencesMessage + + result.substring(copyrightMessage.length); + } + result = removeNonInteropDoc(result); + result = postProcessContent(result); + writeFile(url, result, inputDir, outputPath); + if (exportFlag) { + writeGlobalESValueFile(removeComments(result), outputPath); + } +} + +function removeComments(content) { + let result = content.replace(/\/\*[\s\S]*?\*\//g, ''); + result = result.replace(/\/\/.*$/gm, ''); + result = result.replace(/^\s*[\r\n]/gm, ''); + return result; } function collectAllIdentifier(node, context) { - const identifierSet = new Set([]); - if (!ts.isSourceFile(node) || !node.statements) { - return identifierSet; + const identifierSet = new Set([]); + if (!ts.isSourceFile(node) || !node.statements) { + return identifierSet; + } + node.statements.forEach((stat) => { + if (!ts.isImportDeclaration(stat)) { + ts.visitEachChild(stat, collectAllNodes, context); } - node.statements.forEach((stat) => { - if (!ts.isImportDeclaration(stat)) { - ts.visitEachChild(stat, collectAllNodes, context); - } - }); + }); - function collectAllNodes(node) { - if (ts.isIdentifier(node)) { - identifierSet.add(node.escapedText.toString()); - } - return ts.visitEachChild(node, collectAllNodes, context); + function collectAllNodes(node) { + if (ts.isIdentifier(node)) { + identifierSet.add(node.escapedText.toString()); } + return ts.visitEachChild(node, collectAllNodes, context); + } - return identifierSet; -} - -/** - * 每个文件处理前回调函数第二个 - * @param {string} url 文件路径 - * @returns {Function} - */ -function formatImportDeclaration(url, copyrightMessage = '', isCopyrightDeleted = false) { - return (context) => { - return (node) => { - sourceFile = node; - const allIdentifierSet = collectAllIdentifier(node, context); // 获取所有标识符 - formatValue = formatAllNodes(url, node, allIdentifierSet); // 获取所有节点 - node = formatValue.node; - const referencesMessage = formatValue.referencesMessage; - if (formatValue.isCopyrightDeleted) { - copyrightMessage = formatValue.copyrightMessage; - isCopyrightDeleted = formatValue.isCopyrightDeleted; - } - outputFile(url, node, sourceFile, referencesMessage, copyrightMessage, isCopyrightDeleted); - return ts.factory.createSourceFile([], ts.SyntaxKind.EndOfFileToken, ts.NodeFlags.None); - }; - }; + return identifierSet; } function getCoreFilename(fileName) { - if (fileName.endsWith(EXTNAME_TS)) { - return fileName.slice(0, -EXTNAME_TS.length); - } - return fileName; + if (fileName.endsWith(EXTNAME_TS)) { + return fileName.slice(0, -EXTNAME_TS.length); + } + return fileName; } function createFrameNodeTypeNode() { - return ts.factory.createModuleDeclaration( - [ - ts.factory.createToken(ts.SyntaxKind.ExportKeyword), - ts.factory.createToken(ts.SyntaxKind.DeclareKeyword) - ], - ts.factory.createIdentifier(TYPENODE), - ts.factory.createModuleBlock([ts.factory.createTypeAliasDeclaration( - undefined, - ts.factory.createIdentifier(XCOMPONENT), - undefined, - ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier(ANY), - undefined - ) - )]), - ts.NodeFlags.Namespace | ts.NodeFlags.ExportContext | ts.NodeFlags.Ambient | ts.NodeFlags.ContextFlags - ); -} - -function addForSpecialFiles(node, newStatements) { - const fileName = getCoreFilename(path.basename(node.fileName)); - if (fileName === FRAMENODE) { - newStatements.push(createFrameNodeTypeNode()); - } -} - -function formatAllNodes(url, node, allIdentifierSet, copyrightMessage = '', isCopyrightDeleted = false) { - let referencesMessage = ''; - let currReferencesModule = []; - if (!ts.isSourceFile(node) || !node.statements) { - return { node, referencesMessage, copyrightMessage, isCopyrightDeleted }; - } - const newStatements = []; - node.statements.forEach((statement) => { - if (ts.isImportDeclaration(statement)) { - const importInfo = formatAllNodesImportDeclaration( - node, - statement, - url, - currReferencesModule, - allIdentifierSet - ); - if (importInfo.statement) { - newStatements.push(statement); - } else if (importInfo.isCopyrightDeleted) { - copyrightMessage = importInfo.copyrightMessage; - isCopyrightDeleted = importInfo.isCopyrightDeleted; - } - } else if (ts.isStructDeclaration(statement)) { - statement = ts.factory.updateStructDeclaration( - statement, - statement.modifiers, - statement.name, - statement.typeParameters, - statement.heritageClauses, - statement.members.slice(1) - ); - newStatements.push(statement); - } else { - newStatements.push(statement); - } - }); - - addForSpecialFiles(node, newStatements); - - currReferencesModule.forEach((item) => { - if (item.isUsed) { - referencesMessage += item.reference + '\n'; - } - }); - node = ts.factory.updateSourceFile(node, newStatements); - return { node, referencesMessage, copyrightMessage, isCopyrightDeleted }; + return ts.factory.createModuleDeclaration( + [ + ts.factory.createToken(ts.SyntaxKind.ExportKeyword), + ts.factory.createToken(ts.SyntaxKind.DeclareKeyword) + ], + ts.factory.createIdentifier(TYPENODE), + ts.factory.createModuleBlock([ts.factory.createTypeAliasDeclaration( + undefined, + ts.factory.createIdentifier(XCOMPONENT), + undefined, + ts.factory.createTypeReferenceNode( + ts.factory.createIdentifier(ANY), + undefined + ) + )]), + ts.NodeFlags.Namespace | ts.NodeFlags.ExportContext | ts.NodeFlags.ContextFlags + ); } function hasCopyright(node) { - return /http\:\/\/www\.apache\.org\/licenses\/LICENSE\-2\.0/g.test(node.getFullText().replace(node.getText(), '')); + return /http\:\/\/www\.apache\.org\/licenses\/LICENSE\-2\.0/g.test(node.getFullText() + .replace(node.getText(), '')); } function getClauseSet(statement) { - // 是import节点 import { AsyncCallback } from './@ohos.base'; - const clauseSet = new Set([]); - if (!statement.importClause || !ts.isImportClause(statement.importClause)) { - return clauseSet; - } - // 标识符 - const clauseNode = statement.importClause; - if (!clauseNode.namedBindings && clauseNode.name && ts.isIdentifier(clauseNode.name)) { - // 没有大括号的标识符 - clauseSet.add(clauseNode.name.escapedText.toString()); - } else if ( - clauseNode.namedBindings && - clauseNode.namedBindings.name && - ts.isIdentifier(clauseNode.namedBindings.name) - ) { - // 没有标识符 *号 - clauseSet.add(clauseNode.namedBindings.name.escapedText.toString()); - } else if (clauseNode.namedBindings && clauseNode.namedBindings.elements) { - // 有花括号的标识符 - clauseNode.namedBindings.elements.forEach((ele) => { - if (ele.name && ts.isIdentifier(ele.name)) { - clauseSet.add(ele.name.escapedText.toString()); - } - }); - } + const clauseSet = new Set([]); + if (!statement.importClause || !ts.isImportClause(statement.importClause)) { return clauseSet; -} - -function getExsitClauseSet(hasImportSpecifierInModules, importSpecifier, currReferencesModule, clauseSet, - allIdentifierSet) { - let currModule = []; - if (hasImportSpecifierInModules) { - let index = globalModules.get(importSpecifier); - currModule = currReferencesModule[index].modules[importSpecifier]; - } - const clasueCheckList = []; - let exsitClauseSet = new Set([]); - for (const clause of clauseSet) { - let flag = allIdentifierSet.has(clause); - if (hasImportSpecifierInModules) { - flag = allIdentifierSet.has(clause) && currModule.includes(clause); - } - if (flag) { - // 标识符使用到了当前import中的引用 - exsitClauseSet.add(clause); - clasueCheckList.push('exist'); - } else { - clasueCheckList.push('non-exist'); - } - } - let hasExsitStatus = false; - let hasNonExsitStatus = false; - clasueCheckList.forEach((ele) => { - if (ele === 'exist') { - hasExsitStatus = true; - } else { - hasNonExsitStatus = true; - } + } + const clauseNode = statement.importClause; + if (!clauseNode.namedBindings && clauseNode.name && ts.isIdentifier(clauseNode.name)) { + clauseSet.add(clauseNode.name.escapedText.toString()); + } else if (clauseNode.namedBindings && ts.isNamespaceImport(clauseNode.namedBindings) && + clauseNode.namedBindings.name && ts.isIdentifier(clauseNode.namedBindings.name)) { + clauseSet.add(clauseNode.namedBindings.name.escapedText.toString()); + } else if (clauseNode.namedBindings && ts.isNamedImports(clauseNode.namedBindings) && + clauseNode.namedBindings.elements) { + clauseNode.namedBindings.elements.forEach((ele) => { + if (ele.name && ts.isIdentifier(ele.name)) { + clauseSet.add(ele.name.escapedText.toString()); + } }); - return { exsitClauseSet, hasExsitStatus, hasNonExsitStatus }; -} - -function handleUsedImport(hasNonExsitStatus, statement, exsitClauseSet, hasImportSpecifierInModules, - currReferencesModule) { - // 有使用到的标识符 - if (hasNonExsitStatus) { - // 有没有使用到的标识符 - const newSpecifiers = []; - statement.importClause.namedBindings.elements.forEach((element) => { - if (exsitClauseSet.has(element.name.escapedText.toString())) { - newSpecifiers.push(element); - } - }); - statement.importClause.namedBindings = ts.factory.updateNamedImports( - statement.importClause.namedBindings, - newSpecifiers - ); - } + } + return clauseSet; +} + +function getExsitClauseSet(hasImportSpecifierInModules, importSpecifier, + currReferencesModule, clauseSet, allIdentifierSet) { + let currModule = []; + if (hasImportSpecifierInModules) { + let index = globalModules.get(importSpecifier); + const referenceModule = currReferencesModule[index]; + currModule = referenceModule.modules[importSpecifier]; + } + const clasueCheckList = []; + let exsitClauseSet = new Set([]); + for (const clause of clauseSet) { + let flag = allIdentifierSet.has(clause); if (hasImportSpecifierInModules) { - let index = globalModules.get(importSpecifier); - currReferencesModule[index].isUsed = true; + flag = allIdentifierSet.has(clause) && currModule.includes(clause); } - return { statement }; -} - - -/** - * 处理Import节点 去除未使用、不存在、References中没有对应模块的导入 - * @param {ts.node} node 当前节点 - * @param {ts.ImportDeclaration} statement 导入节点 - * @param {string} url 文件路径 - * @param {string} url 文件路径 - * @param {Set} allIdentifierSet 该文件的所有Identifier关键字 - * @returns {{statement:ts.ImportDeclaration,copyrightMessage:string,isCopyrightDeleted:boolean}} statement 处理完成的导入节点、copyrightMessage - */ -function formatAllNodesImportDeclaration(node, statement, url, currReferencesModule, allIdentifierSet) { - const clauseSet = getClauseSet(statement); - const importSpecifier = statement.moduleSpecifier.getText().replace(/[\'\"]/g, ''); - const fileDir = path.dirname(url); - let hasImportSpecifierFile = hasFileByImportPath(importSpecifier, fileDir); - let hasImportSpecifierInModules = globalModules.has(importSpecifier); - if ((!hasImportSpecifierFile && !hasImportSpecifierInModules) || clauseSet.size === 0) { - if (hasCopyright(statement)) { - return { copyrightMessage: node.getFullText().replace(node.getText(), ''), isCopyrightDeleted: true }; - } else { - return { statement: undefined, copyrightMessage: '', isCopyrightDeleted: false }; - } - } - const clauseSetValue = - getExsitClauseSet(hasImportSpecifierInModules, importSpecifier, currReferencesModule, clauseSet, - allIdentifierSet); - const hasExsitStatus = clauseSetValue.hasExsitStatus; - const hasNonExsitStatus = clauseSetValue.hasNonExsitStatus; - let exsitClauseSet = clauseSetValue.exsitClauseSet; - if (hasExsitStatus) { - return handleUsedImport(hasNonExsitStatus, statement, exsitClauseSet, hasImportSpecifierInModules, - currReferencesModule); - } else if (hasCopyright(statement)) { - return { copyrightMessage: node.getFullText().replace(node.getText(), ''), isCopyrightDeleted: true }; + if (flag) { + // use import + exsitClauseSet.add(clause); + clasueCheckList.push(EXIST); } else { - return { statement: undefined, copyrightMessage: '', isCopyrightDeleted: false }; - } -} - -/** - * - * 防止@file和@kit段注释丢失 - * @param {string} fileFullText - * @returns {string} - * - */ -function getFileAndKitComment(fileFullText) { - let fileAndKitComment = ''; - let pattern = /\/\*\*\s*\*\s*@file[\s\S]*?@kit[\s\S]*?\*\//; - let comment = fileFullText.match(pattern); - if (comment) { - fileAndKitComment = comment[0]; + clasueCheckList.push(NON_EXIST); + } + } + let hasExsitStatus = false; + let hasNonExsitStatus = false; + clasueCheckList.forEach((ele) => { + if (ele === EXIST) { + hasExsitStatus = true; + } else { + hasNonExsitStatus = true; } - return fileAndKitComment; + }); + return { exsitClauseSet, hasExsitStatus, hasNonExsitStatus }; } -/** - * 处理最终结果中的noninterop - * @param {string} result - */ -function removeNonInteropDoc(result) { - result.split; - return result.replace(/\/\*\*[\s\S]*?\*\//g, (substring, p1) => { - return /@noninterop/g.test(substring) ? '' : substring; +function handleUsedImport(hasNonExsitStatus, statement, + exsitClauseSet, hasImportSpecifierInModules, + currReferencesModule, importSpecifier) { + if (hasNonExsitStatus) { + const newSpecifiers = []; + (statement.importClause.namedBindings).elements.forEach((element) => { + if (exsitClauseSet.has(element.name.escapedText.toString())) { + newSpecifiers.push(element); + } }); + (statement.importClause).namedBindings = ts.factory.updateNamedImports( + statement.importClause.namedBindings, + newSpecifiers + ); + } + if (hasImportSpecifierInModules) { + let index = globalModules.get(importSpecifier); + currReferencesModule[index].isUsed = true; + } + return { statement }; } -function needProcessLabelNonInterop(fileName, kitName) { - if (inputDir.endsWith('component') || fileName.startsWith('@ohos.arkui') || kitName === 'ArkUI') { - return true; - } - return false; +function getFileAndKitComment(fileFullText) { + let fileAndKitComment = ''; + let pattern = /\/\*\*\s*\*\s*@file[\s\S]*?@kit[\s\S]*?\*\//; + let comment = fileFullText.match(pattern); + if (comment) { + fileAndKitComment = comment[0]; + } + return fileAndKitComment; } -/** - * 每个文件处理前回调函数第一个 - * @callback deleteNonInteropApi - * @param {string} url 文件路径 - * @returns {Function} - */ -function deleteNonInteropApi(url) { - return (context) => { - return (node) => { - const fullText = String(node.getFullText()); - //获取文件头部的注释信息--这里可能会涉及到@file和@kit段注释丢失 - let fileAndKitComment = getFileAndKitComment(fullText); - const copyrightMessage = fullText.replace(node.getText(), '').split(/\/\*\*/)[0] + fileAndKitComment + '\n'; - let kitName = ''; - if (fullText.match(/\@kit (.*)\r?\n/g)) { - kitName = RegExp.$1.replace(/\s/g, ''); - } - const fileName = processFileName(url); - sourceFile = node; - const deleteNode = processSourceFile(node, kitName, url); // 处理最外层节点 - node = processVisitEachChild(context, deleteNode.node); - if (needProcessLabelNonInterop(fileName, kitName)) { - const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); - const result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); - ts.transpileModule(result, { - compilerOptions: { - target: ts.ScriptTarget.ES2017, - }, - fileName: fileName, - transformers: { - before: [formatImportDeclaration(url, copyrightMessage, deleteNode.isCopyrightDeleted)] - }, - }); - } - return ts.factory.createSourceFile([], ts.SyntaxKind.EndOfFileToken, ts.NodeFlags.None); - }; - }; +function removeNonInteropDoc(result) { + return result.replace(/\/\*\*[\s\S]*?\*\//g, (substring, p1) => { + return /@noninterop/g.test(substring) ? '' : substring; + }); +} + +function needProcessLabelNonInterop(fileName, kitName, inputDir) { + if (inputDir.endsWith(COMPONENT) || fileName.startsWith(OHOS_ARKUI) || + kitName.toLowerCase() === ARKUI || whiteFileList.includes(fileName.slice(0, -EXTNAME_TS.length))) { + return true; + } + return false; +} + +function setDeleteExport(statement, node, needDeleteExport, + deleteNonInteropApiSet) { + if (ts.isExportAssignment(statement) && + deleteNonInteropApiSet.has((statement.expression).escapedText.toString())) { + needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); + needDeleteExport.default = (statement.expression).escapedText.toString(); + } else if (ts.isExportDeclaration(statement)) { + needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); + (statement.exportClause).elements.forEach((element) => { + const exportName = element.propertyName ? + element.propertyName.escapedText.toString() : + element.name.escapedText.toString(); + if (deleteNonInteropApiSet.has(exportName)) { + needDeleteExport.exportName.add(element.name.escapedText.toString()); + } + }); + } + //export namespace xxx {} + const modifiers = statement.modifiers; + if (modifiers === undefined) { + return; + } + const exportFlag = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword); + const defaultFlag = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword); + if (exportFlag && defaultFlag) { + needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); + needDeleteExport.default = (statement).name.escapedText.toString(); + } else if (exportFlag) { + needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); + needDeleteExport.exportName.add((statement).name.escapedText.toString()); + } } -exports.deleteNonInteropApi = deleteNonInteropApi; - -/** - * 遍历每个文件下的所有节点,然后删除节点 - * @param node - * @returns - */ - -/** - * 处理最外层的节点看是否删除 - * @param node 解析过后的节点 - * @param kitName 当前文件kitName - * @returns - */ -function processSourceFile(node, kitName, url) { - let isCopyrightDeleted = false; - const newStatements = []; - const newStatementsWithoutExport = []; - const deleteNonInteropApiSet = new Set(); - let needDeleteExport = { - fileName: '', - default: '', - exportName: new Set(), - }; - isCopyrightDeleted = addNewStatements(node, newStatements, deleteNonInteropApiSet, needDeleteExport); - newStatements.forEach((statement) => { - const names = getExportIdentifierName(statement); - if (ts.isExportDeclaration(statement) && statement.moduleSpecifier && - statement.moduleSpecifier.text.startsWith('./arkui/component/')) { - const importPath = statement.moduleSpecifier.text.replace('./arkui/component/', ''); - const isDeleteSystemFile = componentEtsDeleteFiles.includes(getPureName(importPath)); - const hasEtsFile = componentEtsFiles.includes(getPureName(importPath)); - const existFile = isExistImportFile(path.dirname(url), statement.moduleSpecifier.text.toString()); - if (isDeleteSystemFile || !hasEtsFile && !existFile) { - return; - } - } - if (names.length === 0) { - newStatementsWithoutExport.push(statement); - return; - } - if (names.length === 1 && !deleteNonInteropApiSet.has(names[0])) { - //exports.name = test; - //export default test1 - //export {test1} - newStatementsWithoutExport.push(statement); - return; - } - processExportNode(statement, node, needDeleteExport, names, deleteNonInteropApiSet, newStatementsWithoutExport); +function getExportIdentifierName(statement) { + const names = []; + if (ts.isExpressionStatement(statement)) { + // exports.name = xxx; + if (ts.isBinaryExpression(statement.expression) && ts.isIdentifier(statement.expression.right) && + statement.expression.right.escapedText) { + names.push(statement.expression.right.escapedText.toString()); + } + } else if (ts.isExportAssignment(statement)) { + // export default xxx + names.push((statement.expression).escapedText.toString()); + } else if (ts.isExportDeclaration(statement) && statement.exportClause) { + // export {xxx} 、export {xxx as yyy} 、export * from './zzz' + const specifiers = (statement.exportClause).elements; + specifiers.forEach((specifier) => { + if (ts.isExportSpecifier(specifier)) { + const name = specifier.propertyName ? specifier.propertyName : specifier.name; + names.push(name.escapedText.toString()); + } }); - if (needDeleteExport.fileName !== '') { - kitFileNeedDeleteMap.set(needDeleteExport.fileName, needDeleteExport); - } - return { - node: ts.factory.updateSourceFile(node, newStatementsWithoutExport, node.isDeclarationFile, - node.referencedFiles), - isCopyrightDeleted, - }; + } + return names; +} + +function addExport2Modifiers( + modifiers) { + modifiers = modifiers || []; + const isAlreadyExported = modifiers.some(m => m.kind === ts.SyntaxKind.ExportKeyword); + if (!isAlreadyExported) { + modifiers = [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword), + ...modifiers]; + } + return modifiers; +} + +function processTypeAliasDeclaration(node, + exportFlag) { + if (exportFlag) { + return ts.factory.updateTypeAliasDeclaration( + node, + addExport2Modifiers(node.modifiers), + node.name, + node.typeParameters, + node.type + ); + } else { + return node; + } +} + +function processInterfaceDeclaration(node, + exportFlag) { + const newMembers = []; + node.members.forEach((member) => { + if (!isNonInterop(member)) { + newMembers.push(member); + } + }); + let modifiers = exportFlag ? addExport2Modifiers(node.modifiers) : node.modifiers; + return ts.factory.updateInterfaceDeclaration( + node, + modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + newMembers + ); +} + +function processClassDeclaration(node, exportFlag) { + const newMembers = []; + node.members.forEach((member) => { + if (!isNonInterop(member)) { + newMembers.push(member); + } + }); + let modifiers = exportFlag ? addExport2Modifiers(node.modifiers) : node.modifiers; + return ts.factory.updateClassDeclaration( + node, + modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + newMembers + ); +} + +function processEnumDeclaration(node, exportFlag) { + const newMembers = []; + node.members.forEach((member) => { + if (!isNonInterop(member)) { + newMembers.push(member); + } + }); + let modifiers = exportFlag ? addExport2Modifiers(node.modifiers) : node.modifiers; + return ts.factory.updateEnumDeclaration( + node, + modifiers, + node.name, + newMembers + ); } -function processExportNode(statement, node, needDeleteExport, names, deleteNonInteropApiSet, newStatementsWithoutExport) { - //删除export节点信息 - if (ts.isExportAssignment(statement)) { - //export default abilityAccessCtrl; - needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); - needDeleteExport.default = statement.expression.escapedText.toString(); - } else if (ts.isExportDeclaration(statement)) { - //export {test1 as test,testa as test2} - let needExport = false; - const newSpecifiers = []; - names.forEach((name, index) => { - const exportSpecifier = statement.exportClause.elements[index]; - if (!deleteNonInteropApiSet.has(name)) { - //未被删除的节点 - newSpecifiers.push(exportSpecifier); - needExport = true; - } else { - //被删除的节点 - needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); - needDeleteExport.exportName.add(exportSpecifier.name.escapedText.toString()); - } - }); - if (needExport) { - statement.exportClause = ts.factory.updateNamedExports(statement.exportClause, newSpecifiers); - newStatementsWithoutExport.push(statement); - } - } +function processStructDeclaration(node) { + const newMembers = []; + node.members.forEach((member, index) => { + if (index >= 1 && !isNonInterop(member)) { + newMembers.push(member); + } + }); + node = ts.factory.updateStructDeclaration( + node, + node.modifiers, + node.name, + node.typeParameters, + node.heritageClauses, + newMembers + ); + return node; } -function addNewStatements(node, newStatements, deleteNonInteropApiSet, needDeleteExport) { - let isCopyrightDeleted = false; - node.statements.forEach((statement, index) => { - if (!isNonInterop(statement)) { - newStatements.push(statement); - return; - } - if (index === 0) { - isCopyrightDeleted = true; - } - if (ts.isVariableStatement(statement)) { - deleteNonInteropApiSet.add(variableStatementGetEscapedText(statement)); - } else if ( - ts.isModuleDeclaration(statement) || - ts.isInterfaceDeclaration(statement) || - ts.isClassDeclaration(statement) || - ts.isEnumDeclaration(statement) || - ts.isStructDeclaration(statement) || - ts.isTypeAliasDeclaration(statement) - ) { - if (statement && statement.name && statement.name.escapedText) { - deleteNonInteropApiSet.add(statement.name.escapedText.toString()); - } - setDeleteExport(statement, node, needDeleteExport, deleteNonInteropApiSet); - } else if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { - setDeleteExport(statement, node, needDeleteExport, deleteNonInteropApiSet); - } - }); - - return isCopyrightDeleted; +function variableStatementGetEscapedText(statement) { + let name = ''; + if ( + statement && + statement.declarationList && + statement.declarationList.declarations && + statement.declarationList.declarations.length > 0 && + statement.declarationList.declarations[0].name && + (statement.declarationList.declarations[0].name).escapedText + ) { + name = (statement.declarationList.declarations[0].name).escapedText.toString(); + } + return name; } -function setDeleteExport(statement, node, needDeleteExport, deleteNonInteropApiSet) { - if (ts.isExportAssignment(statement) && deleteNonInteropApiSet.has(statement.expression.escapedText.toString())) { - needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); - needDeleteExport.default = statement.expression.escapedText.toString(); - } else if (ts.isExportDeclaration(statement)) { - needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); - statement.exportClause.elements.forEach((element) => { - const exportName = element.propertyName ? - element.propertyName.escapedText.toString() : - element.name.escapedText.toString(); - if (deleteNonInteropApiSet.has(exportName)) { - needDeleteExport.exportName.add(element.name.escapedText.toString()); - } - }); - } - //export namespace test {} - const modifiers = statement.modifiers; - if (modifiers === undefined) { - return; - } - const exportFlag = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword); - const defaultFlag = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword); - if (exportFlag && defaultFlag) { - needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); - needDeleteExport.default = statement.name.escapedText.toString(); - } else if (exportFlag) { - needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); - needDeleteExport.exportName.add(statement.name.escapedText.toString()); +function isNonInterop(node) { + const notesContent = node.getFullText().replace(node.getText(), '').replace(/[\s]/g, ''); + const notesArr = notesContent.split(/\/\*\*/); + for (const note of notesArr) { + if (note.length !== 0 && /@noninterop/g.test(note)) { + return true; } + } + return false; } -/** - * 获取export节点的名字,只获取第一个关键词 - * @param {ts.node} statement - * @returns {Array} - */ -function getExportIdentifierName(statement) { - const names = []; - if (ts.isExpressionStatement(statement)) { - //exports.name = test; - if (ts.isBinaryExpression(statement.expression) && statement.expression.right.escapedText) { - names.push(statement.expression.right.escapedText.toString()); - } - } else if (ts.isExportAssignment(statement)) { - //export default test1 - names.push(statement.expression.escapedText.toString()); - } else if (ts.isExportDeclaration(statement) && statement.exportClause) { - //export {test1} 、export {test1 as test} 、export * from './featureability' - const specifiers = statement.exportClause.elements; - specifiers.forEach((specifier) => { - if (ts.isExportSpecifier(specifier)) { - const name = specifier.propertyName ? specifier.propertyName : specifier.name; - names.push(name.escapedText.toString()); - } - }); - } - return names; -} +exports.transformFiles = transformFiles; -/** - * 遍历处理tsnode节点 - * @param context 解析过后的内容 - * @param node 解析过后的节点 - * @returns ts.node - */ -function processVisitEachChild(context, node) { - return ts.visitEachChild(node, processAllNodes, context); // 遍历所有子节点 - - function getNewStatements(node) { - const newStatements = []; - node.body.statements.forEach((statement) => { - if (!isNonInterop(statement)) { - newStatements.push(statement); - } - }); - return newStatements; - } +let outputPath = ''; +let inputDir = ''; +let exportFlag = false; - function processAllNodes(node) { - if (ts.isInterfaceDeclaration(node)) { - node = processInterfaceDeclaration(node); - } else if (ts.isClassDeclaration(node)) { - node = processClassDeclaration(node); - } else if (ts.isModuleDeclaration(node) && node.body && ts.isModuleBlock(node.body)) { - const newModuleBody = ts.factory.updateModuleBlock(node.body, getNewStatements(node)); - node = ts.factory.updateModuleDeclaration( - node, - node.modifiers, - node.name, - newModuleBody - ); - } else if (ts.isEnumDeclaration(node)) { - node = processEnumDeclaration(node); - } else if (ts.isStructDeclaration(node)) { - node = processStructDeclaration(node); - } else if (ts.isTypeAliasDeclaration(node)) { - node = processTypeAliasDeclaration(node); - } - return ts.visitEachChild(node, processAllNodes, context); - } -} +let sourceFile = null; +let componentEtsFiles = []; +let componentEtsDeleteFiles = []; +const kitFileNeedDeleteMap = new Map(); +const stmtReplacementMap = new Map(); +const globalModules = new Map(); -function addExport2Modifiers(modifiers) { - modifiers = modifiers || []; - const isAlreadyExported = modifiers.some(m => m.kind === ts.SyntaxKind.ExportKeyword); - if (!isAlreadyExported) { - modifiers = [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword), ...modifiers]; - } - return modifiers; -} +const GLOBAL_ESVALUE_FILE = '@ohos.arkui.GlobalESValue.d.ts'; +const ARKUI = 'arkui'; +const ARKTS = 'arkts'; +const COMPONENT = 'component'; -/** - * 处理type子节点 - */ -function processTypeAliasDeclaration(node) { - if (exportFlag) { - return ts.factory.updateTypeAliasDeclaration( - node, - node.decorators, - addExport2Modifiers(node.modifiers), - node.name, - node.typeParameters, - node.type - ); - } else { - return node; - } -} +const ANY = 'Any'; +const EXTNAME_D_TS = '.d.ts'; +const EXTNAME_D_ETS = '.d.ets'; +const EXTNAME_TS = '.ts'; +const EXTNAME_ETS = '.ets'; +const ETS = 'ets'; +const INTERNAL = '@internal'; +const EXIST = 'exist'; +const NON_EXIST = 'non-exist'; +const OHOS_ARKUI = '@ohos.arkui'; -/** - * 处理interface子节点 - */ -function processInterfaceDeclaration(node) { - const newMembers = []; - node.members.forEach((member) => { - if (!isNonInterop(member)) { - newMembers.push(member); - } - }); - let modifiers = exportFlag ? addExport2Modifiers(node.modifiers) : node.modifiers; - return ts.factory.updateInterfaceDeclaration( - node, - modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - newMembers - ); -} +const FRAMENODE = 'FrameNode'; +const TRUE = 'true'; +const TYPENODE = 'typeNode'; +const XCOMPONENT = 'XComponent'; +const ALERT_DIALOG = 'alert_dialog'; +const ALERT_DIALOG_TEXT_STYLE = 'AlertDialogTextStyle'; +const COMMON = 'common'; +const COMMON_LINEAR_GRADIENT = 'CommonLinearGradient'; -/** - * 处理class子节点 - */ -function processClassDeclaration(node) { - const newMembers = []; - node.members.forEach((member) => { - if (!isNonInterop(member)) { - newMembers.push(member); - } - }); - let modifiers = exportFlag ? addExport2Modifiers(node.modifiers) : node.modifiers; - return ts.factory.updateClassDeclaration( - node, - modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - newMembers - ); -} +const whiteFileList = [ + 'web', +]; -/** - * 处理enum子节点 - */ -function processEnumDeclaration(node) { - const newMembers = []; - node.members.forEach((member) => { - if (!isNonInterop(member)) { - newMembers.push(member); - } - }); - let modifiers = exportFlag ? addExport2Modifiers(node.modifiers) : node.modifiers; - return ts.factory.updateEnumDeclaration( - node, - modifiers, - node.name, - newMembers - ); -} +const specialFileList = [ + 'alert_dialog', + 'common', +]; -/** - * 处理struct子节点 - */ -function processStructDeclaration(node) { - const newMembers = []; - node.members.forEach((member, index) => { - if (index >= 1 && !isNonInterop(member)) { - newMembers.push(member); - } +function start() { + const program = new commander.Command(); + program + .name('noninterop') + .version('0.0.1'); + program + .option('--input ', 'input path') + .option('--output ', 'output path') + .option('--export ', 'export flag', false) + .action((opts) => { + outputPath = opts.output; + inputDir = opts.input; + exportFlag = opts.export === TRUE; + transformFiles(inputDir, outputPath, exportFlag); }); - node = ts.factory.updateStructDeclaration( - node, - node.modifiers, - node.name, - node.typeParameters, - node.heritageClauses, - newMembers - ); - return node; + program.parse(process.argv); } -function variableStatementGetEscapedText(statement) { - let name = ''; - if ( - statement && - statement.declarationList && - statement.declarationList.declarations && - statement.declarationList.declarations.length > 0 && - statement.declarationList.declarations[0].name && - statement.declarationList.declarations[0].name.escapedText - ) { - name = statement.declarationList.declarations[0].name.escapedText.toString(); - } - return name; -} - -function isNonInterop(node) { - const notesContent = node.getFullText().replace(node.getText(), '').replace(/[\s]/g, ''); - const notesArr = notesContent.split(/\/\*\*/); - for (const note of notesArr) { - if (note.length !== 0 && /@noninterop/g.test(note)) { - return true; - } - } - return false; -} - -let outputPath = ''; -let inputDir = ''; -let exportFlag = false; start(); -- Gitee