Example #1
0
		// Claim all local symbols in this scope, preventing use
		// by the symbol allocator.  Used on the global scope to
		// reserve global symbols
		public void ClaimSymbols(SymbolAllocator symbols)
		{
			foreach (var i in Symbols)
			{
				var s = i.Value;
				if (s.Scope == Symbol.ScopeType.local && s.Accessibility==Accessibility.Public)
				{
					symbols.ClaimSymbol(s.Name);
				}
			}
		}
Example #2
0
		// Obfuscate all local symbols
		//  - enumerate all local symbols and tell the symbol allocator
		//    that it can be obfuscated.
		//	- where there are `holes` in the rank mapping, tell the symbol
		//    allocator to reserve those symbols.  These holes are to be
		//    filled by higher frequency symbols on the inner scopes.
		public void ObfuscateSymbols(RenderContext ctx, SymbolFrequency SymbolFrequency, SymbolAllocator Allocator, string prefix)
		{
			// Walk through local symbols
			int expectedRank = 0;
			foreach (var symbol in SymbolFrequency.Sort())
			{
				// Ignore public symbols
				if (symbol.Accessibility != Accessibility.Private)
					continue;

				// Ignore non-local symbols
				if (symbol.Scope != Symbol.ScopeType.local)
					continue;

				// Reserve space for inner, higher frequency symbols
				if (symbol.Rank > expectedRank)
				{
					if (ctx.Compiler.Formatted && ctx.Compiler.SymbolInfo)
					{
						for (int r = expectedRank; r < symbol.Rank; r++)
						{
							ctx.StartLine();
							ctx.AppendFormat("// #{0} reserved", r);
						}
					}
					Allocator.ReserveObfuscatedSymbols(symbol.Rank - expectedRank);
				}

				string newSymbol = Allocator.OnfuscateSymbol(symbol.Name);

				// Show info
				if (ctx.Compiler.Formatted && ctx.Compiler.SymbolInfo)
				{
					ctx.StartLine();
					ctx.AppendFormat("// #{0} {3}{1} -> {3}{2}", symbol.Rank, symbol.Name, newSymbol, prefix);
				}

				expectedRank = symbol.Rank + 1;
			}
		}
Example #3
0
        // Compile all loaded script to a string
        public string CompileJavascriptToString()
        {
            // Create a symbol allocator
            SymbolAllocator SymbolAllocator = new SymbolAllocator(this);

            // Don't let the symbol allocator use any reserved words or common Javascript bits
            // We only go up to three letters - symbol allocation of more than 3 letters is
            // highly unlikely.
            // (based on list here: http://www.quackit.com/javascript/javascript_reserved_words.cfm)
            string[] words = new string[] { "if", "in", "do", "for", "new", "var", "int", "try", "NaN", "ref", "sun", "top" };
            foreach (var s in words)
            {
                SymbolAllocator.ClaimSymbol(s);
            }

            // Create a member allocator
            SymbolAllocator MemberAllocator = new SymbolAllocator(this);

            // Render
            RenderContext r = new RenderContext(this, SymbolAllocator, MemberAllocator);

            // Process all files
            bool bNeedSemicolon = false;

            foreach (var file in m_files)
            {
                Console.WriteLine("Processing {0}...", System.IO.Path.GetFileName(file.filename));

                // Create a tokenizer and parser
                Warnings             = new List <Warning>();
                WarningsEnabledStack = new Stack <bool>();
                Tokenizer t = new Tokenizer(this, file.content, file.filename, file.warnings);
                Parser    p = new Parser(t);

                // Create the global statement block
                var code = new ast.CodeBlock(null, TriState.No);

                // Parse the file into a namespace
                p.ParseStatements(code);

                // Ensure everything processed
                if (t.more)
                {
                    throw new CompileError("Unexpected end of file", t);
                }


                // Dump the abstract syntax tree
                if (DumpAST)
                {
                    code.Dump(0);
                }

                // Create the root symbol scope and build scopes for all
                // constained function scopes
                SymbolScope rootScope       = new SymbolScope(this, null, Accessibility.Public);
                SymbolScope rootPseudoScope = new SymbolScope(this, null, Accessibility.Public);
                code.Visit(new VisitorScopeBuilder(rootScope, rootPseudoScope));

                // Combine consecutive var declarations into a single one
                code.Visit(new VisitorCombineVarDecl(rootScope));

                // Find all variable declarations
                code.Visit(new VisitorSymbolDeclaration(rootScope, rootPseudoScope));

                // Do lint stuff
                code.Visit(new VisitorLint(rootScope, rootPseudoScope));

                // Try to eliminate const declarations
                if (DetectConsts && !NoObfuscate)
                {
                    code.Visit(new VisitorConstDetectorPass1(rootScope));
                    code.Visit(new VisitorConstDetectorPass2(rootScope));
                    code.Visit(new VisitorConstDetectorPass3(rootScope));
                }

                // Simplify expressions
                code.Visit(new VisitorSimplifyExpressions());

                // If obfuscation is allowed, find all in-scope symbols and then
                // count the frequency of their use.
                if (!NoObfuscate)
                {
                    code.Visit(new VisitorSymbolUsage(rootScope));
                }

                // Process all symbol scopes, applying default accessibility levels
                // and determining the "rank" of each symbol
                rootScope.Prepare();

                // Dump scopes to stdout
                if (DumpScopes)
                {
                    rootScope.Dump(0);
                }

                // Tell the global scope to claim all locally defined symbols
                // so they're not re-used (and therefore hidden) by the
                // symbol allocation
                rootScope.ClaimSymbols(SymbolAllocator);

                // Create a credit comment on the first file
                if (!NoCredit && file == m_files[0])
                {
                    int iInsertPos = 0;
                    while (iInsertPos < code.Content.Count && code.Content[iInsertPos].GetType() == typeof(ast.StatementComment))
                    {
                        iInsertPos++;
                    }
                    code.Content.Insert(iInsertPos, new ast.StatementComment(null, "// Minified by MiniME from toptensoftware.com"));
                }

                if (bNeedSemicolon)
                {
                    r.Append(";");
                }

                // Render it
                r.EnterScope(rootScope);
                bNeedSemicolon = code.Render(r);
                r.LeaveScope();

                // Display warnings
                Warnings.Sort(delegate(Warning w1, Warning w2)
                {
                    int Compare = w1.Order.file.FileName.CompareTo(w2.Order.file.FileName);
                    if (Compare == 0)
                    {
                        Compare = w1.Order.position - w2.Order.position;
                    }
                    if (Compare == 0)
                    {
                        Compare = w1.OriginalOrder - w2.OriginalOrder;
                    }
                    return(Compare);
                });
                foreach (var w in Warnings)
                {
                    Console.WriteLine("{0}: {1}", w.Bookmark, w.Message);
                }
            }

            // return the final script
            string strResult = r.GetGeneratedOutput();

            return(strResult);
        }
