Esempio n. 1
0
File: Typer.cs Progetto: Daouki/wire
        public IType VisitArrayLiteral(ArrayLiteral arrayLiteral)
        {
            var firstElementType = GetExpressionType(arrayLiteral.Elements[0]);

            if (firstElementType == null)
            {
                return(null);
            }

            if (arrayLiteral.Length == 1)
            {
                return(new ArrayType(firstElementType, 1));
            }

            for (var i = 1; i < arrayLiteral.Length; i++)
            {
                var element     = arrayLiteral.Elements[i];
                var elementType = GetExpressionType(element);
                if (elementType == null || elementType.IsSame(firstElementType))
                {
                    continue;
                }

                _context.Error(
                    element.Span,
                    "type mismatch in array literal; " +
                    $"expected \"{firstElementType}\", but found \"{elementType}\"");
                return(null);
            }

            return(new ArrayType(firstElementType, arrayLiteral.Length));
        }
        private void ProcessArguments(ArrayLiteral arguments)
        {
            var processedArguments = CommandLineArgumentsConverter.ArrayLiteralToListOfArguments(m_context.StringTable, arguments);

            foreach (var argument in processedArguments)
            {
                // Not every arguments are valid.
                // Cmd.option function will return invalid argument if the argument value is undefined.
                if (!argument.IsDefined)
                {
                    continue;
                }

                // It could be just a switch argument, i.e., argument name without a value
                if (!argument.Value.IsDefined)
                {
                    AddOption(argument.Name, (string)null);
                    continue;
                }

                switch (argument.Value.Type)
                {
                case CommandLineValueType.ScalarArgument:
                    AddScalarArgument(argument.Name, argument.Value.ScalarArgument);
                    break;

                case CommandLineValueType.ScalarArgumentArray:
                    AddScalarArguments(argument.Name, argument.Value.ScalarArguments);
                    break;
                }
            }
        }
Esempio n. 3
0
        public ArrayLiteral ParseArrayLiteral()
        {
            var al = new ArrayLiteral {
                Token = Next()
            };

            Match(TokenType.LeftBracket);
            while (Next().IsNot(TokenType.RightBracket))
            {
                al.Expressions.Add(ParseAssignmentExpression());
                if (Next().Is(TokenType.Derive))
                {
                    if (al.Expressions.Count != 1)
                    {
                        throw Error("Invalid array definition", al.Token);
                    }
                    Match(TokenType.Derive);
                    al.Expressions.Add(ParseAssignmentExpression());
                    al.IsRange = true;
                    break;
                }
                if (Next().Is(TokenType.Comma))
                {
                    Match(TokenType.Comma);
                }
            }
            Match(TokenType.RightBracket);
            return(al);
        }
Esempio n. 4
0
        private static EvaluationResult ForEach(Context context, OrderedSet receiver, EvaluationResult arg, EvaluationStackFrame captures)
        {
            var cls         = Converter.ExpectClosure(arg);
            var result      = new EvaluationResult[receiver.Count];
            int paramsCount = cls.Function.Params;

            using (var frame = EvaluationStackFrame.Create(cls.Function, captures.Frame))
            {
                int i = 0;

                foreach (var item in receiver)
                {
                    frame.TrySetArguments(paramsCount, item);
                    result[i] = context.InvokeClosure(cls, frame);

                    if (result[i].IsErrorValue)
                    {
                        return(EvaluationResult.Error);
                    }

                    ++i;
                }

                return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, context.TopStack.InvocationLocation, context.TopStack.Path)));
            }
        }
Esempio n. 5
0
 public virtual void Visit(ArrayLiteral node)
 {
     if (node != null)
     {
         AcceptChildren(node);
     }
 }
Esempio n. 6
0
        private static EvaluationResult ForEach(Context context, OrderedMap receiver, EvaluationResult arg, EvaluationStackFrame captures)
        {
            var cls         = Converter.ExpectClosure(arg);
            var result      = new EvaluationResult[receiver.Count];
            int paramsCount = cls.Function.Params;

            // One frame can be reused for multiple calls of a callback function
            using (var frame = EvaluationStackFrame.Create(cls.Function, captures.Frame))
            {
                var entry = context.TopStack;

                int i = 0;

                foreach (var kvp in receiver)
                {
                    var kvpAsArray = ArrayLiteral.CreateWithoutCopy(new EvaluationResult[] { kvp.Key, kvp.Value }, entry.InvocationLocation, entry.Path);

                    frame.TrySetArguments(paramsCount, EvaluationResult.Create(kvpAsArray));
                    result[i] = context.InvokeClosure(cls, frame);

                    if (result[i].IsErrorValue)
                    {
                        return(EvaluationResult.Error);
                    }

                    ++i;
                }

                return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path)));
            }
        }
 public void Visit(ArrayLiteral node)
 {
     if (node != null)
     {
         DoesRequire = true;
     }
 }
Esempio n. 8
0
        private static EvaluationResult SealDirectoryHelper(Context context, ModuleLiteral env, EvaluationStackFrame args, SealDirectoryKind sealDirectoryKind)
        {
            AbsolutePath path        = Args.AsPath(args, 0, false);
            ArrayLiteral contents    = Args.AsArrayLiteral(args, 1);
            var          tags        = Args.AsStringArrayOptional(args, 2);
            var          description = Args.AsStringOptional(args, 3);
            // Only do scrub for fully seal directory
            var scrub = sealDirectoryKind.IsFull() ? Args.AsBoolOptional(args, 4) : false;

            var fileContents = new FileArtifact[contents.Length];

            for (int i = 0; i < contents.Length; ++i)
            {
                fileContents[i] = Converter.ExpectFile(contents[i], strict: false, context: new ConversionContext(pos: i, objectCtx: contents));
            }

            var sortedFileContents = SortedReadOnlyArray <FileArtifact, OrdinalFileArtifactComparer> .CloneAndSort(fileContents, OrdinalFileArtifactComparer.Instance);

            DirectoryArtifact sealedDirectoryArtifact;

            if (!context.GetPipConstructionHelper().TrySealDirectory(path, sortedFileContents, sealDirectoryKind, tags, description, null, out sealedDirectoryArtifact, scrub))
            {
                // Error has been logged
                return(EvaluationResult.Error);
            }

            var result = new StaticDirectory(sealedDirectoryArtifact, sealDirectoryKind, sortedFileContents.WithCompatibleComparer(OrdinalPathOnlyFileArtifactComparer.Instance));

            return(new EvaluationResult(result));
        }
Esempio n. 9
0
        private static EvaluationResult ToArray(Context context, string receiver, EvaluationStackFrame captures)
        {
            var elems = string.IsNullOrEmpty(receiver)
                ? CollectionUtilities.EmptyArray <EvaluationResult>()
                : receiver.ToCharArray().SelectArray(ch => EvaluationResult.Create(ch.ToString()));

            return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(elems, context.TopStack.InvocationLocation, context.TopStack.Path)));
        }
Esempio n. 10
0
        private IExpression ParseArrayLiteral()
        {
            var array = new ArrayLiteral {
                Token = CurrentToken, Elements = ParseExpressionList(Token.Rbracket)
            };

            return(array);
        }
Esempio n. 11
0
        private Expression ParseArrayLiteral()
        {
            var array = new ArrayLiteral();

            array.Token    = this._curToken;
            array.Elements = this.ParseExpressionList(TokenType.RBRACKET);
            return(array);
        }
