برای اینکه solutionهایی که تفاوتهای غیرضروری دارند، representation یکسانی داشته باشند، Representer باید نرمالسازیها را اعمال کند. بهطور کلی، فرایند ساختن یک representation نرمالشده اینطور است:
representation.txt بنویسید (به رابط نگاه کنید)البته توجه کنید که representation لزوماً نباید یک AST باشد؛ میتواند کد معمولی (نرمالشده) باشد، هرکدام که برای track شما بهتر جواب میدهد.
برای اینکه شروع کار راحتتر شود، حالا چند راهبرد رایج نرمالسازی را معرفی میکنیم.
نکته ۱: مثالهای نرمالسازی بر پایهی یکدیگر بنا نشدهاند؛ هرکدام فقط یک نرمالسازی مشخص را نشان میدهند. یک Representer واقعی اینها را پشت سر هم اعمال میکند.
نکته ۲: کد این راهنماها به زبان C# نوشته شده است، اما خودِ راهنماها به زبان خاصی وابسته نیستند.
برای اینکه representationها مستقل از اسمگذاری باشند، میتوان اسمهای تعریفشده توسط کاربر (مثل متغیرها، توابع و غیره) را با «جانگهدارها» جایگزین کرد. در این حالت باید یک mapping.json تولید شود (به رابط نگاه کنید).
نکتهی مهم این است که همهی اسمهای یکسان، صرفنظر از «محدوده»، باید با جانگهدار یکسانی جایگزین شوند.
public static class Fake
{
public static int Test(int input)
{
var test = input + 2;
return test;
}
}
public static class PLACEHOLDER_1
{
public static int PLACEHOLDER_2(int PLACEHOLDER_3)
{
var PLACEHOLDER_4 = PLACEHOLDER_3 + 2;
return PLACEHOLDER_4;
}
}
فضای سفید ناهماهنگ آنقدر رایج است که نرمالسازی آن به یک مرحلهی معمول تبدیل شده است. پایان خطوط را هم باید نرمال کرد.
using System;
public static class Fake
{
public static DateTime Add (DateTime birthDate)
{
return birthDate.Add( TimeSpan.FromSeconds ( 10 ) ) ;
}
}
public static class Fake
{
public static DateTime Add(DateTime birthDate)
{
return birthDate.Add(TimeSpan.FromSeconds(10));
}
}
در بسیاری از زبانها، کاربر در نحوهی تعریف یک «بلوک» (یا محدوده) آزادی عمل دارد. برای مثال، در بیشتر زبانهای شبیه به C، محدوده بین آکولادها تعریف میشود. معمولاً مهم نیست که آنها را در همان خط بگذارید یا خط بعد؛ پس میتوان این را نرمال کرد.
public static class Fake {
public static int Test() {
if (1 > 2) {
return 0;
}
return 1;
}
}
public static class Fake
{
public static int Test()
{
if (1 > 2)
{
return 0;
}
return 1;
}
}
همهی بخشهای کد برای Representer مهم نیستند و میتوان آنها را حذف کرد. برای مثال، در بیشتر زبانها کامنتها بیاهمیتاند و میتوان با خیال راحت حذفشان کرد.
/*
These are some very nice
comments spanning multiple lines
*/
public static class Fake
{
// Nice method
public static string Test()
{
return "Test"; // This is very nice
}
}
public static class Fake
{
public static string Test()
{
return "Test";
}
}
در بعضی موارد، ترتیب کد اهمیتی ندارد. برای اینکه کد یکسان با ترتیب متفاوت، representationهای متفاوتی تولید نکند، مرتبکردن آن میتواند مفید باشد. معمولاً مواردی که باید مرتب شوند، توابع یا اعلانها هستند. پیدا کردن معیار (معیارهای) مرتبسازی و همچنین پیادهسازی آن ممکن است دشوار باشد. یک معیار میتواند تعداد فرزندان گرهی AST باشد، و معیار دیگر، اسم نوع اولین گرهی فرزند.
این مثال بر اساس نوعی از طول تابع مرتب میکند:
public static class Fake
{
public static string Test2()
{
int a = "Test2";
return a;
}
public static string Test()
{
return "Test";
}
}
public static class Fake
{
public static string Test()
{
return "Test";
}
public static string Test2()
{
int a = "Test2";
return a;
}
}