Example #4
0
        /// <summary>
        /// Parses all loaded scripts as javascript and compiles them to a string.
        /// </summary>
        /// <returns>A string containing the minified javascript.</returns>
        public string CompileJavascriptToString()
        {
            // Create a symbol allocator
            SymbolAllocator SymbolAllocator = new SymbolAllocator(this);

            // Don't let the symbol allocator use any reserved words or common Javascript bits
            // We only go up to three letters - symbol allocation of more than 3 letters is
            // highly unlikely.
            // (based on list here: http://www.quackit.com/javascript/javascript_reserved_words.cfm)
            string[] words = new string[] { "if", "in", "do", "for", "new", "var", "int", "try", "NaN", "ref", "sun", "top" };
            foreach (var s in words)
            {
                SymbolAllocator.ClaimSymbol(s);
            }

            // Create a member allocator
            SymbolAllocator MemberAllocator = new SymbolAllocator(this);

            // Render
            RenderContext r = new RenderContext(this, SymbolAllocator, MemberAllocator);

            // Process all files
            bool bNeedSemicolon = false;
            foreach (var file in m_files)
            {
                Console.WriteLine("Processing {0}...", System.IO.Path.GetFileName(file.filename));

                // Create a tokenizer and parser
                Warnings = new List<Warning>();
                WarningsEnabledStack = new Stack<bool>();
                Tokenizer t = new Tokenizer(this, file.content, file.filename, file.warnings);
                Parser p = new Parser(t);

                // Create the global statement block
                var code = new ast.CodeBlock(null, TriState.No);

                // Parse the file into a namespace
                p.ParseStatements(code);

                // Ensure everything processed
                if (t.more)
                {
                    throw new CompileError("Unexpected end of file", t);
                }

                // Dump the abstract syntax tree
                if (DumpAST)
                    code.Dump(0);

                // Create the root symbol scope and build scopes for all
                // constained function scopes
                SymbolScope rootScope = new SymbolScope(this, null, Accessibility.Public);
                SymbolScope rootPseudoScope = new SymbolScope(this, null, Accessibility.Public);
                code.Visit(new VisitorScopeBuilder(rootScope, rootPseudoScope));

                // Combine consecutive var declarations into a single one
                code.Visit(new VisitorCombineVarDecl(rootScope));

                // Find all variable declarations
                code.Visit(new VisitorSymbolDeclaration(rootScope, rootPseudoScope));

                // Do lint stuff
                code.Visit(new VisitorLint(rootScope, rootPseudoScope));

                // Try to eliminate const declarations
                if (DetectConsts && !NoObfuscate)
                {
                    code.Visit(new VisitorConstDetectorPass1(rootScope));
                    code.Visit(new VisitorConstDetectorPass2(rootScope));
                    code.Visit(new VisitorConstDetectorPass3(rootScope));
                }

                // Simplify expressions
                code.Visit(new VisitorSimplifyExpressions());

                // If obfuscation is allowed, find all in-scope symbols and then
                // count the frequency of their use.
                if (!NoObfuscate)
                {
                    code.Visit(new VisitorSymbolUsage(rootScope));
                }

                // Process all symbol scopes, applying default accessibility levels
                // and determining the "rank" of each symbol
                rootScope.Prepare();

                // Dump scopes to stdout
                if (DumpScopes)
                    rootScope.Dump(0);

                // Tell the global scope to claim all locally defined symbols
                // so they're not re-used (and therefore hidden) by the
                // symbol allocation
                rootScope.ClaimSymbols(SymbolAllocator);

                // Create a credit comment on the first file
                if (!NoCredit && file==m_files[0])
                {
                    int iInsertPos = 0;
                    while (iInsertPos < code.Content.Count && code.Content[iInsertPos].GetType() == typeof(ast.StatementComment))
                        iInsertPos++;
                    code.Content.Insert(iInsertPos, new ast.StatementComment(null, "// Minified by MiniME from toptensoftware.com"));
                }

                if (bNeedSemicolon)
                {
                    r.Append(";");
                }

                // Render it
                r.EnterScope(rootScope);
                bNeedSemicolon=code.Render(r);
                r.LeaveScope();

                // Display warnings
                Warnings.Sort(delegate(Warning w1, Warning w2)
                {
                    int Compare = w1.Order.file.FileName.CompareTo(w2.Order.file.FileName);
                    if (Compare == 0)
                        Compare = w1.Order.position - w2.Order.position;
                    if (Compare == 0)
                        Compare = w1.OriginalOrder - w2.OriginalOrder;
                    return Compare;
                });
                foreach (var w in Warnings)
                {
                    Console.WriteLine("{0}: {1}", w.Bookmark, w.Message);
                }

            }

            // return the final script
            string strResult = r.GetGeneratedOutput();
            return strResult;
        }