Esempio n. 12
0
        public void Visit(ArrayLiteral node)
        {
            if (node != null)
            {
                // if this is multi-line output, we're going to want to run some checks first
                // to see if we want to put the array all on one line or put elements on separate lines.
                var multiLine = false;
                if (m_settings.OutputMode == OutputMode.MultipleLines)
                {
                    if (node.Elements.Count > 5 || NotJustPrimitives(node.Elements))
                    {
                        multiLine = true;
                    }
                }

                m_writer.Write('[');
                if (node.Elements != null)
                {
                    if (multiLine)
                    {
                        // multiline -- let's pretty it up a bit
                        m_settings.Indent();
                        try
                        {
                            var first = true;
                            foreach (var element in node.Elements)
                            {
                                if (first)
                                {
                                    first = false;
                                }
                                else
                                {
                                    m_writer.Write(',');
                                }

                                NewLine();
                                element.Accept(this);
                            }
                        }
                        finally
                        {
                            m_settings.Unindent();
                        }

                        NewLine();
                    }
                    else
                    {
                        // not multiline, so just run through all the items
                        node.Elements.Accept(this);
                    }
                }

                m_writer.Write(']');
            }
        }
Esempio n. 13
0
        private IExpression ParseArrayLiteral()
        {
            var arr = new ArrayLiteral {
                Token = this.currentToken
            };

            arr.Elements = ParseExpressionList(TokenType.RBracket);
            return(arr);
        }
        private IExpression ParseArrayLiteral()
        {
            var array = new ArrayLiteral {
                Token = curToken
            };

            array.Elements = ParseExpressionList(TokenType.RBracket);

            return(array);
        }
Esempio n. 15
0
 public virtual void Visit(ArrayLiteral node)
 {
     if (node != null)
     {
         foreach (var childNode in node.Children)
         {
             childNode.Accept(this);
         }
     }
 }
Esempio n. 16
0
 public virtual void Visit(ArrayLiteral node)
 {
     if (node != null)
     {
         if (node.Elements != null)
         {
             node.Elements.Accept(this);
         }
     }
 }
Esempio n. 17
0
 public virtual void Visit(ArrayLiteral node)
 {
     if (node != null)
     {
         foreach (var childNode in node.Children)
         {
             childNode.Accept(this);
         }
     }
 }
Esempio n. 18
0
        private static EvaluationResult GetContent(Context context, StaticDirectory receiver, EvaluationStackFrame captures)
        {
            GetProvenance(context, out AbsolutePath path, out LineInfo lineInfo);

            // Can't use content directly, because there is no IS-A relationship between collection
            // of value types and collection of objects. So need to box everything any way.
            var content = receiver.Contents.SelectArray(x => EvaluationResult.Create(x));

            return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(content, lineInfo, path)));
        }
Esempio n. 19
0
        private static ArrayLiteral DeepCloneArray(ArrayLiteral array)
        {
            var results = new EvaluationResult[array.Count];

            for (int i = 0; i < array.Count; i++)
            {
                results[i] = DeepCloneValue(array[i]);
            }

            return(ArrayLiteral.CreateWithoutCopy(results, array.Location, array.Path));
        }
Esempio n. 20
0
        private IExpression ParseArrayLiteral()
        {
            var array = new ArrayLiteral
            {
                Token = _currentToken
            };

            array.Elements = ParseExpressionList(TokenType.RBRACKET);

            return(array);
        }
Esempio n. 21
0
 public virtual object Walk(ArrayLiteral node)
 {
     if (Enter(node))
     {
         foreach (var exp in node.Expressions)
         {
             exp.Accept(this);
         }
     }
     Exit(node);
     return(null);
 }
Esempio n. 22
0
        private static bool TryHashArray(ArrayLiteral array, HashingHelper helper)
        {
            helper.Add(array.Length);
            foreach (var item in array.Values)
            {
                if (!TryHashValue(item, helper))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 23
0
        public bool VisitArrayLiteral(ArrayLiteral arrayLiteral)
        {
            var isValid = arrayLiteral.Elements.Aggregate(
                true,
                (current, element) => current & IsExpressionValid(element));

            if (!isValid)
            {
                return(false);
            }

            return(Typer.GetExpressionType(_context, _environment, arrayLiteral) != null);
        }
Esempio n. 24
0
        private ArgumentValue[] ConvertArrayOfScalarArguments(ArrayLiteral scalarArguments)
        {
            Contract.Requires(scalarArguments != null);

            var results = new ArgumentValue[scalarArguments.Length];

            for (int i = 0; i < scalarArguments.Length; ++i)
            {
                results[i] = ConvertScalarArgument(new PropertyValue(SymbolAtom.Invalid, scalarArguments, scalarArguments[i]));
            }

            return(results);
        }
Esempio n. 25
0
        private static EvaluationResult ToPathAtoms(Context context, RelativePath receiver, EvaluationStackFrame captures)
        {
            PathAtom[]         atoms  = receiver.GetAtoms();
            EvaluationResult[] result = new EvaluationResult[atoms.Length];

            for (int i = 0; i < atoms.Length; i++)
            {
                result[i] = EvaluationResult.Create(atoms[i]);
            }

            var entry = context.TopStack;

            return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result, entry.InvocationLocation, entry.Path)));
        }
Esempio n. 26
0
        private static IEnumerable <object> GetDifferentListRepresenations <T>(IReadOnlyList <T> array)
        {
            var objectArray = new object[array.Count];

            for (var i = 0; i < objectArray.Length; i++)
            {
                objectArray[i] = array[i];
            }

            return(new List <object>
            {
                array,
                ArrayLiteral.CreateWithoutCopy(objectArray.Select(e => EvaluationResult.Create(e)).ToArray(), default(LineInfo), AbsolutePath.Invalid)
            });
        }
Esempio n. 27
0
        private EvaluationResult AddIf(Context context, ModuleLiteral env, EvaluationStackFrame args)
        {
            var condition = Args.AsBool(args, 0);

            if (!condition)
            {
                // Return empty Array
                var entry = context.TopStack;
                return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(new EvaluationResult[0], entry.InvocationLocation, entry.Path)));
            }

            var items = Args.AsArrayLiteral(args, 1);

            return(EvaluationResult.Create(items));
        }
Esempio n. 28
0
        public void TestAmbientEnvironmentUses()
        {
            const string Spec    = @"
// Any change will break Office.
const newLine = Environment.newLine();
const hasVariable = Environment.hasVariable(""ProgramFiles(x86)"");
const stringValue = Environment.getStringValue(""UserName"");
const pathValue = Environment.getPathValue(""ProgramFiles(x86)"");
const fileValue = Environment.getFileValue(""ProgramFiles(x86)""); // yes, I know it's not a file.
const pathValues = Environment.getPathValues(""Path"", "";"");
";
            var          results = EvaluateExpressionsWithNoErrors(
                Spec,
                "newLine",
                "hasVariable",
                "stringValue",
                "pathValue",
                "fileValue",
                "pathValues");

            string programFileX86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
            string userName       = Environment.GetEnvironmentVariable("UserName");
            string path           = Environment.GetEnvironmentVariable("Path");

            Assert.Equal(Environment.NewLine, results["newLine"]);
            Assert.Equal(programFileX86 != null, results["hasVariable"]);
            Assert.Equal(userName != null ? (object)userName : UndefinedValue.Instance, results["stringValue"]);
            Assert.Equal(
                programFileX86 != null ? (object)CreateAbsolutePath(programFileX86).Value : UndefinedValue.Instance,
                results["pathValue"]);
            Assert.Equal(
                programFileX86 != null ? (object)CreateSourceFile(programFileX86).Value : UndefinedValue.Instance,
                results["fileValue"]);

            if (path != null)
            {
                var paths = ArrayLiteral.CreateWithoutCopy(
                    path.Split(';').Select(p => EvaluationResult.Create(CreateAbsolutePath(p))).ToArray(),
                    default(LineInfo),
                    AbsolutePath.Invalid);
                Assert.IsAssignableFrom <ArrayLiteral>(results["pathValues"]);
                CheckUnorderedArray <AbsolutePath>(paths, results["pathValues"]);
            }
            else
            {
                Assert.Equal(UndefinedValue.Instance, results["pathValues"]);
            }
        }
