blob: c1e7830f3ad7e8ffc5db40f6da29dffeaecb42d1 [file] [log] [blame]
/*
*
* 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.
*
*/
/**
* cmc-js.jbg mirrors cmc.jbg and contains FalconJS's definitions for JBurg.
*
* After making changes to cmc-js.jbg or JSCmcRules.jbg you need to run this command
* in the ./compiler/trunk folder:
*
* ant -f build-js.xml
*
* This implementation is part of FalconJS.
* For more details on FalconJS see org.apache.flex.compiler.JSDriver.
*
*/
package org.apache.flex.compiler.internal.as.codegen;
header
{
import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.problems.*;
import static org.apache.flex.abc.ABCConstants.*;
import org.apache.flex.abc.semantics.Label;
import org.apache.flex.abc.semantics.Name;
import org.apache.flex.abc.semantics.Namespace;
import org.apache.flex.abc.instructionlist.InstructionList;
import org.apache.flex.compiler.constants.IASLanguageConstants;
import org.apache.flex.compiler.tree.ASTNodeID;
import static org.apache.flex.compiler.tree.ASTNodeID.*;
import org.apache.flex.compiler.internal.semantics.SemanticUtils;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.ITryNode;
import org.apache.flex.abc.semantics.ECMASupport;
}
INodeType IASNode;
OpcodeType ASTNodeID;
/*
* The I-node type is IASNode, and it has its own adapter.
*/
INodeAdapter org.apache.flex.compiler.internal.as.codegen.IASNodeAdapter;
// Generate Java output.
Language java;
ReturnType String;
ReturnType InstructionList = String;
ReturnType name = Binding;
ReturnType type_name = Binding;
ReturnType decl_name = Name;
ReturnType new_type_name = Binding;
ReturnType qualifiedName = Binding;
ReturnType qualifiedNamePart = String;
ReturnType return_type_name = Binding;
ReturnType dottedNamePart = String;
ReturnType conditionalElements = JSGeneratingReducer.ConditionalFragment;
ReturnType ifElseIf = JSGeneratingReducer.ConditionalFragment;
ReturnType catch_block = JSGeneratingReducer.CatchPrototype;
ReturnType integer_constant = Integer;
ReturnType uint_constant = Long;
ReturnType double_constant = Double;
ReturnType string_constant = String;
ReturnType boolean_constant = Boolean;
ReturnType float_constant = Float;
ReturnType numeric_constant = Number;
ReturnType constant_value = Object;
ReturnType required_constant_value = Object;
ReturnType non_resolving_identifier = String;
ReturnType runtime_name_expression = JSGeneratingReducer.RuntimeMultiname;
ReturnType multinameL = Name;
ReturnType stmt_label = String;
ReturnType e4x_literal = String;
JBurg.Constant ERROR_TRAP = 268435456;
{
final static boolean NEED_VALUE = true;
final static boolean DISCARD_VALUE = false;
/**
* The reducer has all the implementation
* logic for the rewrite; the BURM constructed
* by this specification drives that logic.
*/
JSGeneratingReducer reducer;
/**
* Delegate calls to pushNumericConstant to the reducer.
* This routine is called from other parts of the code generator,
* so it's necessary to keep this layer of indirection.
*/
public static void pushNumericConstant(long value, String result_list)
{
JSGeneratingReducer.pushNumericConstant(value, result_list);
}
/*
* ** Cost functions **
*/
/**
* @return "feasible" if the reducer can reduce this to a dotted name.
*/
int isDottedName(IASNode iNode)
{
return reducer.isDottedName(iNode);
}
/**
* @return "feasible" if the reducer can reduce this to a dotted name.
*/
int isPackageName(IASNode iNode)
{
return reducer.isPackageName(iNode);
}
/**
* @return "feasible" if this node's qualifier is a compile-time constant.
*/
int qualifierIsCompileTimeConstant(IASNode iNode)
{
return reducer.qualifierIsCompileTimeConstant(iNode);
}
/**
/**
* @return "feasible" if this node's qualifier is an interface.
*/
int qualifierIsInterface(IASNode iNode)
{
return reducer.qualifierIsInterface(iNode);
}
/**
* @return "feasible" if this node can be resolved to a compile-time constant.
*/
int isCompileTimeConstant(IASNode iNode)
{
return reducer.isCompileTimeConstant(iNode);
}
/**
* @return "feasible" if this function call node can be resolved to a compile-time constant function.
*/
int isCompileTimeConstantFunction(IASNode iNode)
{
return reducer.isCompileTimeConstantFunction(iNode);
}
/**
* @return "feasible" if this node is for 'new Array()'.
*/
int isEmptyArrayConstructor(IASNode iNode)
{
return reducer.isEmptyArrayConstructor(iNode);
}
/**
* @return "feasible" if this node is for 'new Object()'.
*/
int isEmptyObjectConstructor(IASNode iNode)
{
return reducer.isEmptyObjectConstructor(iNode);
}
/**
* @return "feasible" if this node is "super(this)".
*/
int isSuperThisForFieldAccess(IASNode iNode)
{
return SemanticUtils.isSuperThisForFieldAccess(iNode);
}
/**
* @return "feasible" if the base and parameter types of
* a parameterized type are both known types.
*/
int parameterTypeIsConstant(IASNode iNode)
{
return reducer.parameterTypeIsConstant(iNode);
}
/**
* @return "feasible" if a standalone "super" expression is in a parameter list.
*/
int isValidStandaloneSuper(IASNode iNode)
{
return /* SemanticUtils.isValidStandaloneSuper(iNode)? 1: */ Integer.MAX_VALUE;
}
/**
* @return "feasible" if this node resolves to a type definition.
*/
int isKnownType(IASNode iNode)
{
return reducer.isKnownType(iNode);
}
/*
* ******************************
* ** IASNodeAdapter Support **
* ******************************
*/
/**
* Get the default child of a node type that requires special handling.
* @param parent - the child's parent node.
* @param index - the desired child.
* @return the child at the specified (abstract) index, or null
* if no such child exists.
*/
public static IASNode getDefaultChild(IASNode parent, int index)
{
switch(parent.getNodeID())
{
case VariableID:
case BindableVariableID:
{
// Look for chained variable definitions.
IASNode candidate = parent.getChild(index);
if ( candidate != null )
{
ASTNodeID candidateID = candidate.getNodeID();
if( candidateID == VariableID || candidateID == BindableVariableID )
{
return candidate;
}
}
return null;
}
case Op_CommaID:
return parent.getChild(index-1);
case FunctionID:
case GetterID:
case SetterID:
return null;
case TryID:
{
// Note: If the try has a contents and finally nodes,
// they are presented to the CG by getNthChild() as child
// nodes 0 and 1 before the n-ary tail of catch nodes.
if (((ITryNode)parent).getStatementContentsNode() != null)
index--;
if (((ITryNode)parent).getFinallyNode() != null)
index--;
return ((ITryNode)parent).getCatchNode(index);
}
default:
return parent.getChild(index);
}
}
/**
* recordError is a convenience method for error reductions;
* it adds a problem to the current set of problems and
* returns an empty String.
* @return an empty String.
*/
String recordError(ICompilerProblem problem)
{
reducer.getProblems().add(problem);
return "";
}
}
/*
* Error recovery routine: deduce what we can from the problem
* tree, then abort this BURM with an exception that the caller
* can catch and ignore.
*/
/*
bparadie, 2011-12-01: Tom recommends not using DefaultErrorHandler at all.
DefaultErrorHandler
{
new UnknownTreeHandler(reducer.getProblems()).analyze(p);
throw new BURMAbortException();
}
*/
/*
* Patterns and rules are stored in their own, shareable file.
*/
JBurg.include "../../../../../../../../../compiler/src/org/apache/flex/compiler/internal/as/codegen/CmcPatterns.jbg"
JBurg.include "../../../../../../../../../compiler/src/org/apache/flex/compiler/internal/as/codegen/CmcRules.jbg"
JBurg.include "../../../../../../../../../compiler/src/org/apache/flex/compiler/internal/as/codegen/SemanticErrors.jbg"