1 | // Copyright (C) 2005 Google Inc. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package com.google.caja.parser.js; |
16 | |
17 | import com.google.caja.lexer.FilePosition; |
18 | import com.google.caja.lexer.TokenConsumer; |
19 | import com.google.caja.parser.ParseTreeNode; |
20 | import com.google.caja.reporting.RenderContext; |
21 | import com.google.javascript.jscomp.jsonml.JsonML; |
22 | import com.google.javascript.jscomp.jsonml.TagType; |
23 | |
24 | import java.util.List; |
25 | |
26 | /** |
27 | * A top level statement that declares a variable and assigns a function to it. |
28 | * |
29 | * @author mikesamuel@gmail.com |
30 | */ |
31 | public final class FunctionDeclaration extends Declaration { |
32 | @ReflectiveCtor |
33 | public FunctionDeclaration( |
34 | FilePosition pos, Void value, List<? extends ParseTreeNode> children) { |
35 | super(pos, value, children); |
36 | } |
37 | |
38 | public FunctionDeclaration( |
39 | FunctionConstructor initializer) { |
40 | super(initializer.getFilePosition(), |
41 | (Identifier) initializer.getIdentifier().clone(), |
42 | initializer); |
43 | } |
44 | |
45 | @Override |
46 | protected void childrenChanged() { |
47 | super.childrenChanged(); |
48 | FunctionConstructor initializer = getInitializer(); // Checks class. |
49 | if (null == initializer) { |
50 | throw new NullPointerException( |
51 | "Function declaration missing function"); |
52 | } |
53 | if (!getIdentifierName().equals(initializer.getIdentifierName())) { |
54 | throw new IllegalStateException("Name mismatch"); |
55 | } |
56 | } |
57 | |
58 | @Override |
59 | public FunctionConstructor getInitializer() { |
60 | return (FunctionConstructor) super.getInitializer(); |
61 | } |
62 | |
63 | @Override |
64 | public boolean isTerminal() { |
65 | return getInitializer().getBody().isTerminal(); |
66 | } |
67 | |
68 | @Override |
69 | public void render(RenderContext rc) { |
70 | FunctionConstructor fc = getInitializer(); |
71 | TokenConsumer out = rc.getOut(); |
72 | out.mark(getFilePosition()); |
73 | out.consume("function"); |
74 | getIdentifier().render(rc); |
75 | out.consume("("); |
76 | boolean seen = false; |
77 | for (FormalParam p : fc.getParams()) { |
78 | if (seen) { |
79 | out.consume(","); |
80 | } else { |
81 | seen = true; |
82 | } |
83 | p.render(rc); |
84 | } |
85 | out.consume(")"); |
86 | fc.getBody().renderBlock(rc, false); |
87 | } |
88 | |
89 | @Override |
90 | public JsonML toJsonML() { |
91 | FunctionConstructor fc = getInitializer(); |
92 | JsonML exprJsonMl = fc.toJsonML(); |
93 | return new JsonML( |
94 | TagType.FunctionDecl, exprJsonMl.getAttributes(), |
95 | exprJsonMl.getChildren()); |
96 | } |
97 | } |