| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package flash.tools.debugger.expression; |
| |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import com.adobe.flash.compiler.problems.ICompilerProblem; |
| import com.adobe.flash.compiler.tree.as.IASNode; |
| |
| import flash.localization.LocalizationManager; |
| import flash.tools.debugger.DebuggerLocalizer; |
| |
| /** |
| * ASTBuilder.java |
| * |
| * This class creates an abstract syntax tree representation |
| * of an expression given a sequence of tokens. |
| * |
| * The tree is built by calling the ActionScript compiler and |
| * having it parse the expression, then converting the result |
| * to a form we prefer. |
| * |
| * No compression is performed on the tree, thus expressions |
| * such as (3*4) will result in 3 nodes. |
| * |
| */ |
| public class ASTBuilder implements IASTBuilder |
| { |
| private static LocalizationManager s_localizationManager; |
| |
| /** |
| * whether the fdb indirection operators are allowed, e.g. asterisk (*x) or |
| * trailing dot (x.) |
| */ |
| private boolean m_isIndirectionOperatorAllowed = true; |
| |
| static |
| { |
| // set up for localizing messages |
| s_localizationManager = new LocalizationManager(); |
| s_localizationManager.addLocalizer( new DebuggerLocalizer("flash.tools.debugger.expression.expression.") ); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param isIndirectionOperatorAllowed |
| * whether the fdb indirection operators are allowed, e.g. |
| * asterisk (*x) or trailing dot (x.) |
| */ |
| public ASTBuilder(boolean isIndirectionOperatorAllowed) |
| { |
| m_isIndirectionOperatorAllowed = isIndirectionOperatorAllowed; |
| } |
| |
| /** |
| * @return whether the fdb indirection operators are allowed, e.g. asterisk |
| * (*x) or trailing dot (x.) |
| */ |
| public boolean isIndirectionOperatorAllowed() |
| { |
| return m_isIndirectionOperatorAllowed; |
| } |
| |
| |
| /* |
| * @see flash.tools.debugger.expression.IASTBuilder#parse(java.io.Reader) |
| */ |
| public ValueExp parse(Reader in) throws IOException, ParseException |
| { |
| DebuggerExpression retval = new DebuggerExpression(); |
| |
| StringBuilder sb = new StringBuilder(); |
| int ch; |
| while ( (ch=in.read()) != -1 ) |
| sb.append((char)ch); |
| |
| String s = sb.toString(); |
| |
| // FB-16879: If expression begins with "#N" where N is a number, |
| // replace that with "$obj(N)". For example, "#3" would become |
| // "$obj(3)". Later, in PlayerSession.callFunction(), we will |
| // detect the $obj() function and handle it. |
| s = s.replaceFirst("^#([0-9]+)", "\\$obj($1)"); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| if (isIndirectionOperatorAllowed()) { |
| if (s.endsWith(".")) { //$NON-NLS-1$ |
| retval.setLookupMembers(true); |
| s = s.substring(0, s.length() - 1); |
| } else if (s.startsWith("*")) { //$NON-NLS-1$ |
| retval.setLookupMembers(true); |
| s = s.substring(1); |
| } |
| } |
| |
| // Enclose the expression in parentheses, in order to ensure that the |
| // parser considers it to be an expression. For example, "{x:3}" would |
| // be considered to be a block with label "x" and value "3", but, |
| // "({x:3})" is considered to be an inline object with field "x" that |
| // has value 3. |
| s = "(" + s + ")"; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| final List<ICompilerProblem> errors = new ArrayList<ICompilerProblem>(); |
| // CompilerHandler newHandler = new CompilerHandler() { |
| // @Override |
| // public void error(final String filename, int ln, int col, String msg, String source) { |
| // ErrorInfo ei = new ErrorInfo(); |
| // ei.filename = filename; |
| // ei.ln = ln; |
| // ei.col = col; |
| // ei.msg = msg; |
| // ei.source = source; |
| // errors.add(ei); |
| // } |
| // }; |
| // cx.setHandler(newHandler); |
| // cx.scriptAssistParsing = true; |
| // Parser parser = new Parser(cx, s, "Expression"); //$NON-NLS-1$ |
| IASNode programNode = DebuggerUtil.parseExpression(s, errors); |
| //ProgramNode programNode = parser.parseProgram(); |
| |
| if (errors.size() > 0) { |
| ICompilerProblem firstError = errors.get(0); |
| throw new ParseException(firstError.toString(), firstError.getColumn()); |
| } |
| |
| retval.setProgramNode(programNode); |
| return retval; |
| } |
| |
| |
| static LocalizationManager getLocalizationManager() |
| { |
| return s_localizationManager; |
| } |
| } |