Esempio n. 29
0
        private EvaluationResult GlobFolders(Context context, ModuleLiteral env, EvaluationStackFrame args)
        {
            var dirPath   = Args.AsPath(args, 0, false);
            var pathTable = context.FrontEndContext.PathTable;
            var path      = dirPath.ToString(pathTable);

            // TODO:ST: add different set of function that will distinguish optional from required arguments!
            string pattern   = Args.AsStringOptional(args, 1) ?? "*";
            bool   recursive = Args.AsBoolOptional(args, 2);

            var resultPaths = EnumerateFilesOrDirectories(context, path, pattern, directoriesToSkipRecursively: 0, isRecursive: recursive, enumerateDirectory: true);

            var entry = context.TopStack;

            return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(resultPaths, entry.InvocationLocation, entry.Path)));
        }
Esempio n. 30
0
        private static ObjectLiteral GetQualifierSpaceValue(EvaluationContext context, QualifierSpaceId qualifierSpaceId)
        {
            Contract.Requires(context != null);
            Contract.Requires(context.FrontEndContext.QualifierTable.IsValidQualifierSpaceId(qualifierSpaceId));

            var qualifierSpace = context.FrontEndContext.QualifierTable.GetQualifierSpace(qualifierSpaceId);
            var bindings       = new List <Binding>(qualifierSpace.Keys.Count);

            foreach (var kvp in qualifierSpace.AsDictionary)
            {
                var values = ArrayLiteral.CreateWithoutCopy(kvp.Value.Select(s => EvaluationResult.Create(s.ToString(context.StringTable))).ToArray(), default(LineInfo), AbsolutePath.Invalid);
                bindings.Add(new Binding(kvp.Key, values, default(LineInfo)));
            }

            return(ObjectLiteral.Create(bindings, default(LineInfo), AbsolutePath.Invalid));
        }
Esempio n. 31
0
        private IEnumerable <Argument> ConvertArrayOfArguments(ArrayLiteral literal)
        {
            Contract.Requires(literal != null);
            for (int i = 0; i < literal.Length; ++i)
            {
                var l = literal[i];
                if (!l.IsUndefined)
                {
                    var x = ConvertArgument(l, i, literal);

                    if (x.IsDefined)
                    {
                        yield return(x);
                    }
                }
            }
        }
Esempio n. 32
0
        public override object Walk(ArrayLiteral node)
        {
            var array = new BikeArray();

            if (node.IsRange)
            {
                var from      = node.Expressions[0].Accept(this);
                var fromValue = ((BikeNumber)from).Value;
                if ((fromValue % 1) != 0)
                {
                    throw ErrorFactory.CreateTypeError("Array range initializer must start with a whole number");
                }

                var end      = node.Expressions[1].Accept(this);
                var endValue = ((BikeNumber)end).Value;
                if ((endValue % 1) != 0)
                {
                    throw ErrorFactory.CreateTypeError("Array range initializer must end with a whole number");
                }

                if (fromValue <= endValue)
                {
                    int index = 0;
                    for (var i = (int)fromValue; i < (int)endValue; i++)
                    {
                        array.Define((index++).ToString(), new BikeNumber(i));
                    }
                }
                else
                {
                    int index = 0;
                    for (var i = (int)fromValue; i > (int)endValue; i--)
                    {
                        array.Define((index++).ToString(), new BikeNumber(i));
                    }
                }
                return(array);
            }
            for (int i = 0; i < node.Expressions.Count; i++)
            {
                var value = node.Expressions[i].Accept(this);
                array.Define(i.ToString(), value);
            }
            return(array);
        }
Esempio n. 33
0
 public ArrayLiteral ParseArrayLiteral()
 {
     var al = new ArrayLiteral {Token = Next()};
     Match(TokenType.LeftBracket);
     while (Next().IsNot(TokenType.RightBracket))
     {
         al.Expressions.Add(ParseAssignmentExpression());
         if (Next().Is(TokenType.Derive))
         {
             if (al.Expressions.Count != 1)
                 throw Error("Invalid array definition", al.Token);
             Match(TokenType.Derive);
             al.Expressions.Add(ParseAssignmentExpression());
             al.IsRange = true;
             break;
         }
         if (Next().Is(TokenType.Comma))
             Match(TokenType.Comma);
     }
     Match(TokenType.RightBracket);
     return al;
 }
Esempio n. 34
0
 public virtual bool Enter(ArrayLiteral node)
 {
     return true;
 }