Example #5
0
 // Constructor
 public RenderContext(Compiler c, SymbolAllocator SymbolAllocator, SymbolAllocator MemberAllocator)
 {
     m_Compiler = c;
     m_SymbolAllocator = SymbolAllocator;
     m_MemberAllocator = MemberAllocator;
 }
Example #6
0
 // Constructor
 public RenderContext(Compiler c, SymbolAllocator SymbolAllocator, SymbolAllocator MemberAllocator)
 {
     m_Compiler        = c;
     m_SymbolAllocator = SymbolAllocator;
     m_MemberAllocator = MemberAllocator;
 }
Example #7
0
        // Obfuscate all local symbols
        //  - enumerate all local symbols and tell the symbol allocator
        //    that it can be obfuscated.
        //    - where there are `holes` in the rank mapping, tell the symbol
        //    allocator to reserve those symbols.  These holes are to be
        //    filled by higher frequency symbols on the inner scopes.
        public void ObfuscateSymbols(RenderContext ctx, SymbolFrequency SymbolFrequency, SymbolAllocator Allocator, string prefix)
        {
            // Walk through local symbols
            int expectedRank = 0;
            foreach (var symbol in SymbolFrequency.Sort())
            {
                // Ignore public symbols
                if (symbol.Accessibility != Accessibility.Private)
                    continue;

                // Ignore non-local symbols
                if (symbol.Scope != Symbol.ScopeType.local)
                    continue;

                // Reserve space for inner, higher frequency symbols
                if (symbol.Rank > expectedRank)
                {
                    if (ctx.Compiler.Formatted && ctx.Compiler.SymbolInfo)
                    {
                        for (int r = expectedRank; r < symbol.Rank; r++)
                        {
                            ctx.StartLine();
                            ctx.AppendFormat("// #{0} reserved", r);
                        }
                    }
                    Allocator.ReserveObfuscatedSymbols(symbol.Rank - expectedRank);
                }

                string newSymbol = Allocator.OnfuscateSymbol(symbol.Name);

                // Show info
                if (ctx.Compiler.Formatted && ctx.Compiler.SymbolInfo)
                {
                    ctx.StartLine();
                    ctx.AppendFormat("// #{0} {3}{1} -> {3}{2}", symbol.Rank, symbol.Name, newSymbol, prefix);
                }

                expectedRank = symbol.Rank + 1;
            }
        }
Example #8
0
 // Claim all local symbols in this scope, preventing use
 // by the symbol allocator.  Used on the global scope to
 // reserve global symbols
 public void ClaimSymbols(SymbolAllocator symbols)
 {
     foreach (var i in Symbols)
     {
         var s = i.Value;
         if (s.Scope == Symbol.ScopeType.local && s.Accessibility==Accessibility.Public)
         {
             symbols.ClaimSymbol(s.Name);
         }
     }
 }