Ejemplo n.º 1
0
        private object CompileImpl(IScriptable scope, StreamReader sourceReader, string sourceString, string sourceName, int lineno, object securityDomain, bool returnFunction, Interpreter compiler, ErrorReporter compilationErrorReporter)
        {
            if (securityDomain != null && securityController == null) {
                throw new ArgumentException ("securityDomain should be null if setSecurityController() was never called");
            }

            // One of sourceReader or sourceString has to be null
            if (!(sourceReader == null ^ sourceString == null))
                Context.CodeBug ();
            // scope should be given if and only if compiling function
            if (!(scope == null ^ returnFunction))
                Context.CodeBug ();

            CompilerEnvirons compilerEnv = new CompilerEnvirons ();
            compilerEnv.initFromContext (this);
            if (compilationErrorReporter == null) {
                compilationErrorReporter = compilerEnv.getErrorReporter ();
            }

            if (m_Debugger != null) {
                if (sourceReader != null) {
                    sourceString = sourceReader.ReadToEnd ();
                    sourceReader = null;
                }
            }

            Parser p = new Parser (compilerEnv, compilationErrorReporter);
            if (returnFunction) {
                p.calledByCompileFunction = true;
            }
            ScriptOrFnNode tree;
            if (sourceString != null) {
                tree = p.Parse (sourceString, sourceName, lineno);
            }
            else {
                tree = p.Parse (sourceReader, sourceName, lineno);
            }
            if (returnFunction) {
                if (!(tree.FunctionCount == 1 && tree.FirstChild != null && tree.FirstChild.Type == Token.FUNCTION)) {
                    // TODO: the check just look for the first child
                    // TODO: and allows for more nodes after it for compatibility
                    // TODO: with sources like function() {};;;
                    throw new ArgumentException ("compileFunction only accepts source with single JS function: " + sourceString);
                }
            }

            if (compiler == null) {
                compiler = new Interpreter ();
                //compiler = new Compiler();
            }

            string encodedSource = p.EncodedSource;

            object bytecode = compiler.Compile (compilerEnv, tree, encodedSource, returnFunction);

            if (m_Debugger != null) {
                if (sourceString == null)
                    Context.CodeBug ();
                if (bytecode is DebuggableScript) {
                    DebuggableScript dscript = (DebuggableScript)bytecode;
                    NotifyDebugger (this, dscript, sourceString);
                }
                else {
                    throw new ApplicationException ("NOT SUPPORTED");
                }
            }

            object result;
            if (returnFunction) {
                result = compiler.CreateFunctionObject (this, scope, bytecode, securityDomain);
            }
            else {
                result = compiler.CreateScriptObject (bytecode, securityDomain);
            }

            return result;
        }
        private static ArrayList Parse(StreamReader stream,
                                       ErrorReporter reporter)
        {
            var compilerEnvirons = new CompilerEnvirons();
            var parser = new Parser(compilerEnvirons, reporter);
            parser.Parse(stream, null, 1);
            string source = parser.EncodedSource;

            int offset = 0;
            int length = source.Length;
            var tokens = new ArrayList();
            var stringBuilder = new StringBuilder();

            while (offset < length)
            {
                int tt = source[offset++];
                switch (tt)
                {
                    case Token.CONDCOMMENT:
                    case Token.KEEPCOMMENT:
                    case Token.NAME:
                    case Token.REGEXP:
                    case Token.STRING:
                        stringBuilder.Length = 0;
                        offset = PrintSourceString(source,
                                                   offset,
                                                   stringBuilder);
                        tokens.Add(new JavaScriptToken(tt, stringBuilder.ToString()));
                        break;

                    case Token.NUMBER:
                        stringBuilder.Length = 0;
                        offset = PrintSourceNumber(source, offset, stringBuilder);
                        tokens.Add(new JavaScriptToken(tt, stringBuilder.ToString()));
                        break;

                    default:
                        var literal = (string) Literals[tt];
                        if (literal != null)
                        {
                            tokens.Add(new JavaScriptToken(tt, literal));
                        }
                        break;
                }
            }

            return tokens;
        }
Ejemplo n.º 3
0
 /// <summary> Check whether a string is ready to be compiled.
 /// <p>
 /// stringIsCompilableUnit is intended to support interactive compilation of
 /// javascript.  If compiling the string would result in an error
 /// that might be fixed by appending more source, this method
 /// returns false.  In every other case, it returns true.
 /// <p>
 /// Interactive shells may accumulate source lines, using this
 /// method after each new line is appended to check whether the
 /// statement being entered is complete.
 /// 
 /// </summary>
 /// <param name="source">the source buffer to check
 /// </param>
 /// <returns> whether the source is ready for compilation
 /// </returns>
 public ScriptOrFnNode IsCompilableUnit(string source)
 {
     ScriptOrFnNode ret = null;
     bool errorseen = false;
     CompilerEnvirons compilerEnv = new CompilerEnvirons ();
     compilerEnv.initFromContext (this);
     // no source name or source text manager, because we're just
     // going to throw away the result.
     compilerEnv.setGeneratingSource (false);
     Parser p = new Parser (compilerEnv, DefaultErrorReporter.instance);
     try {
         ret = p.Parse (source, null, 1);
     }
     catch (EcmaScriptRuntimeException) {
         errorseen = true;
     }
     // Return false only if an error occurred as a result of reading past
     // the end of the file, i.e. if the source could be fixed by
     // appending more source.
     if (!(errorseen && p.Eof))
         return ret;
     return null;
 }