Esempio n. 35
0
    // $ANTLR start "arrayLiteral"
    // JavaScript.g:340:1: arrayLiteral : '[' ( LT )* ( elision ( ',' elision )* ( ',' )? )? ']' ;
    public JavaScriptParser.arrayLiteral_return arrayLiteral() // throws RecognitionException [1]
    {   
        JavaScriptParser.arrayLiteral_return retval = new JavaScriptParser.arrayLiteral_return();
        retval.Start = input.LT(1);

        object root_0 = null;

        IToken char_literal404 = null;
        IToken LT405 = null;
        IToken char_literal407 = null;
        IToken char_literal409 = null;
        IToken char_literal410 = null;
        JavaScriptParser.elision_return elision406 = default(JavaScriptParser.elision_return);

        JavaScriptParser.elision_return elision408 = default(JavaScriptParser.elision_return);


        object char_literal404_tree=null;
        object LT405_tree=null;
        object char_literal407_tree=null;
        object char_literal409_tree=null;
        object char_literal410_tree=null;

        try 
    	{
            // JavaScript.g:341:2: ( '[' ( LT )* ( elision ( ',' elision )* ( ',' )? )? ']' )
            // JavaScript.g:341:4: '[' ( LT )* ( elision ( ',' elision )* ( ',' )? )? ']'
            {
            	root_0 = (object)adaptor.GetNilNode();

            	char_literal404=(IToken)Match(input,67,FOLLOW_67_in_arrayLiteral3070); if (state.failed) return retval;
            	if ( state.backtracking == 0 )
            	{char_literal404_tree = new ArrayLiteral(char_literal404) ;
            		root_0 = (object)adaptor.BecomeRoot(char_literal404_tree, root_0);
            	}
            	// JavaScript.g:341:25: ( LT )*
            	do 
            	{
            	    int alt202 = 2;
            	    int LA202_0 = input.LA(1);

            	    if ( (LA202_0 == LT) )
            	    {
            	        alt202 = 1;
            	    }


            	    switch (alt202) 
            		{
            			case 1 :
            			    // JavaScript.g:341:25: LT
            			    {
            			    	LT405=(IToken)Match(input,LT,FOLLOW_LT_in_arrayLiteral3076); if (state.failed) return retval;

            			    }
            			    break;

            			default:
            			    goto loop202;
            	    }
            	} while (true);

            	loop202:
            		;	// Stops C# compiler whining that label 'loop202' has no statements

            	// JavaScript.g:341:28: ( elision ( ',' elision )* ( ',' )? )?
            	int alt205 = 2;
            	int LA205_0 = input.LA(1);

            	if ( ((LA205_0 >= Identifier && LA205_0 <= RegexLiteral) || (LA205_0 >= 39 && LA205_0 <= 40) || LA205_0 == 42 || (LA205_0 >= 66 && LA205_0 <= 67) || (LA205_0 >= 99 && LA205_0 <= 100) || (LA205_0 >= 104 && LA205_0 <= 114)) )
            	{
            	    alt205 = 1;
            	}
            	switch (alt205) 
            	{
            	    case 1 :
            	        // JavaScript.g:341:30: elision ( ',' elision )* ( ',' )?
            	        {
            	        	PushFollow(FOLLOW_elision_in_arrayLiteral3082);
            	        	elision406 = elision();
            	        	state.followingStackPointer--;
            	        	if (state.failed) return retval;
            	        	if ( state.backtracking == 0 ) adaptor.AddChild(root_0, elision406.Tree);
            	        	// JavaScript.g:341:38: ( ',' elision )*
            	        	do 
            	        	{
            	        	    int alt203 = 2;
            	        	    int LA203_0 = input.LA(1);

            	        	    if ( (LA203_0 == 43) )
            	        	    {
            	        	        int LA203_1 = input.LA(2);

            	        	        if ( ((LA203_1 >= Identifier && LA203_1 <= RegexLiteral) || (LA203_1 >= 39 && LA203_1 <= 40) || LA203_1 == 42 || (LA203_1 >= 66 && LA203_1 <= 67) || (LA203_1 >= 99 && LA203_1 <= 100) || (LA203_1 >= 104 && LA203_1 <= 114)) )
            	        	        {
            	        	            alt203 = 1;
            	        	        }


            	        	    }


            	        	    switch (alt203) 
            	        		{
            	        			case 1 :
            	        			    // JavaScript.g:341:39: ',' elision
            	        			    {
            	        			    	char_literal407=(IToken)Match(input,43,FOLLOW_43_in_arrayLiteral3085); if (state.failed) return retval;
            	        			    	if ( state.backtracking == 0 )
            	        			    	{char_literal407_tree = (object)adaptor.Create(char_literal407);
            	        			    		adaptor.AddChild(root_0, char_literal407_tree);
            	        			    	}
            	        			    	PushFollow(FOLLOW_elision_in_arrayLiteral3087);
            	        			    	elision408 = elision();
            	        			    	state.followingStackPointer--;
            	        			    	if (state.failed) return retval;
            	        			    	if ( state.backtracking == 0 ) adaptor.AddChild(root_0, elision408.Tree);

            	        			    }
            	        			    break;

            	        			default:
            	        			    goto loop203;
            	        	    }
            	        	} while (true);

            	        	loop203:
            	        		;	// Stops C# compiler whining that label 'loop203' has no statements

            	        	// JavaScript.g:341:53: ( ',' )?
            	        	int alt204 = 2;
            	        	int LA204_0 = input.LA(1);

            	        	if ( (LA204_0 == 43) )
            	        	{
            	        	    alt204 = 1;
            	        	}
            	        	switch (alt204) 
            	        	{
            	        	    case 1 :
            	        	        // JavaScript.g:341:53: ','
            	        	        {
            	        	        	char_literal409=(IToken)Match(input,43,FOLLOW_43_in_arrayLiteral3091); if (state.failed) return retval;
            	        	        	if ( state.backtracking == 0 )
            	        	        	{char_literal409_tree = (object)adaptor.Create(char_literal409);
            	        	        		adaptor.AddChild(root_0, char_literal409_tree);
            	        	        	}

            	        	        }
            	        	        break;

            	        	}


            	        }
            	        break;

            	}

            	char_literal410=(IToken)Match(input,68,FOLLOW_68_in_arrayLiteral3097); if (state.failed) return retval;

            }

            retval.Stop = input.LT(-1);

            if ( (state.backtracking==0) )
            {	retval.Tree = (object)adaptor.RulePostProcessing(root_0);
            	adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);}
        }
        catch (RecognitionException re) 
    	{
            ReportError(re);
            Recover(input,re);
    	// Conversion of the second argument necessary, but harmless
    	retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re);

        }
        finally 
    	{
        }
        return retval;
    }
Esempio n. 36
0
        public override object Walk(ArrayLiteral node)
        {
            var array = new BikeArray();
            if (node.IsRange)
            {
                var from = node.Expressions[0].Accept(this);
                var fromValue = ((BikeNumber) from).Value;
                if ((fromValue % 1) != 0)
                    throw ErrorFactory.CreateTypeError("Array range initializer must start with a whole number");

                var end = node.Expressions[1].Accept(this);
                var endValue = ((BikeNumber)end).Value;
                if ((endValue % 1) != 0)
                    throw ErrorFactory.CreateTypeError("Array range initializer must end with a whole number");

                if (fromValue <= endValue)
                {
                    int index = 0;
                    for (var i = (int) fromValue; i < (int) endValue; i++)
                    {
                        array.Define((index++).ToString(), new BikeNumber(i));
                    }
                }
                else
                {
                    int index = 0;
                    for (var i = (int)fromValue; i > (int)endValue; i--)
                    {
                        array.Define((index++).ToString(), new BikeNumber(i));
                    }
                }
                return array;
            }
            for (int i = 0; i < node.Expressions.Count; i++)
            {
                var value = node.Expressions[i].Accept(this);
                array.Define(i.ToString(), value);
            }
            return array;
        }
Esempio n. 37
0
 public override void Exit(ArrayLiteral node)
 {
     level--;
 }
Esempio n. 38
0
 public virtual void Exit(ArrayLiteral node)
 {
 }
Esempio n. 39
0
 public virtual void PostWalk(ArrayLiteral node) { }
Esempio n. 40
0
        public void VisitArrayLiteral(ArrayLiteral arrayLiteral)
        {
            foreach (Expression e in arrayLiteral.Values) {
                VisitExpression(e);
            }

            ReturnValue = null;
        }
Esempio n. 41
0
 public virtual bool Walk(ArrayLiteral node) { return true; }
