mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-26 04:19:33 +08:00
fix(c): a macro alone below an #include <…> no longer hides the next declaration (#2709)
blankLoneMacroLines blanks a macro alone on its line, like FMT_BEGIN_NAMESPACE, before C and C++ parse, unless the line above ends in an operator it could be an operand of. A directive like `#include <glib/gtypes.h>` ends in `>`, so GLib's G_BEGIN_DECLS below it stayed, and the parser read `G_BEGIN_DECLS typedef struct _GBytes GBytes;` as one broken declaration. The first declaration of nearly every GLib header went missing (GBytes, GError, GHashTable, GList, GQuark, the GIOCondition enum), a few headers grew junk functions (one named `enum` swallowing a whole header), and the parse error kept the file off the native kernel. Objective-C already read a directive as ending at its line (#2691, directivesEnd). C and C++ now do too, so the flag goes: a directive continues only through a trailing backslash. The kernel takes C and C++ input from the hoisted preParse, so it needs no change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
90e2456b43
commit
a31bf2f476
@@ -1213,7 +1213,10 @@ export function blankCppAnnotationMacroCalls(source: string): string {
|
||||
* (`=`, an operator, `,`, `(`, `?`, `:`, or a `\` macro-definition
|
||||
* continuation) — so an ALL-CAPS operand split onto its own line inside a
|
||||
* multi-line expression (`int x =\n SOME_CONST\n | OTHER;`) is left
|
||||
* alone; and
|
||||
* alone. A preprocessor directive ends at its own line, even one that
|
||||
* ends in `>`: GLib's `G_BEGIN_DECLS` below `#include <glib.h>`, and
|
||||
* Objective-C's `NS_ASSUME_NONNULL_BEGIN` below `#import
|
||||
* <Foundation/Foundation.h>`, are blanked; and
|
||||
* - the NEXT line of code starts like a declaration/scope token
|
||||
* (letter, `_`, `#`, `{`, `}`, or `~`) or the file ends — an operator,
|
||||
* string literal, or `;` continuation rejects the match. Comments in
|
||||
@@ -1229,29 +1232,23 @@ const LONE_MACRO_CONTINUATION_END_RE = /[=+\-*/%&|^<>?:,(\\]$/;
|
||||
interface LoneMacroRules {
|
||||
/** What the code after the macro may start with. */
|
||||
nextCode: RegExp;
|
||||
/** Whether a preprocessor directive above the macro ends at its own line. */
|
||||
directivesEnd: boolean;
|
||||
/** Whether a macro that is a body's only statement, between `{` and `}`, stays. */
|
||||
keepsSoleStatement: boolean;
|
||||
}
|
||||
|
||||
const C_LONE_MACROS: LoneMacroRules = { nextCode: /[A-Za-z_#{}~]/, directivesEnd: false, keepsSoleStatement: false };
|
||||
const C_LONE_MACROS: LoneMacroRules = { nextCode: /[A-Za-z_#{}~]/, keepsSoleStatement: false };
|
||||
|
||||
/**
|
||||
* Objective-C's: the code after the macro may be a directive, like the
|
||||
* `@interface` below `NS_ASSUME_NONNULL_BEGIN` or the `@end` below
|
||||
* `OF_SINGLETON_METHODS`. A preprocessor line above it continues nothing,
|
||||
* even one that ends in `>`, like the `#import <Foundation/Foundation.h>`
|
||||
* above most headers' `NS_ASSUME_NONNULL_BEGIN`. Blanking that macro but not
|
||||
* another before the same `@interface` (`OF_SUBCLASSING_RESTRICTED`) left
|
||||
* `OF_ASSUME_NONNULL_BEGIN @interface …`, which reads as a function.
|
||||
* `OF_SINGLETON_METHODS`.
|
||||
*
|
||||
* A macro that is a method's whole body, like ObjFW's `{
|
||||
* OF_UNRECOGNIZED_SELECTOR }`, stays: the parser's error there stays inside
|
||||
* that body, but blanking it changed how the parser recovered from an
|
||||
* earlier misread, and OFMutableString.m lost 11 calls in the methods below.
|
||||
*/
|
||||
export const OBJC_LONE_MACROS: LoneMacroRules = { nextCode: /[A-Za-z_#{}~@]/, directivesEnd: true, keepsSoleStatement: true };
|
||||
export const OBJC_LONE_MACROS: LoneMacroRules = { nextCode: /[A-Za-z_#{}~@]/, keepsSoleStatement: true };
|
||||
|
||||
export function blankLoneMacroLines(source: string, rules: LoneMacroRules = C_LONE_MACROS): string {
|
||||
if (!/^[ \t]*[A-Z][A-Z0-9_]{3,}[ \t]*\r?$/m.test(source)) return source;
|
||||
@@ -1274,7 +1271,7 @@ export function blankLoneMacroLines(source: string, rules: LoneMacroRules = C_LO
|
||||
// continues nothing either.
|
||||
const prevText = prev >= 0 ? content(lines[prev] as string) : '';
|
||||
const prevCode = /^(?:\/\/|\/\*|\*)/.test(prevText) ? '' : prevText.replace(/\/\*.*?\*\/|\/\/.*$/g, '').trim();
|
||||
const directiveEnds = rules.directivesEnd && prevCode.startsWith('#') && !prevCode.endsWith('\\');
|
||||
const directiveEnds = prevCode.startsWith('#') && !prevCode.endsWith('\\');
|
||||
if (prevCode !== '' && !directiveEnds && !/^template\s*</.test(prevCode) && LONE_MACRO_CONTINUATION_END_RE.test(prevCode)) continue;
|
||||
const first = firstCodeCharAfter(lines, i + 1);
|
||||
if (first !== undefined && !rules.nextCode.test(first)) continue;
|
||||
|
||||
Reference in New Issue
Block a user