WEBA

שרת השפה של Go מוסיף ריפקטורינג אינטראקטיבי

גרסאות חדשות לשרת השפה ולהרחבת העריכה מוסיפות דיאלוגים מרובי שלבים להוספת תגיות ומימוש ממשקים, על בסיס הרחבה פתוחה לתקן שפותחה עם צוות Dart.

654 מילים23 עובדות אומתו

עריכת קוד ב־Go מחוץ לסביבות פיתוח כבדות דרשה עד היום סבלנות יוצאת דופן לפעולות בסיסיות. בזמן שמשתמשי GoLand נהנו מקיצורי מקלדת שמייצרים קוד לפי דרישה, מפתחים שבחרו בעורכים קלים נאלצו לתקתק struct tags ידנית או להסתמך על תוספים צד שלישי שנוטים להישבר בכל עדכון. עכשיו, צוות הפיתוח של השפה מביא את הדיאלוגים האינטראקטיביים ישירות לתוך gopls.

השבוע פורסם בבלוג הרשמי של Go כי שרת השפה מתחדש ביכולת לנהל שיחה אמיתית עם המפתח. העדכון נשען על v0.24.0 של שרת השפה ועל הרחבת VS Code בגרסה v0.56.0. מי שמנהל שירותי ענן בישראל ב־Go מקבל סוף סוף סביבת עבודה קלה שלא מתפשרת על פעולות תחזוקה שוטפות.

סוף לעיוורון של פקודות הקוד

הבעיה שעיכבה את הפיתוח הזה במשך שנים אינה קשורה למנוע הפנימי של Go, אלא למבנה של Language Server Protocol (LSP). הפרוטוקול תוכנן כך שפעולות קוד רגילות התנהגו כמו פונקציות ללא פרמטרים: המשתמש מפעיל פקודה, והשרת מחזיר מיד את עריכות הטקסט. החריג היחיד עד כה היה שינוי שם של סמל, שדרש קריאה ייעודית נפרדת בפרוטוקול כדי לקלוט שם חדש מהמשתמש.

המגבלה אינה ביכולת של gopls לחשב את העריכות הנדרשות, אלא בהיעדרו של מנגנון בתוך LSP המאפשר לשרתי שפה לבקש קלט מהמשתמש.הונגשיאנג ג׳יאנג, מהנדס בצוות Go, בבלוג הרשמי

במקום להטמיע טפסים ייעודיים שנעולים לעורך בודד, צוות Go חבר לצוות Dart. השניים גיבשו את LSP interactive refactoring proposal, שנמצאת בדיון בקהילת התקינה תחת microsoft/language-server-protocol#1164. ההרחבה מאפשרת לשרת השפה להציג תיבות קלט ורשימות בחירה מרובות שלבים בעורך, בלי שהעורך יצטרך להכיר את החוקים הפנימיים של שפת התכנות.

שלושה חידושים שעובדים כבר היום

החידוש הראשון מורגש בהוספת תגיות למבנים. במקום להזריק אוטומטית שדות JSON בתבנית camelCase ללא שאלות, הפקודה מציגה שדה קלט שבו אפשר לציין שילוב של תגיות כמו json, yaml ו־db. שלב נוסף מאפשר לבחור את סגנון השמות הרצוי, למשל snake_case או PascalCase, והשרת מעדכן את כל השדות בהתאם.

היכולת השנייה היא הסרה בררנית של תגיות. בעבר, מחיקת תגיות מחקה את כל המאפיינים של המבנה ללא הבחנה. עכשיו המערכת שואלת אילו מפתחות תרצו להסיר, ומאפשרת למחוק תגיות db בלבד תוך שמירה על הגדרות הסריאליזציה של הרשת.

היכולת השלישית פותרת את מימוש הממשקים. כשמפעילים את הפעולה על טיפוס בטקסט, העורך פותח שדה חיפוש דינמי המשלים שמות מתוך חבילות הפרויקט והספרייה הסטנדרטית. אם בממשק יש טיפוסים כלליים (generics), השרת מבקש מהמפתח להזין את הטיפוס הקונקרטי ומייצר שלד מתודות שלם עם שמות ה־receiver המתאימים. לא צריך יותר לזכור חתימות בעל פה.

לצד פעולות הייצור, המפתחים כללו פקודת הדגמה בשם Slay the dragon שמופעלת על משתנה בשם dragonSlayer, כדי לבדוק שהדיאלוגים הרב שלביים פועלים כסדרם בעורך.

פתוח בתקן, מוגבל בינתיים בעורך

למרות שהתקן תוכנן כסטנדרט פתוח לכלל השפות והעורכים, התמיכה המלאה והעובדת זמינה כרגע רק ב־VS Code.

למרות שהפרוטוקול תוכנן לשרת כל לקוח, התמיכה המלאה והיציבה מוטמעת נכון לעכשיו רק בהרחבה הרשמית של VS Code. מי שעובד בעורכים פופולריים אחרים יגלה שהדרך ארוכה יותר: עבור Neovim קיים כרגע רק מימוש ניסיוני לבדיקת היתכנות, ומצב דומה קיים בתוספים עבור Emacs. משתמשי עורכים קלים אחרים כמו Helix יצטרכו להמתין עד שצוותי הפיתוח של אותם כלים יטמיעו את מפרט הטפסים.