Esempio n. 42
0
        //---------------------------------------------------------------------------------------
        // ParseLeftHandSideExpression
        //
        //  LeftHandSideExpression :
        //    PrimaryExpression Accessor  |
        //    'new' LeftHandSideExpression |
        //    FunctionExpression
        //
        //  PrimaryExpression :
        //    'this' |
        //    Identifier |
        //    Literal |
        //    '(' Expression ')'
        //
        //  FunctionExpression :
        //    'function' OptionalFuncName '(' FormalParameterList ')' { FunctionBody }
        //
        //  OptionalFuncName :
        //    <empty> |
        //    Identifier
        //---------------------------------------------------------------------------------------
        private AstNode ParseLeftHandSideExpression(bool isMinus)
        {
            AstNode ast = null;
            bool isFunction = false;
            List<Context> newContexts = null;

            TryItAgain:

            // new expression
            while (JSToken.New == m_currentToken.Token)
            {
                if (null == newContexts)
                    newContexts = new List<Context>(4);
                newContexts.Add(m_currentToken.Clone());
                GetNextToken();
            }
            JSToken token = m_currentToken.Token;
            switch (token)
            {
                // primary expression
                case JSToken.Identifier:
                    ast = new Lookup(m_scanner.GetIdentifier(), m_currentToken.Clone(), this);
                    break;

                case JSToken.ConditionalCommentStart:
                    // skip past the start to the next token
                    GetNextToken();
                    if (m_currentToken.Token == JSToken.PreprocessorConstant)
                    {
                        // we have /*@id
                        ast = new ConstantWrapperPP(m_currentToken.Code, true, m_currentToken.Clone(), this);
                        GetNextToken();

                        if (m_currentToken.Token == JSToken.ConditionalCommentEnd)
                        {
                            // skip past the closing comment
                            GetNextToken();
                        }
                        else
                        {
                            // we ONLY support /*@id@*/ in expressions right now. If there's not
                            // a closing comment after the ID, then we don't support it.
                            // throw an error, skip to the end of the comment, then ignore it and start
                            // looking for the next token.
                            m_currentToken.HandleError(JSError.ConditionalCompilationTooComplex);

                            // skip to end of conditional comment
                            while (m_currentToken.Token != JSToken.EndOfFile && m_currentToken.Token != JSToken.ConditionalCommentEnd)
                            {
                                GetNextToken();
                            }
                            GetNextToken();
                            goto TryItAgain;
                        }
                    }
                    else if (m_currentToken.Token == JSToken.ConditionalCommentEnd)
                    {
                        // empty conditional comment! Ignore.
                        GetNextToken();
                        goto TryItAgain;
                    }
                    else
                    {
                        // we DON'T have "/*@IDENT". We only support "/*@IDENT @*/", so since this isn't
                        // and id, throw the error, skip to the end of the comment, and ignore it
                        // by looping back and looking for the NEXT token.
                        m_currentToken.HandleError(JSError.ConditionalCompilationTooComplex);

                        // skip to end of conditional comment
                        while (m_currentToken.Token != JSToken.EndOfFile && m_currentToken.Token != JSToken.ConditionalCommentEnd)
                        {
                            GetNextToken();
                        }
                        GetNextToken();
                        goto TryItAgain;
                    }
                    break;

                case JSToken.This:
                    ast = new ThisLiteral(m_currentToken.Clone(), this);
                    break;

                case JSToken.StringLiteral:
                    ast = new ConstantWrapper(m_scanner.StringLiteral, PrimitiveType.String, m_currentToken.Clone(), this);
                    break;

                case JSToken.IntegerLiteral:
                case JSToken.NumericLiteral:
                    {
                        Context numericContext = m_currentToken.Clone();
                        double doubleValue;
                        if (ConvertNumericLiteralToDouble(m_currentToken.Code, (token == JSToken.IntegerLiteral), out doubleValue))
                        {
                            // conversion worked fine
                            // check for some boundary conditions
                            if (doubleValue == double.MaxValue)
                            {
                                ReportError(JSError.NumericMaximum, numericContext, true);
                            }
                            else if (isMinus && -doubleValue == double.MinValue)
                            {
                                ReportError(JSError.NumericMinimum, numericContext, true);
                            }

                            // create the constant wrapper from the value
                            ast = new ConstantWrapper(doubleValue, PrimitiveType.Number, numericContext, this);
                        }
                        else
                        {
                            // check to see if we went overflow
                            if (double.IsInfinity(doubleValue))
                            {
                                ReportError(JSError.NumericOverflow, numericContext, true);
                            }

                            // regardless, we're going to create a special constant wrapper
                            // that simply echos the input as-is
                            ast = new ConstantWrapper(m_currentToken.Code, PrimitiveType.Other, numericContext, this);
                        }
                        break;
                    }

                case JSToken.True:
                    ast = new ConstantWrapper(true, PrimitiveType.Boolean, m_currentToken.Clone(), this);
                    break;

                case JSToken.False:
                    ast = new ConstantWrapper(false, PrimitiveType.Boolean, m_currentToken.Clone(), this);
                    break;

                case JSToken.Null:
                    ast = new ConstantWrapper(null, PrimitiveType.Null, m_currentToken.Clone(), this);
                    break;

                case JSToken.PreprocessorConstant:
                    ast = new ConstantWrapperPP(m_currentToken.Code, false, m_currentToken.Clone(), this);
                    break;

                case JSToken.DivideAssign:
                // normally this token is not allowed on the left-hand side of an expression.
                // BUT, this might be the start of a regular expression that begins with an equals sign!
                // we need to test to see if we can parse a regular expression, and if not, THEN
                // we can fail the parse.

                case JSToken.Divide:
                    // could it be a regexp?
                    String source = m_scanner.ScanRegExp();
                    if (source != null)
                    {
                        // parse the flags (if any)
                        String flags = m_scanner.ScanRegExpFlags();
                        // create the literal
                        ast = new RegExpLiteral(source, flags, m_currentToken.Clone(), this);
                        break;
                    }
                    goto default;

                // expression
                case JSToken.LeftParenthesis:
                    {
                        // save the current context reference
                        Context openParenContext = m_currentToken.Clone();
                        GetNextToken();
                        m_noSkipTokenSet.Add(NoSkipTokenSet.s_ParenExpressionNoSkipToken);
                        try
                        {
                            // parse an expression
                            ast = ParseExpression();
                            
                            // update the expression's context with the context of the open paren
                            ast.Context.UpdateWith(openParenContext);
                            if (JSToken.RightParenthesis != m_currentToken.Token)
                            {
                                ReportError(JSError.NoRightParenthesis);
                            }
                            else
                            {
                                // add the closing paren to the expression context
                                ast.Context.UpdateWith(m_currentToken);
                            }
                        }
                        catch (RecoveryTokenException exc)
                        {
                            if (IndexOfToken(NoSkipTokenSet.s_ParenExpressionNoSkipToken, exc) == -1)
                                throw;
                            else
                                ast = exc._partiallyComputedNode;
                        }
                        finally
                        {
                            m_noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenExpressionNoSkipToken);
                        }
                        if (ast == null) //this can only happen when catching the exception and nothing was sent up by the caller
                            SkipTokensAndThrow();
                    }
                    break;

                // array initializer
                case JSToken.LeftBracket:
                    Context listCtx = m_currentToken.Clone();
                    AstNodeList list = new AstNodeList(m_currentToken.Clone(), this);
                    GetNextToken();
                    while (JSToken.RightBracket != m_currentToken.Token)
                    {
                        if (JSToken.Comma != m_currentToken.Token)
                        {
                            m_noSkipTokenSet.Add(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet);
                            try
                            {
                                list.Append(ParseExpression(true));
                                if (JSToken.Comma != m_currentToken.Token)
                                {
                                    if (JSToken.RightBracket != m_currentToken.Token)
                                        ReportError(JSError.NoRightBracket);
                                    break;
                                }
                                else
                                {
                                    // we have a comma -- skip it
                                    GetNextToken();

                                    // if the next token is the closing brackets, then we need to
                                    // add a missing value to the array because we end in a comma and
                                    // we need to keep it for cross-platform compat.
                                    // TECHNICALLY, that puts an extra item into the array for most modern browsers, but not ALL.
                                    if (m_currentToken.Token == JSToken.RightBracket)
                                    {
                                        list.Append(new ConstantWrapper(Missing.Value, PrimitiveType.Other, m_currentToken.Clone(), this));
                                    }
                                }
                            }
                            catch (RecoveryTokenException exc)
                            {
                                if (exc._partiallyComputedNode != null)
                                    list.Append(exc._partiallyComputedNode);
                                if (IndexOfToken(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet, exc) == -1)
                                {
                                    listCtx.UpdateWith(CurrentPositionContext());
                                    exc._partiallyComputedNode = new ArrayLiteral(listCtx, this, list);
                                    throw;
                                }
                                else
                                {
                                    if (JSToken.RightBracket == m_currentToken.Token)
                                        break;
                                }
                            }
                            finally
                            {
                                m_noSkipTokenSet.Remove(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet);
                            }
                        }
                        else
                        {
                            // comma -- missing array item in the list
                            list.Append(new ConstantWrapper(Missing.Value, PrimitiveType.Other, m_currentToken.Clone(), this));

                            // skip over the comma
                            GetNextToken();

                            // if the next token is the closing brace, then we end with a comma -- and we need to
                            // add ANOTHER missing value to make sure this last comma doesn't get left off.
                            // TECHNICALLY, that puts an extra item into the array for most modern browsers, but not ALL.
                            if (m_currentToken.Token == JSToken.RightBracket)
                            {
                                list.Append(new ConstantWrapper(Missing.Value, PrimitiveType.Other, m_currentToken.Clone(), this));
                            }
                        }
                    }
                    listCtx.UpdateWith(m_currentToken);
                    ast = new ArrayLiteral(listCtx, this, list);
                    break;

                // object initializer
                case JSToken.LeftCurly:
                    Context objCtx = m_currentToken.Clone();
                    GetNextToken();

                    // we're going to keep the keys and values in separate lists, but make sure
                    // that the indexes correlate (keyList[n] is associated with valueList[n])
                    List<ObjectLiteralField> keyList = new List<ObjectLiteralField>();
                    List<AstNode> valueList = new List<AstNode>();

                    if (JSToken.RightCurly != m_currentToken.Token)
                    {
                        for (; ; )
                        {
                            ObjectLiteralField field = null;
                            AstNode value = null;
                            bool getterSetter = false;
                            string ident;

                            switch (m_currentToken.Token)
                            {
                                case JSToken.Identifier:
                                    field = new ObjectLiteralField(m_scanner.GetIdentifier(), PrimitiveType.String, m_currentToken.Clone(), this);
                                    break;

                                case JSToken.StringLiteral:
                                    field = new ObjectLiteralField(m_scanner.StringLiteral, PrimitiveType.String, m_currentToken.Clone(), this);
                                    break;

                                case JSToken.IntegerLiteral:
                                case JSToken.NumericLiteral:
                                    {
                                        double doubleValue;
                                        if (ConvertNumericLiteralToDouble(m_currentToken.Code, (m_currentToken.Token == JSToken.IntegerLiteral), out doubleValue))
                                        {
                                            // conversion worked fine
                                            field = new ObjectLiteralField(
                                              doubleValue,
                                              PrimitiveType.Number,
                                              m_currentToken.Clone(),
                                              this
                                              );
                                        }
                                        else
                                        {
                                            // something went wrong and we're not sure the string representation in the source is 
                                            // going to convert to a numeric value well
                                            if (double.IsInfinity(doubleValue))
                                            {
                                                ReportError(JSError.NumericOverflow, m_currentToken.Clone(), true);
                                            }

                                            // use the source as the field name, not the numeric value
                                            field = new ObjectLiteralField(
                                                m_currentToken.Code,
                                                PrimitiveType.Other,
                                                m_currentToken.Clone(),
                                                this);
                                        }
                                        break;
                                    }

                                case JSToken.Get:
                                case JSToken.Set:
                                    if (m_scanner.PeekToken() == JSToken.Colon)
                                    {
                                        // the field is either "get" or "set" and isn't the special Mozilla getter/setter
                                        field = new ObjectLiteralField(m_currentToken.Code, PrimitiveType.String, m_currentToken.Clone(), this);
                                    }
                                    else
                                    {
                                        // ecma-script get/set property construct
                                        getterSetter = true;
                                        bool isGet = (m_currentToken.Token == JSToken.Get);
                                        value = ParseFunction(
                                          (JSToken.Get == m_currentToken.Token ? FunctionType.Getter : FunctionType.Setter),
                                          m_currentToken.Clone()
                                          );
                                        FunctionObject funcExpr = value as FunctionObject;
                                        if (funcExpr != null)
                                        {
                                            // getter/setter is just the literal name with a get/set flag
                                            field = new GetterSetter(
                                              funcExpr.Name,
                                              isGet,
                                              funcExpr.IdContext.Clone(),
                                              this
                                              );
                                        }
                                        else
                                        {
                                            ReportError(JSError.FunctionExpressionExpected);
                                        }
                                    }
                                    break;

                                default:
                                    // NOT: identifier, string, number, or getter/setter.
                                    // see if it's a token that COULD be an identifier.
                                    ident = JSKeyword.CanBeIdentifier(m_currentToken.Token);
                                    if (ident != null)
                                    {
                                        // don't throw a warning -- it's okay to have a keyword that
                                        // can be an identifier here.
                                        field = new ObjectLiteralField(ident, PrimitiveType.String, m_currentToken.Clone(), this);
                                    }
                                    else
                                    {
                                        ReportError(JSError.NoMemberIdentifier);
                                        field = new ObjectLiteralField("_#Missing_Field#_" + s_cDummyName++, PrimitiveType.String, CurrentPositionContext(), this);
                                    }
                                    break;
                            }

                            if (field != null)
                            {
                                if (!getterSetter)
                                {
                                    GetNextToken();
                                }

                                m_noSkipTokenSet.Add(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet);
                                try
                                {
                                    if (!getterSetter)
                                    {
                                        // get the value
                                        if (JSToken.Colon != m_currentToken.Token)
                                        {
                                            ReportError(JSError.NoColon, true);
                                            value = ParseExpression(true);
                                        }
                                        else
                                        {
                                            GetNextToken();
                                            value = ParseExpression(true);
                                        }
                                    }

                                    // put the pair into the list of fields
                                    keyList.Add(field);
                                    valueList.Add(value);

                                    if (JSToken.RightCurly == m_currentToken.Token)
                                        break;
                                    else
                                    {
                                        if (JSToken.Comma == m_currentToken.Token)
                                        {
                                            // skip the comma
                                            GetNextToken();

                                            // if the next token is the right-curly brace, then we ended 
                                            // the list with a comma, which is perfectly fine
                                            if (m_currentToken.Token == JSToken.RightCurly)
                                            {
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            if (m_scanner.GotEndOfLine)
                                            {
                                                ReportError(JSError.NoRightCurly);
                                            }
                                            else
                                                ReportError(JSError.NoComma, true);
                                            SkipTokensAndThrow();
                                        }
                                    }
                                }
                                catch (RecoveryTokenException exc)
                                {
                                    if (exc._partiallyComputedNode != null)
                                    {
                                        // the problem was in ParseExpression trying to determine value
                                        value = exc._partiallyComputedNode;
                                        keyList.Add(field);
                                        valueList.Add(value);
                                    }
                                    if (IndexOfToken(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet, exc) == -1)
                                    {
                                        exc._partiallyComputedNode = new ObjectLiteral(objCtx, this, keyList.ToArray(), valueList.ToArray());
                                        throw;
                                    }
                                    else
                                    {
                                        if (JSToken.Comma == m_currentToken.Token)
                                            GetNextToken();
                                        if (JSToken.RightCurly == m_currentToken.Token)
                                            break;
                                    }
                                }
                                finally
                                {
                                    m_noSkipTokenSet.Remove(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet);
                                }
                            }
                        }
                    }
                    objCtx.UpdateWith(m_currentToken);
                    ast = new ObjectLiteral(objCtx, this, keyList.ToArray(), valueList.ToArray());
                    break;

                // function expression
                case JSToken.Function:
                    ast = ParseFunction(FunctionType.Expression, m_currentToken.Clone());
                    isFunction = true;
                    break;

                case JSToken.AspNetBlock:
                    ast = ParseAspNetBlock(consumeSemicolonIfPossible: false);
                    break;

                default:
                    string identifier = JSKeyword.CanBeIdentifier(m_currentToken.Token);
                    if (null != identifier)
                    {
                        ast = new Lookup(identifier, m_currentToken.Clone(), this);
                    }
                    else
                    {
                        ReportError(JSError.ExpressionExpected);
                        SkipTokensAndThrow();
                    }
                    break;
            }

            // can be a CallExpression, that is, followed by '.' or '(' or '['
            if (!isFunction)
                GetNextToken();

            return MemberExpression(ast, newContexts);
        }
