1 /* 2 * Copyright 2000-2005 JetBrains s.r.o. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.intellij.lang.javascript.parsing; 17 18 import com.intellij.lang.PsiBuilder; 19 import com.intellij.lang.javascript.JSElementTypes; 20 import com.intellij.lang.javascript.JSTokenTypes; 21 import com.intellij.openapi.diagnostic.Logger; 22 23 /** 24 * Created by IntelliJ IDEA. 25 * User: max 26 * Date: Jan 28, 2005 27 * Time: 1:20:19 PM 28 * To change this template use File | Settings | File Templates. 29 */ 30 public class FunctionParsing { 31 private static final Logger LOG = Logger.getInstance("#com.intellij.lang.javascript.parsing.FunctionParsing"); 32 33 private FunctionParsing() { } 34 35 public static void parseFunctionExpression(PsiBuilder builder) { 36 parseFunction(builder, true); 37 } 38 39 public static void parseFunctionDeclaration(PsiBuilder builder) { 40 parseFunction(builder, false); 41 } 42 43 private static void parseFunction(PsiBuilder builder, boolean expressionContext) { 44 final PsiBuilder.Marker functionMarker = builder.mark(); 45 if (builder.getTokenType() == JSTokenTypes.FUNCTION_KEYWORD) { // function keyword may be ommited in context of get/set property definition 46 builder.advanceLexer(); 47 } 48 49 // Function name 50 if (builder.getTokenType() == JSTokenTypes.IDENTIFIER) { 51 builder.advanceLexer(); 52 } 53 else { 54 if (!expressionContext) { 55 builder.error("function name expected"); 56 } 57 } 58 59 parseParameterList(builder); 60 61 StatementParsing.parseFunctionBody(builder); 62 63 functionMarker.done(expressionContext ? JSElementTypes.FUNCTION_EXPRESSION : JSElementTypes.FUNCTION_DECLARATION); 64 } 65 66 private static void parseParameterList(final PsiBuilder builder) { 67 final PsiBuilder.Marker parameterList; 68 if (builder.getTokenType() != JSTokenTypes.LPAR) { 69 builder.error("( expected"); 70 parameterList = builder.mark(); // To have non-empty parameters list at all the time. 71 parameterList.done(JSElementTypes.PARAMETER_LIST); 72 return; 73 } 74 else { 75 parameterList = builder.mark(); 76 builder.advanceLexer(); 77 } 78 79 boolean first = true; 80 while (builder.getTokenType() != JSTokenTypes.RPAR) { 81 if (first) { 82 first = false; 83 } 84 else { 85 if (builder.getTokenType() == JSTokenTypes.COMMA) { 86 builder.advanceLexer(); 87 } 88 else { 89 builder.error(", or ) expected"); 90 break; 91 } 92 } 93 94 final PsiBuilder.Marker parameter = builder.mark(); 95 if (builder.getTokenType() == JSTokenTypes.IDENTIFIER) { 96 builder.advanceLexer(); 97 parameter.done(JSElementTypes.FORMAL_PARAMETER); 98 } 99 else { 100 builder.error("formal parameter name expected"); 101 parameter.rollbackTo(); 102 } 103 } 104 105 if (builder.getTokenType() == JSTokenTypes.RPAR) { 106 builder.advanceLexer(); 107 } 108 109 parameterList.done(JSElementTypes.PARAMETER_LIST); 110 } 111 } 112