גם עורכי קוד מבוססי בינה מלאכותית כמו Cursor נשענים על תשתית LSP, אך אימוץ רשמי תלוי בקצב שבו מיקרוסופט תמזג את ההצעה לתקן הכללי. בנוסף, לא פורסם מידע על התנהגות החיפוש הדינמי במאגרי ענק (monorepos) עתירי קוד.

הזזת קוד ועדכון חתימות בקנה

מעבר למה שכבר שוחרר, צוות השפה מציג גרסת תצוגה מקדימה ליכולת העברת הצהרות (Move Declaration), שנמצאת במעקב תחת golang/go#70583. הפעולה מאפשרת לבחור טיפוס ולהעביר אותו לקובץ אחר או לחבילה חדשה דרך בורר קבצים. השרת מעביר איתו מתודות וקבועים פרטיים שקשורים אליו, משאיר קוד בלתי תלוי במקומו ומעדכן אוטומטית את הייבוא בכל הפרויקט.

על פי מפת הדרכים, השלב הבא הוא שינוי חתימות פונקציה (Change Signature) תחת golang/go#38028. שינוי של סדר פרמטרים או הוספת ארגומנטים דורשים הגדרת ערכי ברירת מחדל בכל נקודות הקריאה בקוד, משימה שאי אפשר לבצע בלי שאלון מקדים למפתח. בעתיד המנגנון ישמש גם לפעולות שאינן עריכת טקסט, כמו הגדרת פרופילים של מעבד וזיכרון בריצות מבחנים דרך שכבת ה־command.

זמינות יכולות הריפקטורינג האינטראקטיביות בשרת השפה של Go
יכולת ריפקטורינגסטטוס זמינותגרסת מינימום נדרשתדרישות קלט מהמשתמש
הוספת תגיות מבנה (Struct Tags)זמיןgopls v0.23.0 / vscode-go v0.56.0הזנת שמות תגיות ובחירת סגנון אותיות
הסרת תגיות מבנהזמיןgopls v0.23.0 / vscode-go v0.56.0בחירת מפתחות ספציפיים למחיקה
מימוש ממשקים (Implement Interface)זמיןgopls v0.23.0 / vscode-go v0.56.0חיפוש שם ממשק והזנת ארגומנטי טיפוס
העברת הצהרות בין קבצים וחבילותתצוגה מקדימהגרסאות gopls הבאותבחירת נתיב לקובץ יעד קיים או חדש
שינוי חתימת פונקציה (Change Signature)בתכנוןלא פורסםהגדרת סדר פרמטרים וערכי ברירת מחדל

כדי להתחיל לעבוד עם הכלים החדשים אין צורך בהגדרות מיוחדות. שדרגו את שרת השפה gopls לגרסה v0.24.0, ודאו שתוסף Go ב־VS Code מעודכן לגרסה v0.56.0, ותיבות הקלט יופיעו אוטומטית ברגע שתפעילו את פעולות הקוד מהתפריט הרגיל. מה שבאמת מעניין כאן הוא שמי שמשלם על רישיונות GoLand רק בשביל יצירת תגיות ומימוש ממשקים יכול לשקול מחדש את ההוצאה. המרחק בין השניים הצטמצם בעוד צעד.

מה לעשות עכשיושדרגו את gopls לגרסה v0.24.0 ואת תוסף VS Code ל־v0.56.0 כדי לקבל דיאלוגים מובנים ליצירת תגיות ומימוש ממשקים ישירות בעורך.

מקורות

הידיעה נכתבה מהמקורות שלמעלה בתאריך הפרסום, וכל טענה בה נבדקה מולם. מצאתם טעות? כתבו.

מה שואלים על זה

איך מפעילים את הריפקטורינג האינטראקטיבי בקוד קיים?

מציבים את הסמן על הגדרת טיפוס, מבנה או הצהרה מתאימה, פותחים את תפריט פעולות הקוד הרגיל (Code Actions) בעורך, ובוחרים בפעולה המבוקשת. העורך יציג תיבת טקסט או תפריט בחירה לקבלת הפרמטרים לפני החלת השינויים.

האם היכולת החדשה זמינה כרגע בעורכי Neovim או Helix?

עבור Neovim קיים כרגע מימוש בדיקת היתכנות ראשוני בענף פיתוח ייעודי, אך התמיכה אינה חלק מהגרסה הרשמית היציבה. בעורכים אחרים כמו Helix ו־Emacs היכולת אינה מובנית ודורשת פיתוח נוסף בצד הלקוח.

מדוע היה צורך לשנות את פרוטוקול LSP במקום להוסיף תוסף ייעודי לעורך?

תוספים ייעודיים לעורכים שוברים את העירון המרכזי של LSP, שנועד להפריד בין תכונות שפה לבין תוכנת העריכה. הרחבת התקן מאפשרת לכל עורך שתומך בפרוטוקול ליהנות מאותן יכולות שרת בלי לתחזק קוד ייעודי לכל שפת תכנות בנפרד.

מה נדרש כדי לקבל את העדכון כבר עכשיו?

יש להתקין את שרת השפה gopls בגרסה v0.24.0 ומעלה, ולוודא שהרחבת Go הרשמית ב־VS Code מעודכנת לגרסה v0.56.0 ומעלה.