Esempio n. 43
0
 void ArrayLiteral(Scope scope, out IExpression expr)
 {
     IExpression innerExpr;
     Expect(10);
     List<IExpression> innerExprs = new List<IExpression>();
     if (StartOf(1)) {
         Expression(scope, out innerExpr);
         innerExprs.Add(innerExpr);
         while (la.kind == 11) {
             Get();
             Expression(scope, out innerExpr);
             innerExprs.Add(innerExpr);
         }
     }
     Expect(12);
     expr = new ArrayLiteral(innerExprs);
 }
Esempio n. 44
0
 public override bool Enter(ArrayLiteral node)
 {
     Print("ArrayLiteral");
     level++;
     return true;
 }
Esempio n. 45
0
        public override void Visit(CallNode node)
        {
            if (node != null)
            {
                // see if this is a member (we'll need it for a couple checks)
                Member member = node.Function as Member;

                if (m_parser.Settings.StripDebugStatements
                    && m_parser.Settings.IsModificationAllowed(TreeModifications.StripDebugStatements))
                {
                    // if this is a member, and it's a debugger object, and it's a constructor....
                    if (member != null && member.IsDebuggerStatement && node.IsConstructor)
                    {
                        // we need to replace our debugger object with a generic Object
                        node.ReplaceChild(node.Function, new Lookup("Object", node.Function.Context, m_parser));

                        // and make sure the node list is empty
                        if (node.Arguments != null && node.Arguments.Count > 0)
                        {
                            node.ReplaceChild(node.Arguments, new AstNodeList(node.Arguments.Context, m_parser));
                        }
                    }
                }

                // if this is a constructor and we want to collapse
                // some of them to literals...
                if (node.IsConstructor && m_parser.Settings.CollapseToLiteral)
                {
                    // see if this is a lookup, and if so, if it's pointing to one
                    // of the two constructors we want to collapse
                    Lookup lookup = node.Function as Lookup;
                    if (lookup != null)
                    {
                        if (lookup.Name == "Object"
                            && m_parser.Settings.IsModificationAllowed(TreeModifications.NewObjectToObjectLiteral))
                        {
                            // no arguments -- the Object constructor with no arguments is the exact same as an empty
                            // object literal
                            if (node.Arguments == null || node.Arguments.Count == 0)
                            {
                                // replace our node with an object literal
                                ObjectLiteral objLiteral = new ObjectLiteral(node.Context, m_parser, null, null);
                                if (node.Parent.ReplaceChild(node, objLiteral))
                                {
                                    // and bail now. No need to recurse -- it's an empty literal
                                    return;
                                }
                            }
                            else if (node.Arguments.Count == 1)
                            {
                                // one argument
                                // check to see if it's an object literal.
                                ObjectLiteral objectLiteral = node.Arguments[0] as ObjectLiteral;
                                if (objectLiteral != null)
                                {
                                    // the Object constructor with an argument that is a JavaScript object merely returns the
                                    // argument. Since the argument is an object literal, it is by definition a JavaScript object
                                    // and therefore we can replace the constructor call with the object literal
                                    node.Parent.ReplaceChild(node, objectLiteral);

                                    // don't forget to recurse the object now
                                    objectLiteral.Accept(this);

                                    // and then bail -- we don't want to process this call
                                    // operation any more; we've gotten rid of it
                                    return;
                                }
                            }
                        }
                        else if (lookup.Name == "Array"
                            && m_parser.Settings.IsModificationAllowed(TreeModifications.NewArrayToArrayLiteral))
                        {
                            // Array is trickier.
                            // If there are no arguments, then just use [].
                            // if there are multiple arguments, then use [arg0,arg1...argN].
                            // but if there is one argument and it's numeric, we can't crunch it.
                            // also can't crunch if it's a function call or a member or something, since we won't
                            // KNOW whether or not it's numeric.
                            //
                            // so first see if it even is a single-argument constant wrapper.
                            ConstantWrapper constWrapper = (node.Arguments != null && node.Arguments.Count == 1
                                ? node.Arguments[0] as ConstantWrapper
                                : null);

                            // if the argument count is not one, then we crunch.
                            // if the argument count IS one, we only crunch if we have a constant wrapper,
                            // AND it's not numeric.
                            if (node.Arguments == null
                              || node.Arguments.Count != 1
                              || (constWrapper != null && !constWrapper.IsNumericLiteral))
                            {
                                // create the new array literal object
                                ArrayLiteral arrayLiteral = new ArrayLiteral(node.Context, m_parser, node.Arguments);

                                // replace ourself within our parent
                                if (node.Parent.ReplaceChild(node, arrayLiteral))
                                {
                                    // recurse
                                    arrayLiteral.Accept(this);
                                    // and bail -- we don't want to recurse this node any more
                                    return;
                                }
                            }
                        }
                    }
                }

                // if we are replacing resource references with strings generated from resource files
                // and this is a brackets call: lookup[args]
                ResourceStrings resourceStrings = m_parser.ResourceStrings;
                if (node.InBrackets && resourceStrings != null && resourceStrings.Count > 0)
                {
                    // see if the root object is a lookup that corresponds to the
                    // global value (not a local field) for our resource object
                    // (same name)
                    Lookup rootLookup = node.Function as Lookup;
                    if (rootLookup != null
                        && rootLookup.LocalField == null
                        && string.CompareOrdinal(rootLookup.Name, resourceStrings.Name) == 0)
                    {
                        // we're going to replace this node with a string constant wrapper
                        // but first we need to make sure that this is a valid lookup.
                        // if the parameter contains anything that would vary at run-time,
                        // then we need to throw an error.
                        // the parser will always have either one or zero nodes in the arguments
                        // arg list. We're not interested in zero args, so just make sure there is one
                        if (node.Arguments.Count == 1)
                        {
                            // must be a constant wrapper
                            ConstantWrapper argConstant = node.Arguments[0] as ConstantWrapper;
                            if (argConstant != null)
                            {
                                string resourceName = argConstant.Value.ToString();

                                // get the localized string from the resources object
                                ConstantWrapper resourceLiteral = new ConstantWrapper(
                                    resourceStrings[resourceName],
                                    PrimitiveType.String,
                                    node.Context,
                                    m_parser);

                                // replace this node with localized string, analyze it, and bail
                                // so we don't anaylze the tree we just replaced
                                node.Parent.ReplaceChild(node, resourceLiteral);
                                resourceLiteral.Accept(this);
                                return;
                            }
                            else
                            {
                                // error! must be a constant
                                node.Context.HandleError(
                                    JSError.ResourceReferenceMustBeConstant,
                                    true);
                            }
                        }
                        else
                        {
                            // error! can only be a single constant argument to the string resource object.
                            // the parser will only have zero or one arguments, so this must be zero
                            // (since the parser won't pass multiple args to a [] operator)
                            node.Context.HandleError(
                                JSError.ResourceReferenceMustBeConstant,
                                true);
                        }
                    }
                }

                // and finally, if this is a backets call and the argument is a constantwrapper that can
                // be an identifier, just change us to a member node:  obj["prop"] to obj.prop.
                // but ONLY if the string value is "safe" to be an identifier. Even though the ECMA-262
                // spec says certain Unicode categories are okay, in practice the various major browsers
                // all seem to have problems with certain characters in identifiers. Rather than risking
                // some browsers breaking when we change this syntax, don't do it for those "danger" categories.
                if (node.InBrackets && node.Arguments != null)
                {
                    // see if there is a single, constant argument
                    string argText = node.Arguments.SingleConstantArgument;
                    if (argText != null)
                    {
                        // see if we want to replace the name
                        string newName;
                        if (m_parser.Settings.HasRenamePairs && m_parser.Settings.ManualRenamesProperties
                            && m_parser.Settings.IsModificationAllowed(TreeModifications.PropertyRenaming)
                            && !string.IsNullOrEmpty(newName = m_parser.Settings.GetNewName(argText)))
                        {
                            // yes -- we are going to replace the name, either as a string literal, or by converting
                            // to a member-dot operation.
                            // See if we can't turn it into a dot-operator. If we can't, then we just want to replace the operator with
                            // a new constant wrapper. Otherwise we'll just replace the operator with a new constant wrapper.
                            if (m_parser.Settings.IsModificationAllowed(TreeModifications.BracketMemberToDotMember)
                                && JSScanner.IsSafeIdentifier(newName)
                                && !JSScanner.IsKeyword(newName, node.EnclosingScope.UseStrict))
                            {
                                // the new name is safe to convert to a member-dot operator.
                                // but we don't want to convert the node to the NEW name, because we still need to Analyze the
                                // new member node -- and it might convert the new name to something else. So instead we're
                                // just going to convert this existing string to a member node WITH THE OLD STRING,
                                // and THEN analyze it (which will convert the old string to newName)
                                Member replacementMember = new Member(node.Context, m_parser, node.Function, argText, node.Arguments[0].Context);
                                node.Parent.ReplaceChild(node, replacementMember);

                                // this analyze call will convert the old-name member to the newName value
                                replacementMember.Accept(this);
                                return;
                            }
                            else
                            {
                                // nope; can't convert to a dot-operator.
                                // we're just going to replace the first argument with a new string literal
                                // and continue along our merry way.
                                node.Arguments.ReplaceChild(node.Arguments[0], new ConstantWrapper(newName, PrimitiveType.String, node.Arguments[0].Context, m_parser));
                            }
                        }
                        else if (m_parser.Settings.IsModificationAllowed(TreeModifications.BracketMemberToDotMember)
                            && JSScanner.IsSafeIdentifier(argText)
                            && !JSScanner.IsKeyword(argText, node.EnclosingScope.UseStrict))
                        {
                            // not a replacement, but the string literal is a safe identifier. So we will
                            // replace this call node with a Member-dot operation
                            Member replacementMember = new Member(node.Context, m_parser, node.Function, argText, node.Arguments[0].Context);
                            node.Parent.ReplaceChild(node, replacementMember);
                            replacementMember.Accept(this);
                            return;
                        }
                    }
                }

                // call the base class to recurse
                base.Visit(node);

                // might have changed
                member = node.Function as Member;

                // call this AFTER recursing to give the fields a chance to resolve, because we only
                // want to make this replacement if we are working on the global Date object.
                if (!node.InBrackets && !node.IsConstructor
                    && (node.Arguments == null || node.Arguments.Count == 0)
                    && member != null && string.CompareOrdinal(member.Name, "getTime") == 0
                    && m_parser.Settings.IsModificationAllowed(TreeModifications.DateGetTimeToUnaryPlus))
                {
                    // this is not a constructor and it's not a brackets call, and there are no arguments.
                    // if the function is a member operation to "getTime" and the object of the member is a
                    // constructor call to the global "Date" object (not a local), then we want to replace the call
                    // with a unary plus on the Date constructor. Converting to numeric type is the same as
                    // calling getTime, so it's the equivalent with much fewer bytes.
                    CallNode dateConstructor = member.Root as CallNode;
                    if (dateConstructor != null
                        && dateConstructor.IsConstructor)
                    {
                        // lookup for the predifined (not local) "Date" field
                        Lookup lookup = dateConstructor.Function as Lookup;
                        if (lookup != null && string.CompareOrdinal(lookup.Name, "Date") == 0
                            && lookup.LocalField == null)
                        {
                            // this is in the pattern: (new Date()).getTime()
                            // we want to replace it with +new Date
                            // use the same date constructor node as the operand
                            NumericUnary unary = new NumericUnary(node.Context, m_parser, dateConstructor, JSToken.Plus);

                            // replace us (the call to the getTime method) with this unary operator
                            node.Parent.ReplaceChild(node, unary);

                            // don't need to recurse on the unary operator. The operand has already
                            // been analyzed when we recursed, and the unary operator wouldn't do anything
                            // special anyway (since the operand is not a numeric constant)
                        }
                    }
                }
                else
                {
                    var isEval = false;

                    var lookup = node.Function as Lookup;
                    if (lookup != null
                        && string.CompareOrdinal(lookup.Name, "eval") == 0
                        && lookup.VariableField is JSPredefinedField)
                    {
                        // call to predefined eval function
                        isEval = true;
                    }
                    else if (member != null && string.CompareOrdinal(member.Name, "eval") == 0)
                    {
                        // if this is a window.eval call, then we need to mark this scope as unknown just as
                        // we would if this was a regular eval call.
                        // (unless, of course, the parser settings say evals are safe)
                        // call AFTER recursing so we know the left-hand side properties have had a chance to
                        // lookup their fields to see if they are local or global
                        if (member.LeftHandSide.IsWindowLookup)
                        {
                            // this is a call to window.eval()
                            isEval = true;
                        }
                    }
                    else
                    {
                        CallNode callNode = node.Function as CallNode;
                        if (callNode != null
                            && callNode.InBrackets
                            && callNode.LeftHandSide.IsWindowLookup
                            && callNode.Arguments.IsSingleConstantArgument("eval"))
                        {
                            // this is a call to window["eval"]
                            isEval = true;
                        }
                    }

                    if (isEval)
                    {
                        if (m_parser.Settings.EvalTreatment != EvalTreatment.Ignore)
                        {
                            // mark this scope as unknown so we don't crunch out locals
                            // we might reference in the eval at runtime
                            ScopeStack.Peek().IsKnownAtCompileTime = false;
                        }
                    }
                }
            }
        }
Esempio n. 46
0
 public override void Visit(ArrayLiteral node)
 {
     // same logic for most nodes
     TypicalHandler(node);
 }
Esempio n. 47
0
 public virtual object Walk(ArrayLiteral node)
 {
     if (Enter(node))
     {
         foreach (var exp in node.Expressions)
         {
             exp.Accept(this);
         }
     }
     Exit(node);
     return null;
 }