public virtual void Visit(JsLexicalDeclaration node) { if (node != null) { foreach (var childNode in node.Children) { childNode.Accept(this); } } }
public void Visit(JsLexicalDeclaration node) { // invalid! ignore IsValid = false; }
public void Visit(JsLexicalDeclaration node) { if (node != null) { // lexical declarations get an order index node.Index = NextOrderIndex; for (var ndx = 0; ndx < node.Count; ++ndx) { var decl = node[ndx]; if (decl != null) { decl.Accept(this); } } } }
public void Visit(JsLexicalDeclaration node) { Debug.Fail("shouldn't get here"); }
//--------------------------------------------------------------------------------------- // ParseVariableStatement // // VariableStatement : // 'var' VariableDeclarationList // or // 'const' VariableDeclarationList // or // 'let' VariableDeclarationList // // VariableDeclarationList : // VariableDeclaration | // VariableDeclaration ',' VariableDeclarationList // // VariableDeclaration : // Identifier Initializer // // Initializer : // <empty> | // '=' AssignmentExpression //--------------------------------------------------------------------------------------- private JsAstNode ParseVariableStatement() { // create the appropriate statement: var- or const-statement JsDeclaration varList; if (m_currentToken.Token == JsToken.Var) { varList = new JsVar(m_currentToken.Clone(), this); } else if (m_currentToken.Token == JsToken.Const || m_currentToken.Token == JsToken.Let) { if (m_currentToken.Token == JsToken.Const && m_settings.ConstStatementsMozilla) { varList = new JsConstStatement(m_currentToken.Clone(), this); } else { varList = new JsLexicalDeclaration(m_currentToken.Clone(), this) { StatementToken = m_currentToken.Token }; } } else { Debug.Fail("shouldn't get here"); return null; } bool single = true; JsAstNode vdecl = null; JsAstNode identInit = null; for (; ; ) { m_noSkipTokenSet.Add(NoSkipTokenSet.s_EndOfLineToken); try { identInit = ParseIdentifierInitializer(JsToken.None); } catch (RecoveryTokenException exc) { // an exception is passing by, possibly bringing some info, save the info if any if (exc._partiallyComputedNode != null) { if (!single) { varList.Append(exc._partiallyComputedNode); varList.Context.UpdateWith(exc._partiallyComputedNode.Context); exc._partiallyComputedNode = varList; } } if (IndexOfToken(NoSkipTokenSet.s_EndOfLineToken, exc) == -1) throw; else { if (single) identInit = exc._partiallyComputedNode; } } finally { m_noSkipTokenSet.Remove(NoSkipTokenSet.s_EndOfLineToken); } if (identInit != null) { vdecl = identInit; varList.Append(vdecl); } if (m_currentToken.Token == JsToken.Comma) { single = false; vdecl.IfNotNull(d => d.TerminatingContext = m_currentToken.Clone()); } else if (m_currentToken.Token == JsToken.Semicolon) { varList.TerminatingContext = m_currentToken.Clone(); GetNextToken(); break; } else if (m_foundEndOfLine || m_currentToken.Token == JsToken.RightCurly || m_currentToken.Token == JsToken.EndOfFile) { // semicolon insertion rules // a right-curly or an end of line is something we don't WANT to throw a warning for. // Just too common and doesn't really warrant a warning (in my opinion) if (JsToken.RightCurly != m_currentToken.Token && JsToken.EndOfFile != m_currentToken.Token) { ReportError(JsError.SemicolonInsertion, varList.Context.IfNotNull(c => c.FlattenToEnd()), true); } break; } else { ReportError(JsError.NoSemicolon, false); break; } } if (vdecl != null) { varList.Context.UpdateWith(vdecl.Context); } return varList; }
private JsAstNode ParseForStatement() { m_blockType.Add(BlockType.Loop); JsAstNode forNode = null; try { JsContext forCtx = m_currentToken.Clone(); GetNextToken(); if (JsToken.LeftParenthesis != m_currentToken.Token) { ReportError(JsError.NoLeftParenthesis); } GetNextToken(); bool isForIn = false, recoveryInForIn = false; JsAstNode lhs = null, initializer = null, condOrColl = null, increment = null; JsContext operatorContext = null; JsContext separator1Context = null; JsContext separator2Context = null; try { if (JsToken.Var == m_currentToken.Token || JsToken.Let == m_currentToken.Token || JsToken.Const == m_currentToken.Token) { isForIn = true; JsDeclaration declaration; if (m_currentToken.Token == JsToken.Var) { declaration = new JsVar(m_currentToken.Clone(), this); } else { declaration = new JsLexicalDeclaration(m_currentToken.Clone(), this) { StatementToken = m_currentToken.Token }; } declaration.Append(ParseIdentifierInitializer(JsToken.In)); // a list of variable initializers is allowed only in a for(;;) while (JsToken.Comma == m_currentToken.Token) { isForIn = false; declaration.Append(ParseIdentifierInitializer(JsToken.In)); //initializer = new Comma(initializer.context.CombineWith(var.context), initializer, var); } initializer = declaration; // if it could still be a for..in, now it's time to get the 'in' // TODO: for ES6 might be 'of' if (isForIn) { if (JsToken.In == m_currentToken.Token || (m_currentToken.Token == JsToken.Identifier && string.CompareOrdinal(m_currentToken.Code, "of") == 0)) { operatorContext = m_currentToken.Clone(); GetNextToken(); condOrColl = ParseExpression(); } else { isForIn = false; } } } else { if (JsToken.Semicolon != m_currentToken.Token) { bool isLHS; initializer = ParseUnaryExpression(out isLHS, false); if (isLHS && (JsToken.In == m_currentToken.Token || (m_currentToken.Token == JsToken.Identifier && string.CompareOrdinal(m_currentToken.Code, "of") == 0))) { isForIn = true; operatorContext = m_currentToken.Clone(); lhs = initializer; initializer = null; GetNextToken(); m_noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { condOrColl = ParseExpression(); } catch (RecoveryTokenException exc) { if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1) { exc._partiallyComputedNode = null; throw; } else { if (exc._partiallyComputedNode == null) condOrColl = new JsConstantWrapper(true, JsPrimitiveType.Boolean, CurrentPositionContext(), this); // what could we put here? else condOrColl = exc._partiallyComputedNode; } if (exc._token == JsToken.RightParenthesis) { GetNextToken(); recoveryInForIn = true; } } finally { m_noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } } else { initializer = ParseExpression(initializer, false, isLHS, JsToken.In); } } } } catch (RecoveryTokenException exc) { // error is too early abort for exc._partiallyComputedNode = null; throw; } // at this point we know whether or not is a for..in if (isForIn) { if (!recoveryInForIn) { if (JsToken.RightParenthesis != m_currentToken.Token) ReportError(JsError.NoRightParenthesis); forCtx.UpdateWith(m_currentToken); GetNextToken(); } JsAstNode body = null; // if the statements aren't withing curly-braces, throw a possible error if (JsToken.LeftCurly != m_currentToken.Token) { ReportError(JsError.StatementBlockExpected, CurrentPositionContext(), true); } try { // parse a Statement, not a SourceElement // and ignore any important comments that spring up right here. body = ParseStatement(false, true); } catch (RecoveryTokenException exc) { if (exc._partiallyComputedNode == null) body = new JsBlock(CurrentPositionContext(), this); else body = exc._partiallyComputedNode; exc._partiallyComputedNode = new JsForIn(forCtx, this) { Variable = (lhs != null ? lhs : initializer), OperatorContext = operatorContext, Collection = condOrColl, Body = JsAstNode.ForceToBlock(body), }; throw; } // for (a in b) // lhs = a, initializer = null // for (var a in b) // lhs = null, initializer = var a forNode = new JsForIn(forCtx, this) { Variable = (lhs != null ? lhs : initializer), OperatorContext = operatorContext, Collection = condOrColl, Body = JsAstNode.ForceToBlock(body), }; } else { m_noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { if (JsToken.Semicolon == m_currentToken.Token) { separator1Context = m_currentToken.Clone(); } else { ReportError(JsError.NoSemicolon); if (JsToken.Colon == m_currentToken.Token) { m_noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet); try { SkipTokensAndThrow(); } catch (RecoveryTokenException) { if (JsToken.Semicolon == m_currentToken.Token) { m_useCurrentForNext = false; } else { throw; } } finally { m_noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet); } } } GetNextToken(); if (JsToken.Semicolon != m_currentToken.Token) { condOrColl = ParseExpression(); if (JsToken.Semicolon != m_currentToken.Token) { ReportError(JsError.NoSemicolon); } } separator2Context = m_currentToken.Clone(); GetNextToken(); if (JsToken.RightParenthesis != m_currentToken.Token) { increment = ParseExpression(); } if (JsToken.RightParenthesis != m_currentToken.Token) { ReportError(JsError.NoRightParenthesis); } forCtx.UpdateWith(m_currentToken); GetNextToken(); } catch (RecoveryTokenException exc) { if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1) { exc._partiallyComputedNode = null; throw; } else { // discard any partial info, just genrate empty condition and increment and keep going exc._partiallyComputedNode = null; if (condOrColl == null) condOrColl = new JsConstantWrapper(true, JsPrimitiveType.Boolean, CurrentPositionContext(), this); } if (exc._token == JsToken.RightParenthesis) { GetNextToken(); } } finally { m_noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } // if this is an assignment, throw a warning in case the developer // meant to use == instead of = // but no warning if the condition is wrapped in parens. var binOp = condOrColl as JsBinaryOperator; if (binOp != null && binOp.OperatorToken == JsToken.Assign) { condOrColl.Context.HandleError(JsError.SuspectAssignment); } JsAstNode body = null; // if the statements aren't withing curly-braces, throw a possible error if (JsToken.LeftCurly != m_currentToken.Token) { ReportError(JsError.StatementBlockExpected, CurrentPositionContext(), true); } try { // parse a Statement, not a SourceElement // and ignore any important comments that spring up right here. body = ParseStatement(false, true); } catch (RecoveryTokenException exc) { if (exc._partiallyComputedNode == null) body = new JsBlock(CurrentPositionContext(), this); else body = exc._partiallyComputedNode; exc._partiallyComputedNode = new JsForNode(forCtx, this) { Initializer = initializer, Separator1Context = separator1Context, Condition = condOrColl, Separator2Context = separator2Context, Incrementer = increment, Body = JsAstNode.ForceToBlock(body) }; throw; } forNode = new JsForNode(forCtx, this) { Initializer = initializer, Separator1Context = separator1Context, Condition = condOrColl, Separator2Context = separator2Context, Incrementer = increment, Body = JsAstNode.ForceToBlock(body) }; } } finally { m_blockType.RemoveAt(m_blockType.Count - 1); } return forNode; }
public void Visit(JsLexicalDeclaration node) { // not applicable; terminate }
public void Visit(JsLexicalDeclaration node) { if (node != null) { var symbol = StartSymbol(node); // save the no-in state -- we'll reset before processing each initializer var isNoIn = m_noIn; Output(OperatorString(node.StatementToken)); MarkSegment(node, null, node.Context); SetContextOutputPosition(node.Context); m_startOfStatement = false; Indent(); var useNewLines = !(node.Parent is JsForNode); for (var ndx = 0; ndx < node.Count; ++ndx) { var decl = node[ndx]; if (decl != null) { if (ndx > 0) { OutputPossibleLineBreak(','); if (useNewLines) { NewLine(); } else if (m_settings.OutputMode == MinifierOutputMode.MultipleLines) { OutputPossibleLineBreak(' '); } } // be sure to set the no-in state to whatever it was when we entered // this node, because each declaration might reset it as it's outputting // its child nodes m_noIn = isNoIn; decl.Accept(this); } } Unindent(); EndSymbol(symbol); } }