You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2016/04/13 20:55:58 UTC
[06/51] [partial] git commit: [flex-falcon]
[refs/heads/feature/maven-migration-test] - - Check-In of the migrated
project to make error analysis easier
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGenerator.java
----------------------------------------------------------------------
diff --git a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGenerator.java b/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGenerator.java
deleted file mode 100644
index 154a70c..0000000
--- a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGenerator.java
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- *
- * 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 org.apache.flex.compiler.internal.as.codegen;
-
-import static org.apache.flex.abc.ABCConstants.OP_add;
-import static org.apache.flex.abc.ABCConstants.OP_getlocal0;
-import static org.apache.flex.abc.ABCConstants.OP_pushscope;
-import static org.apache.flex.abc.ABCConstants.OP_returnvalue;
-import static org.apache.flex.abc.ABCConstants.OP_returnvoid;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-import org.apache.flex.abc.ABCConstants;
-import org.apache.flex.abc.instructionlist.InstructionList;
-import org.apache.flex.abc.semantics.MethodBodyInfo;
-import org.apache.flex.abc.semantics.MethodInfo;
-import org.apache.flex.abc.semantics.Name;
-import org.apache.flex.abc.visitors.IMethodBodyVisitor;
-import org.apache.flex.abc.visitors.IMethodVisitor;
-import org.apache.flex.abc.visitors.IScriptVisitor;
-import org.apache.flex.abc.visitors.IVisitor;
-import org.apache.flex.compiler.definitions.references.IReference;
-import org.apache.flex.compiler.exceptions.BURMAbortException;
-import org.apache.flex.compiler.exceptions.CodegenInterruptedException;
-import org.apache.flex.compiler.exceptions.MissingBuiltinException;
-import org.apache.flex.compiler.internal.as.codegen.ICodeGenerator.IConstantValue;
-import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
-import org.apache.flex.compiler.internal.definitions.ParameterDefinition;
-import org.apache.flex.compiler.internal.definitions.TypeDefinitionBase;
-import org.apache.flex.compiler.internal.embedding.EmbedData;
-import org.apache.flex.compiler.internal.scopes.ASScope;
-import org.apache.flex.compiler.internal.testing.NodesToXMLStringFormatter;
-import org.apache.flex.compiler.internal.tree.as.FunctionNode;
-import org.apache.flex.compiler.internal.tree.mxml.MXMLFileNode;
-import org.apache.flex.compiler.internal.units.requests.ABCBytesRequestResult;
-import org.apache.flex.compiler.problems.CodegenInternalProblem;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-import org.apache.flex.compiler.problems.MissingBuiltinProblem;
-import org.apache.flex.compiler.projects.ICompilerProject;
-import org.apache.flex.compiler.tree.as.IASNode;
-import org.apache.flex.compiler.tree.as.IExpressionNode;
-import org.apache.flex.compiler.units.ICompilationUnit;
-import org.apache.flex.compiler.units.ICompilationUnit.Operation;
-import org.apache.flex.compiler.units.requests.IABCBytesRequestResult;
-
-import com.google.common.util.concurrent.Futures;
-
-/**
- * ABCGenerator is the public interface to the code generator.
- */
-
-/**
- * JSGenerator is modeled after from ABCGenerator and called by
- * JSCompilationUnit. JSGenerator owns the JSSharedData singleton. Ideally
- * JSGenerator and ABCGenerator should be derived from the same base class, i.e.
- * Generator. Some of the code in JSGenerator and ABCGenerator could be shared
- * if Generator used a burm factory in generateInstructions(). ABCGenerator
- * creates and uses a CmcEmitter, while JSGenerator uses a CmcJSEmitter. This
- * implementation is part of FalconJS. For more details on FalconJS see
- * org.apache.flex.compiler.JSDriver
- */
-public class JSGenerator implements ICodeGenerator
-{
- public ICompilationUnit m_compilationUnit = null;
- private Boolean m_needsSecondPass = false;
- private CmcJSEmitter m_cmcJSEmitter = null;
- private JSGeneratingReducer m_burm = null;
- private ICompilationUnit.Operation m_buildPhase = Operation.GET_ABC_BYTES;
- private JSEmitter m_emitter = null;
-
- public JSGenerator()
- {
- m_cmcJSEmitter = JSSharedData.backend.createCmcJSEmitter();
- m_cmcJSEmitter.reducer = JSSharedData.backend.createReducer();
- m_burm = m_cmcJSEmitter.reducer;
- }
-
- // If JSEmitter.needsSecondPass() returns true, JSGenerator.generate() will return null during scanning,
- // which will result in JSCompilationUnit::handleSemanticProblemsRequest not caching any abcBytes for
- // handleABCBytesRequest. The net result is that JSGenerator.generate() will be called again in handleABCBytesRequest.
- // This mechanic will ensure selective two-pass compilation.
- public Boolean needsSecondPass()
- {
- return m_needsSecondPass;
- }
-
- /*
- * There are currently a lot of problems with the DependencyGraph: -
- * ImportNode::resolveRefs() has not been implemented. - import and
- * expression dependencies are not being recognized. If
- * useOwnDependencyGraph() returns true we use our own (old) DependencyGraph
- * implementation that used to drive the while loop in
- * JSGenerator.generate() using nextJS. - JSDriver does a second pass -
- * JSGlobalDirectiveProcessor::processImportDirective() registers imported
- * classes.
- */
- public static Boolean useOwnDependencyGraph()
- {
- // return true;
- return false;
- }
-
- /**
- * Generate an ABC file equivalent to the input syntax tree.
- *
- * @param synthetic_name_prefix Prefix to prepend to all synthetic names
- * @param root_node the root of the syntax tree.
- * @param project {@link ICompilerProject} whose symbol table is used to
- * resolve references to definitions.
- * @throws InterruptedException
- */
- @SuppressWarnings("nls")
- public ABCBytesRequestResult generate(String synthetic_name_prefix, IASNode root_node, ICompilerProject project) throws InterruptedException
- {
- return generate(null, false, synthetic_name_prefix, root_node, project, false, Collections.<String, String>emptyMap());
- }
-
- @Override
- public ABCBytesRequestResult generate(ExecutorService executorService, boolean useParallelCodegen,
- String synthetic_name_prefix, IASNode root_node,
- ICompilerProject project, boolean inInvisibleCompilationUnit,
- Map<String, String> encodedDebugFiles)
- throws InterruptedException
- {
- m_needsSecondPass = false;
- if (root_node instanceof MXMLFileNode)
- m_emitter = new JSMXMLEmitter(JSSharedData.instance, m_buildPhase, project, this);
- else
- m_emitter = JSSharedData.backend.createEmitter(m_buildPhase, project, this);
- m_emitter.visit(ABCConstants.VERSION_ABC_MAJOR_FP10, ABCConstants.VERSION_ABC_MINOR_FP10);
-
- IScriptVisitor sv = m_emitter.visitScript();
- sv.visit();
- MethodInfo init_method = new MethodInfo();
- sv.visitInit(init_method);
-
- MethodBodyInfo init_body = new MethodBodyInfo();
- init_body.setMethodInfo(init_method);
-
- IMethodVisitor mv = m_emitter.visitMethod(init_method);
- IMethodBodyVisitor mbv = mv.visitBody(init_body);
- mbv.visit();
-
- // Set up the global lexical scope.
- final LexicalScope global_scope = new GlobalLexicalScope(project, this, synthetic_name_prefix, m_emitter);
- global_scope.traitsVisitor = sv.visitTraits();
- global_scope.setMethodInfo(init_method);
- global_scope.methodBodyVisitor = mbv;
-
- // Process global directives.
- GlobalDirectiveProcessor top_level_processor = JSSharedData.backend.createGlobalDirectiveProcessor(this, global_scope, m_emitter);
- boolean fatal_error_encountered = false;
- try
- {
- top_level_processor.traverse(root_node);
- }
- catch (MissingBuiltinException e)
- {
- global_scope.addProblem(new MissingBuiltinProblem(root_node, e.getBuiltinName()));
- fatal_error_encountered = true;
- }
- catch (CodegenInterruptedException e)
- {
- // Unwrap the InterruptedException and rethrow it.
- throw e.getException();
- }
-
- byte[] generatedBytes = IABCBytesRequestResult.ZEROBYTES;
-
- if (!fatal_error_encountered)
- {
- // Initialize the init script.
- InstructionList script_init_insns = new InstructionList();
-
- script_init_insns.addInstruction(OP_getlocal0);
- script_init_insns.addInstruction(OP_pushscope);
-
- script_init_insns.addAll(global_scope.getInitInstructions());
- script_init_insns.addAll(top_level_processor.directiveInsns);
-
- if (script_init_insns.canFallThrough() || script_init_insns.hasPendingLabels())
- script_init_insns.addInstruction(OP_returnvoid);
-
- // Allocate temps beginning with register 1,
- // register 0 is reserved for "this" global.
- global_scope.initializeTempRegisters(1);
-
- mbv.visitInstructionList(script_init_insns);
- mbv.visitEnd();
- mv.visitEnd();
- sv.visitEnd();
-
- try
- {
- generatedBytes = m_emitter.emit();
- }
- catch (Throwable cant_generate)
- {
- global_scope.addProblem(new CodegenInternalProblem(root_node, cant_generate));
- }
- }
-
- ICompilerProblem[] problemsArray = global_scope.getProblems().toArray(IABCBytesRequestResult.ZEROPROBLEMS);
- return new ABCBytesRequestResult(generatedBytes, problemsArray, Collections.<EmbedData> emptySet());
- }
-
- /**
- * Translate an AST into ABC instructions.
- *
- * @param subtree - the CM subtree.
- * @param goal_state - the desired goal state. One of the nonterminal states
- * in CmcJSEmitter, or 0 if you're feeling lucky and are willing to accept
- * whatever instruction sequence the BURM decides is optimal.
- * @param scope - the active lexical scope.
- * @return a list of ABC instructions.
- */
- public InstructionList generateInstructions(IASNode subtree, int goal_state, LexicalScope scope)
- {
- return generateInstructions(subtree, goal_state, scope, null);
- }
-
- /**
- * Translate an AST into ABC instructions.
- *
- * @param subtree - the CM subtree.
- * @param goal_state - the desired goal state. One of the nonterminal states
- * in CmcJSEmitter, or 0 if you're feeling lucky and are willing to accept
- * whatever instruction sequence the BURM decides is optimal.
- * @param scope - the active lexical scope.
- * @param instance_init_insns - a list of instance initialization
- * instructions collected outside a constructor body that must be included
- * in the constructor.
- * @post if instance_init_insns is not null then the method will have been
- * processed as and marked as a constructor.
- * @return a list of ABC instructions.
- */
- public InstructionList generateInstructions(IASNode subtree, int goal_state, LexicalScope scope, InstructionList instance_init_insns)
- {
- m_burm.setCurrentscope(scope);
- m_burm.setInstanceInitializers(instance_init_insns);
- m_burm.setAprioriinstructions(instance_init_insns);
- m_burm.setFunctionNode(subtree);
-
- InstructionList list = new InstructionList();
-
- try
- {
- m_cmcJSEmitter.burm(subtree, goal_state);
-
- // TODO: cmcJSEmitter.getResult() now returns a String, which needs to be wrapped into an InstructionList
- // return ((InstructionList)cmcJSEmitter.getResult());
- list.addInstruction(JSSharedData.OP_JS, m_cmcJSEmitter.getResult());
-
- // If JSEmitter.needsSecondPass() returns true, JSGenerator.generate() will return null during scanning,
- // which will result in JSCompilationUnit::handleSemanticProblemsRequest not caching any abcBytes for
- // handleABCBytesRequest. The net result is that JSGenerator.generate() will be called again in handleABCBytesRequest.
- // This mechanic will ensure selective two-pass compilation.
- if (m_burm.needsSecondPass())
- {
- m_needsSecondPass = true;
- }
- }
- catch (Exception cant_reduce)
- {
- handleBurmError(m_cmcJSEmitter, subtree, cant_reduce, scope);
- }
-
- return list;
- }
-
- /**
- * Generate code for a function declaration, and put its initialization code
- * on the relevant instruction list.
- *
- * @param func - the function declaration node.
- * @param enclosing_scope - the lexical scope in which the function was
- * defined.
- * @param a_priori_insns - instructions generated by an enclosing subsystem
- * that should be included in the function (e.g., a constructor needs a
- * priori instructions to initialize instance vars).
- */
- public MethodInfo generateFunction(FunctionNode func, LexicalScope enclosing_scope, InstructionList a_priori_insns)
- {
- m_burm.setCurrentscope(enclosing_scope);
- MethodInfo mi = createMethodInfo(m_burm, m_emitter, enclosing_scope, func);
- if (mi.isNative())
- {
- generateNativeMethod(func, mi, enclosing_scope);
- }
- else
- {
- /*
- * Now done in JSEmitter: // support for class inits. // If this is
- * a static function and the owner class has a class init then call
- * __static_init() final IDefinition fdef = func.getDefinition();
- * if( fdef.isStatic() && fdef.getParent() != null &&
- * fdef.getParent() instanceof ClassDefinition ) { final IDefinition
- * cdef = fdef.getParent(); final String fullName =
- * JSGeneratingReducer
- * .createFullNameFromDefinition(enclosing_scope.getProject(),cdef);
- * if( JSSharedData.instance.hasClassInit(fullName) ) { final String
- * callInit = fullName + "." + JSSharedData.STATIC_INIT + "();\n";
- * if( a_priori_insns == null ) a_priori_insns = new
- * InstructionList(); a_priori_insns.addInstruction(
- * JSSharedData.OP_JS, callInit ); } }
- */
- m_burm.startFunction(func);
- generateMethodBodyForFunction(mi, func, enclosing_scope, a_priori_insns);
- m_burm.endFunction(func);
- }
-
- return mi;
- }
-
- public GenerateFunctionInParallelResult generateFunctionInParallel (ExecutorService executorService, FunctionNode func, LexicalScope enclosing_scope)
- {
- /** AJH commented out for now
- MethodInfo mi = createMethodInfo(enclosing_scope, func);
- if (mi.isNative())
- {
- generateNativeMethod(func, mi, enclosing_scope);
- return new GenerateFunctionInParallelResult(Futures.immediateFuture(null), mi, Collections.<IVisitor>emptyList());
- }
- GenerateFunctionRunnable runnable = new GenerateFunctionRunnable(mi, func, enclosing_scope);
- Future<?> future = executorService.submit(runnable);
- return new GenerateFunctionInParallelResult(future, mi, runnable.getDeferredVisitEndsList());
- */
- System.out.println("unhandled call to generateFunctionInParallel");
- return null;
- }
-
- /**
- * Helper method used by <code>generateFunction()</code>.
- *
- * @param func - the function declaration node.
- * @param mi - the MethodInfo describing the signature
- * @param enclosing_scope - the lexical scope in which the handler method is
- * autogenerated.
- */
- static void generateNativeMethod(FunctionNode func, MethodInfo mi,
- LexicalScope enclosing_scope)
- {
- enclosing_scope.getMethodBodySemanticChecker().checkNativeMethod(func);
-
- // don't need to create a new scope, so just use the enclosing scope
- // to get a handle to the emitter
- IMethodVisitor mv = enclosing_scope.getEmitter().visitMethod(mi);
-
- // Just visit the method info. Do NOT generate a body
- // for native methods
- mv.visit();
-
- // func.getReturnType() returns a short name string.
- // But we need a real name. ctors don't have return types.
- if (!func.isConstructor())
- {
- final ASScope scope = (ASScope)JSGeneratingReducer.getScopeFromNode(func);
- final FunctionDefinition fdef = func.getDefinition();
- final IReference ref = fdef.getReturnTypeReference();
- final Name returnTypeName = ref.getMName(enclosing_scope.getProject(), scope);
- mi.setReturnType(returnTypeName);
- }
-
- // For non native methods, the return type is set by the burm,
- // but for native types, as the burm isn't run, we need to set
- // the return type here.
- // String returnType = func.getReturnType();
- // mi.setReturnType(new Name(returnType));
-
- mv.visitEnd();
- }
-
- /**
- * Helper method used by <code>generateFunction()</code> (and also by
- * <code>generateEventHandler()</code> in MXMLDocumentDirectiveProcessor).
- *
- * @param mi - the MethodInfo describing the signature
- * @param node - the FunctionNode or MXMLEventSpecifierNode. may be null
- * when generating method bodies for purely synthetic functions, such as
- * theIEventDispatcher methods that [Bindable] introduces.
- * @param enclosing_scope - the lexical scope in which the handler method is
- * autogenerated.
- * @param a_priori_insns - instructions generated by an enclosing subsystem
- * that should be included in the function (e.g., a constructor needs a
- * priori instructions to initialize instance vars).
- */
- public void generateMethodBodyForFunction(MethodInfo mi, IASNode node,
- LexicalScope enclosing_scope,
- InstructionList a_priori_insns)
- {
- generateMethodBody(mi, node, enclosing_scope, a_priori_insns, CmcEmitter.__function_NT, null);
- }
-
- /**
- * Helper methods used by databinding codegen to emit anonymous functions
- * based on an expression node.
- *
- * @param mi - the MethodInfo describing the signature
- * @param node - the expression node whose code will start the function. may
- * be null when generating method bodies for purely synthetic functions,
- * such as theIEventDispatcher methods that [Bindable] introduces.
- * @param enclosing_scope
- * @param insns_to_append - typically some massaging of the TOS and a return
- * function
- */
- public MethodInfo generateFunctionFromExpression(MethodInfo mi, IASNode node,
- LexicalScope enclosing_scope,
- InstructionList insns_to_append)
- {
- return generateMethodBody(mi, node, enclosing_scope, null, CmcEmitter.__expression_NT, insns_to_append);
- }
-
- /**
- * Helper methods used by databinding codegen to emit anonymous functions
- * based on an expression node.
- *
- * @param mi - the MethodInfo describing the signature
- * @param nodes - a list of expression nodes whose code will start the
- * function. May have the following values: null when generating method
- * bodies for purely synthetic functions, such as theIEventDispatcher
- * methods that [Bindable] introduces. an IASNode for an expression that
- * will be code-gen'd a List of IASNodes. This is a special case where we
- * code-gen the sum of all the expressions
- * @param enclosing_scope
- * @param insns_to_append - typically some massaging of the TOS and a return
- * function
- */
-
- public MethodInfo generateFunctionFromExpressions(MethodInfo mi, List<? extends IASNode> nodes,
- LexicalScope enclosing_scope,
- InstructionList insns_to_append)
- {
- return generateMethodBody(mi, nodes, enclosing_scope, null, CmcEmitter.__expression_NT, insns_to_append);
- }
-
- /**
- * General method body maker. see the public documentation, above, for more
- * into
- */
- MethodInfo generateMethodBody(MethodInfo mi, Object node,
- LexicalScope enclosing_scope,
- InstructionList a_priori_insns,
- int goal_state,
- InstructionList insns_to_append)
- {
- // Set up a lexical scope for this function.
- LexicalScope function_scope = enclosing_scope.pushFrame();
-
- IMethodVisitor mv = function_scope.getEmitter().visitMethod(mi);
- mv.visit();
-
- MethodBodyInfo mbi = new MethodBodyInfo();
- mbi.setMethodInfo(mi);
-
- IMethodBodyVisitor mbv = mv.visitBody(mbi);
- mbv.visit();
-
- function_scope.methodBodyVisitor = mbv;
- function_scope.traitsVisitor = mbv.visitTraits();
- function_scope.setMethodInfo(mi);
-
- System.out.println(mi.getMethodName());
- if (mi.getMethodName().contains("loginInternal"))
- {
- System.out.println("got it");
- }
-
- InstructionList insns = null;
- if (node == null)
- {
- // node may be null when generating method bodies for purely synthetic functions, such as the
- // IEventDispatcher methods that [Bindable] introduces.
- insns = new InstructionList();
- }
- else if (node instanceof IASNode)
- {
- // If we are passed a single node, generate its instructions
- insns = generateInstructions((IASNode)node, goal_state, function_scope, a_priori_insns);
- }
- else if (node instanceof List<?>)
- {
- List<?> nodes = (List<?>)node;
-
- // for a list of nodes, generate all their instructions and add the results together.
- // typically we are doing this to concatenate strings
- for (int nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex)
- {
- IASNode n = (IASNode)nodes.get(nodeIndex);
- if (nodeIndex == 0)
- {
- // First one in the list makes a new IL and puts
- // instructions into it
- insns = generateInstructions(n, goal_state, function_scope, a_priori_insns);
- }
- else
- {
- // successive children generate into the same IS, then add the results
- insns.addAll(generateInstructions(n, goal_state, function_scope, a_priori_insns));
- insns.addInstruction(OP_add);
- }
- }
- }
- else
- {
- assert false; // Illegal type passed as node parameter
- }
- assert insns != null;
-
- // If caller passed in instructions to get after the BURM-generated stuff,
- // add them to the instruction stream
- if (insns_to_append != null)
- {
- insns.addAll(insns_to_append);
- }
-
- mbv.visitInstructionList(insns);
-
- if (function_scope.needsActivation())
- {
- mi.setFlags((byte)(mi.getFlags() | ABCConstants.NEED_ACTIVATION));
- }
-
- mbv.visitEnd();
- mv.visitEnd();
-
- return mi;
- }
-
- /**
- * Helper method used by mxml databinding codegen to emit an anonymous
- * function used by an mxml data binding destination function. Example:
- * <p>
- * If the expression node is a.b.c, this method will generate a funtion
- * whose source would look something like this:
- *
- * <pre>
- * function (arg:*):void { a.b.c = arg; }
- * </pre>
- *
- * @param mi - the MethodInfo describing the signature
- * @param setterExpression {@link IExpressionNode} that is the destination
- * expression of a mxml data binding.
- * @param enclosing_scope {@link LexicalScope} for the class initializer
- * that encloses the function being generated.
- */
- public void generateMXMLDataBindingSetterFunction (MethodInfo mi, IExpressionNode setterExpression, LexicalScope enclosing_scope)
- {
- System.out.println("unhandled call to generateMXMLDataBindingSetterFunction");
- /* AJH commented out for now
- IMethodVisitor methodVisitor = enclosing_scope.getEmitter().visitMethod(mi);
- methodVisitor.visit();
- MethodBodyInfo methodBodyInfo = new MethodBodyInfo();
- methodBodyInfo.setMethodInfo(mi);
- IMethodBodyVisitor methodBodyVisitor = methodVisitor.visitBody(methodBodyInfo);
- methodBodyVisitor.visit();
-
- // Set up a lexical scope for this function.
- LexicalScope function_scope = enclosing_scope.pushFrame();
-
- function_scope.methodBodyVisitor = methodBodyVisitor;
- function_scope.traitsVisitor = methodBodyVisitor.visitTraits();
- function_scope.setMethodInfo(mi);
-
-
- InstructionList functionBody;
- if (setterExpression instanceof InstructionListNode)
- functionBody = ((InstructionListNode)setterExpression).getInstructions();
- else
- functionBody = generateInstructions(setterExpression, CmcEmitter.__mxml_data_binding_setter_expression_NT, function_scope, null);
-
- functionBody.addInstruction(OP_returnvoid);
-
- methodBodyVisitor.visitInstructionList(functionBody);
- methodBodyVisitor.visitEnd();
- methodVisitor.visitEnd();
- */
- }
-
- /**
- * Helper method used by databinding codegen to emit an anonymous function
- * based on a list of {@link IExpressionNode}'s. This method emits a
- * function that contains code that evaluates each expression in the list
- * and adds the expressions together with {@link ABCConstants#OP_add}.
- *
- * @param mi - the MethodInfo describing the signature
- * @param nodes - a {@link List} of {@link IExpressionNode}'s to be
- * codegen'd.
- * @param enclosing_scope {@link LexicalScope} for the class initializer
- * that encloses the function being generated.
- */
- public void generateMXMLDataBindingGetterFunction (MethodInfo mi, List<IExpressionNode> nodes,
- LexicalScope enclosing_scope)
- {
- System.out.println("unhandled call to generateMXMLDataBindingSetterFunction");
- /* AJH commented out for now
- IMethodVisitor methodVisitor = enclosing_scope.getEmitter().visitMethod(mi);
- methodVisitor.visit();
- MethodBodyInfo methodBodyInfo = new MethodBodyInfo();
- methodBodyInfo.setMethodInfo(mi);
- IMethodBodyVisitor methodBodyVisitor = methodVisitor.visitBody(methodBodyInfo);
- methodBodyVisitor.visit();
-
- // Set up a lexical scope for this function.
- LexicalScope function_scope = enclosing_scope.pushFrame();
-
- function_scope.methodBodyVisitor = methodBodyVisitor;
- function_scope.traitsVisitor = methodBodyVisitor.visitTraits();
- function_scope.setMethodInfo(mi);
-
- InstructionList functionBody = null;
- // for a list of nodes, generate all their instructions and add the results together.
- // typically we are doing this to concatenate strings
- for (IExpressionNode expressionNode : nodes)
- {
- InstructionList instructionsForExpression = generateInstructions(expressionNode, CmcEmitter.__expression_NT, function_scope, null);
- if (functionBody == null)
- {
- // First one in the list makes a new IL and puts
- // instructions into it
- functionBody = instructionsForExpression;
- }
- else
- {
- // successive children generate into the same IL, then add the results
- functionBody.addAll(instructionsForExpression);
- functionBody.addInstruction(OP_add);
- }
- }
-
- functionBody.addInstruction(OP_returnvalue);
-
- methodBodyVisitor.visitInstructionList(functionBody);
- function_scope.traitsVisitor.visitEnd();
- methodBodyVisitor.visitEnd();
- methodVisitor.visitEnd();
- */
- }
-
- /**
- * Creates a MethodInfo specifying the signature of a method declared by a
- * FunctionNode.
- *
- * @param func - A FunctionNode representing a method declaration.
- * @return The MethodInfo specifying the signature of the method.
- */
- public static MethodInfo createMethodInfo(JSGeneratingReducer burm, JSEmitter emitter, LexicalScope scope, FunctionNode func)
- {
- MethodInfo mi = new MethodInfo();
- // FIXME: FunctionNode.getQualifiedName() has
- // preconditions that need to be understood!
- mi.setMethodName(func.getName());
-
- FunctionDefinition funcDef = func.getDefinition();
- // Marshal the function's arguments.
- ParameterDefinition[] args = funcDef.getParameters();
- List<String> param_names = new ArrayList<String>();
-
- ICompilerProject project = scope.getProject();
- if (args.length > 0)
- {
- Vector<Name> method_args = new Vector<Name>();
- for (ParameterDefinition arg : args)
- {
- TypeDefinitionBase arg_type = arg.resolveType(project);
- Name type_name = arg_type != null ? arg_type.getMName(project) : null;
-
- if (arg.isRest())
- {
- mi.setFlags((byte)(mi.getFlags() | ABCConstants.NEED_REST));
- param_names.add(arg.getBaseName());
- }
- else
- {
- method_args.add(type_name);
- param_names.add(arg.getBaseName());
- }
- }
- mi.setParamTypes(method_args);
- mi.setParamNames(param_names);
- }
-
- // check for native modifier
- if (func.getDefinition().isNative())
- {
- mi.setFlags((byte)(mi.getFlags() | ABCConstants.NATIVE));
- }
-
- // The return type will be set by the BURM.
-
- // Falcon's IMethodVisitor only records a fraction of the FunctionDefinition.
- // For that reason we are registering every MethodInfo with its corresponding FunctionDefinition at the JSEmitter.
- emitter.visitFunctionDefinition(mi, funcDef);
-
- return mi;
- }
-
- // called by JSInterfaceDirectiveProcessor
- public MethodInfo createMethodInfo(LexicalScope scope, FunctionNode func)
- {
- return JSGenerator.createMethodInfo(m_burm, m_emitter, scope, func);
- }
-
- /**
- **
- * Creates a MethodInfo specifying the signature of a method
- * declared by a FunctionNode, and adds in the information for any
- * default argument values.
- *
- * @param func - A FunctionNode representing a method declaration.
- * @return The MethodInfo specifying the signature of the method.
- *
- * Will generate a compiler problem is the default value is bad
- */
- @Override
- public MethodInfo createMethodInfoWithDefaultArgumentValues (LexicalScope scope, FunctionNode func)
- {
- return JSGenerator.createMethodInfo(m_burm, m_emitter, scope, func);
- }
-
- /**
- * Helper method to expose the constant folding code to clients outside of
- * the burm, such as
- * org.apache.flex.compiler.internal.as.definitions.ConstantDefinition.
- *
- * @param subtree the tree to generate a constant value for
- * @param project the project to use to evaluate the tree
- * @return the constant value for the subtree, or null if a constant value
- * can't be determined
- */
- public IConstantValue generateConstantValue(IASNode subtree, ICompilerProject project)
- {
- Object result = null;
-
- LexicalScope scope = new GlobalLexicalScope(project, null, GlobalLexicalScope.EMPTY_NAME_PREFIX, m_emitter);
-
- if (subtree != null)
- {
- try
- {
- result = reduceSubtree(subtree, scope, CmcJSEmitter.__constant_value_NT);
- }
- catch (Exception cant_reduce)
- {
- // Can't generate a constant value, just return null
- }
- }
-
- return new ConstantValue(result, null);
- }
-
- /**
- * Reduce an AST to its equivalent ABC structures.
- *
- * @param subtree - the root of the AST subtree. May be null, in which case
- * this routine returns null.
- * @param scope - the active LexicalScope.
- * @param goal - the BURM's goal state. One of the CmcEmitter.__foo_NT
- * constants.
- * @return the result of reducing the subtree to the desired goal state, or
- * null if the input subtree was null.
- * @throws Exception from the BURM if the computation didn't succeed or was
- * interrupted.
- */
- public Object reduceSubtree(IASNode subtree, LexicalScope scope, int goal)
- throws Exception
- {
- CmcJSEmitter burm = m_cmcJSEmitter;
- burm.reducer = this.m_burm;
- burm.reducer.setCurrentscope(scope);
-
- burm.burm(subtree, CmcEmitter.__constant_value_NT);
- return burm.getResult();
- }
-
- /**
- * Handle an error from a BURM: emit diagnostics and bump the error count.
- *
- * @param n - the subtree that was to be reduced.
- * @param ex - the exception.
- */
- @SuppressWarnings("nls")
- private static void handleBurmError(CmcJSEmitter burm, IASNode n, Exception ex, LexicalScope scope)
- {
- if (ex instanceof CodegenInterruptedException)
- {
- // If the exception is an InterruptedException, do nothing, as not
- // a real error. The incremental flow kicked in and interrupted
- // the current work, so just throw away the current work and carry
- // on our merry way.
- // No problem should be reported in this case.
- scope.getProblems().clear();
- return;
- }
- else if (!(ex instanceof BURMAbortException))
- {
- scope.addProblem(new CodegenInternalProblem(n, ex));
- }
-
- java.io.PrintWriter dumper;
-
- String dump_dir = System.getenv("JBURG_DUMP_DIR");
- if (dump_dir != null)
- {
- try
- {
- String dump_file = dump_dir + "/failedBurm-" + Integer.toString(dumpCount++) + ".xml";
- dumper = new java.io.PrintWriter(new java.io.FileWriter(dump_file));
- dumper.println("<?xml version=\"1.0\"?>");
- dumper.println("<BurmDump date=\"" + new Date().toString() + "\">");
- burm.dump(dumper);
- dumper.println("<AST>");
- dumper.println(new NodesToXMLStringFormatter(n).toString());
- dumper.println("</AST>");
- dumper.println("</BurmDump>");
- dumper.flush();
- dumper.close();
- }
- catch (Exception e)
- {
- JSSharedData.instance.stderr("Unable to dump due to: " + e.toString());
- try
- {
- JSSharedData.instance.stderr(new NodesToXMLStringFormatter(n).toString());
- }
- catch (Exception cantformat)
- {
- // Probably an error in the AST itself, diagnosed above.
- }
- }
- }
- }
-
- /**
- * Number of diagnostic dumps emitted by this compiler; used to generate
- * unique dump file names.
- */
- static int dumpCount = 0;
-
- public String toString()
- {
- return "JSGenerator: " + m_compilationUnit.toString();
- }
-
- public void setBuildPhase(ICompilationUnit.Operation op)
- {
- m_buildPhase = op;
- m_burm.setBuildPhase(op);
- }
-
- public JSGeneratingReducer getReducer()
- {
- return m_burm;
- }
-
-
- /**
- * Get an ICodeGeneratorFactory that will always return the same ABCGenerator instance
- */
- public static ICodeGeneratorFactory getABCGeneratorFactory()
- {
- return new ICodeGeneratorFactory()
- {
- public ICodeGenerator get ()
- {
- return new JSGenerator();
- }
- };
- }
-
- /**
- * Represents the result of {@link #generateConstantValue}(}.
- * <p>
- * In addition to producing the constant value itself,
- * the constant reduction process can also produce compiler problems.
- */
- public static final class ConstantValue implements IConstantValue
- {
- public ConstantValue(Object value, Collection<ICompilerProblem> problems)
- {
- this.value = value;
- this.problems = problems;
- }
-
- private final Object value;
- private final Collection<ICompilerProblem> problems;
-
- @Override
- public Object getValue()
- {
- return value;
- }
-
- @Override
- public Collection<ICompilerProblem> getProblems()
- {
- return problems;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGlobalDirectiveProcessor.java
----------------------------------------------------------------------
diff --git a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGlobalDirectiveProcessor.java b/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGlobalDirectiveProcessor.java
deleted file mode 100644
index f15d7d5..0000000
--- a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSGlobalDirectiveProcessor.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- *
- * 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 org.apache.flex.compiler.internal.as.codegen;
-
-import org.apache.flex.abc.ABCConstants;
-import org.apache.flex.abc.instructionlist.InstructionList;
-import org.apache.flex.abc.semantics.MethodInfo;
-import org.apache.flex.abc.semantics.Name;
-import org.apache.flex.abc.visitors.IABCVisitor;
-import org.apache.flex.abc.visitors.IClassVisitor;
-import org.apache.flex.abc.visitors.ITraitVisitor;
-import org.apache.flex.abc.visitors.ITraitsVisitor;
-import org.apache.flex.compiler.common.DependencyType;
-import org.apache.flex.compiler.definitions.IDefinition;
-import org.apache.flex.compiler.internal.definitions.ClassDefinition;
-import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
-import org.apache.flex.compiler.internal.scopes.ASScope;
-import org.apache.flex.compiler.internal.tree.as.ClassNode;
-import org.apache.flex.compiler.internal.tree.as.FunctionNode;
-import org.apache.flex.compiler.internal.tree.as.ImportNode;
-import org.apache.flex.compiler.internal.tree.as.InterfaceNode;
-import org.apache.flex.compiler.internal.tree.as.PackageNode;
-import org.apache.flex.compiler.internal.tree.as.VariableNode;
-import org.apache.flex.compiler.problems.DuplicateFunctionDefinitionProblem;
-import org.apache.flex.compiler.problems.ICompilerProblem;
-import org.apache.flex.compiler.scopes.IASScope;
-import org.apache.flex.compiler.tree.ASTNodeID;
-import org.apache.flex.compiler.tree.as.IASNode;
-import org.apache.flex.compiler.tree.mxml.IMXMLDocumentNode;
-
-/**
- * A GlobalDirectiveProcessor translates directives at global scope into ABC.
- * JSGlobalDirectiveProcessor is derived from GlobalDirectiveProcessor and adds
- * workarounds necessary for FalconJS. Ideally FalconJS should use
- * GlobalDirectiveProcessor and retire JSGlobalDirectiveProcessor. This
- * implementation is part of FalconJS. For more details on FalconJS see
- * org.apache.flex.compiler.JSDriver
- */
-public class JSGlobalDirectiveProcessor extends GlobalDirectiveProcessor
-{
- JSGenerator m_generator;
-
- private String m_packageName = null;
-
- /**
- * @param current_scope - the scope to use. It may be created a priori by
- * the caller, so it's not created by nesting an enclosing scope.
- * @param emitter - the ABC emitter.
- */
- public JSGlobalDirectiveProcessor(JSGenerator generator, LexicalScope current_scope, IABCVisitor emitter)
- {
- super(current_scope, emitter);
- m_generator = generator;
- }
-
- @Override
- void declareFunction(FunctionNode f)
- {
- // No modifiers allowed at global scope.
- // super.verifyModifiers(f);
-
- // MISSING in GlobalDirectiveProcessor
- MethodInfo mi = m_generator.generateFunction(f, currentScope, null);
- if (mi != null)
- {
- FunctionDefinition funcDef = f.getDefinition();
- JSSharedData.instance.registerDefinition(funcDef);
-
- // TODO: generalize excluding functions using metadata annotations.
- final String packageName = funcDef.getPackageName();
- if (!packageName.equals("com.jquery"))
- {
- final IClassVisitor cv = ((JSEmitter)emitter).visitPackage(m_packageName);
- cv.visit();
- this.currentScope.traitsVisitor = cv.visitClassTraits();
- cv.visitEnd();
- /*
- * InstanceInfo iinfo = new InstanceInfo(); iinfo.name =
- * JSGeneratingReducer.makeName(packageName); IClassVisitor cv =
- * emitter.visitClass(iinfo, new ClassInfo()); cv.visit();
- * cv.visitInstanceTraits(); ITraitsVisitor ctraits =
- * cv.visitClassTraits(); final Name funcName =
- * funcDef.getMName(currentScope.getProject(),
- * currentScope.getProblems()); final ITraitVisitor tv =
- * ctraits.visitMethodTrait(TRAIT_Method, funcName, 0, mi);
- * tv.visitAttribute(Trait.TRAIT_FINAL, Boolean.TRUE);
- */
- /*
- * final String key = packageName; ICompilationUnit cu =
- * m_generator.m_compilationUnit; ICompilationUnit registeredCU
- * = JSSharedData.instance.getCompilationUnit(key); if( cu !=
- * registeredCU ) { // make the current cu dependent on the
- * registered cu. if( registeredCU != null ) { final
- * CompilerProject compilerProject =
- * (CompilerProject)cu.getProject();
- * compilerProject.addDependency(cu, registeredCU,
- * DependencyType.INHERITANCE); } else {
- * JSSharedData.instance.registerCompilationUnit(key, cu); } }
- */
- }
-
- Name funcName = funcDef.getMName(this.currentScope.getProject());
-
- if (funcName == null)
- {
- // getMName() emitted a diagnostic,
- // repair and continue.
- funcName = new Name("<invalid>");
- }
-
- ITraitVisitor tv = null;
-
- int traitKind = this.processingPackage ?
- DirectiveProcessor.functionTraitKind(f, ABCConstants.TRAIT_Method) :
- DirectiveProcessor.functionTraitKind(f, ABCConstants.TRAIT_Var);
-
- if (!this.currentScope.traitsVisitor.getTraits().containsTrait(traitKind, funcName))
-
- {
- this.currentScope.declareVariableName(funcName);
-
- if (!this.processingPackage)
- {
- // Functions at the global scope create a var of type '*'
- // TODO: this should be typed as 'Function' if strict mode is on
- if (f.isGetter() || f.isSetter())
- {
- tv = this.currentScope.traitsVisitor.visitMethodTrait(
- DirectiveProcessor.functionTraitKind(f, ABCConstants.TRAIT_Var),
- funcName,
- ITraitsVisitor.RUNTIME_DISP_ID,
- mi);
- }
- else
- {
- tv = this.currentScope.traitsVisitor.visitSlotTrait(
- DirectiveProcessor.functionTraitKind(f, ABCConstants.TRAIT_Var),
- funcName,
- ITraitsVisitor.RUNTIME_SLOT,
- LexicalScope.anyType,
- LexicalScope.noInitializer);
-
- /*
- * this.currentScope.getInitInstructions().addInstruction
- * (ABCConstants.OP_getglobalscope);
- * this.currentScope.getInitInstructions
- * ().addInstruction(ABCConstants.OP_newfunction, mi);
- * this
- * .currentScope.getInitInstructions().addInstruction
- * (ABCConstants.OP_setproperty, funcName);
- */
- }
- }
- else
- {
- tv = this.currentScope.traitsVisitor.visitMethodTrait(DirectiveProcessor.functionTraitKind(f, ABCConstants.TRAIT_Method), funcName, 0, mi);
- }
-
- if (tv != null)
- {
- this.currentScope.processMetadata(tv, funcDef.getAllMetaTags());
- }
- }
- else
- {
- ICompilerProblem problem = new DuplicateFunctionDefinitionProblem(f, funcName.getBaseName());
- this.currentScope.addProblem(problem);
- }
- }
- }
-
- /**
- * Declare a class.
- */
- @Override
- void declareClass(ClassNode c)
- {
- verifyClassModifiers(c);
- verifySkinning(c.getDefinition());
- currentScope.getMethodBodySemanticChecker().checkNamespaceOfDefinition(c, c.getDefinition(), currentScope.getProject());
- JSClassDirectiveProcessor cp = JSSharedData.backend.createClassDirectiveProcessor(m_generator, c, this.currentScope, this.emitter);
- cp.traverse(c.getScopedNode());
- cp.finishClassDefinition();
- }
-
- /**
- * Declare an interface.
- */
- @Override
- void declareInterface(InterfaceNode interface_ast)
- {
- verifyInterfaceModifiers(interface_ast);
- currentScope.getMethodBodySemanticChecker().checkNamespaceOfDefinition(interface_ast, interface_ast.getDefinition(), currentScope.getProject());
- InterfaceDirectiveProcessor ip = JSSharedData.backend.createInterfaceDirectiveProcessor(m_generator, interface_ast, this.currentScope, this.emitter);
- ip.traverse(interface_ast.getScopedNode());
- ip.finishInterfaceDefinition();
- }
-
- /**
- * Process a random directive, which at the global level is probably a loose
- * instruction.
- */
- @Override
- void processDirective(IASNode n)
- {
- // Use nodes have no effect
- /*
- * if(n.getNodeID() == ASTNodeID.UseID ) { if(
- * !JSSharedData.GENERATE_EMBED_WRAPPER ) return; }
- */
-
- // workaround for Falcon bug.
- // DirectiveProcessor is observing NamespaceIdentifierID instead of NamespaceID
- if (n.getNodeID() == ASTNodeID.NamespaceID)
- {
- try
- {
- final IClassVisitor cv = ((JSEmitter)emitter).visitPackage(m_packageName);
- cv.visit();
- this.currentScope.traitsVisitor = cv.visitClassTraits();
- cv.visitEnd();
-
- m_generator.generateInstructions(n, CmcEmitter.__statement_NT, this.currentScope);
- // assert(stmt_insns == null);
- }
- finally
- {
- // this.currentScope.traitsVisitor = null;
- }
- return;
- }
-
- // Handle a loose statement.
- InstructionList stmt_insns = m_generator.generateInstructions(n, CmcJSEmitter.__statement_NT, currentScope);
- if (stmt_insns != null)
- directiveInsns.addAll(stmt_insns);
- }
-
- @Override
- void declarePackage(PackageNode p)
- {
- m_packageName = p.getName();
- ((JSEmitter)emitter).visitPackage(m_packageName);
- JSSharedData.instance.registerPackage(m_packageName);
- super.declarePackage(p);
- }
-
- /**
- * Declare a variable.
- */
- @Override
- void declareVariable(VariableNode var)
- {
- super.declareVariable(var);
- }
-
- /**
- * Translate a ImportNode AST into ABC. Subclasses should override this if
- * they can process imports.
- *
- * @param imp - the import's AST.
- */
- @Override
- void processImportDirective(ImportNode imp)
- {
- String importName = imp.getImportName();
- if (!importName.contains("."))
- {
- final IASScope scope = JSGeneratingReducer.getScopeFromNode(imp);
- final IDefinition def = ((ASScope)scope).findProperty(currentScope.getProject(), imp.getImportName(), DependencyType.INHERITANCE);
- if (def == null)
- {
- importName = null;
- }
- else
- {
- // workaround for Falcon bug.
- // Falcon does not always recognize dependencies to package functions provided by SWCs.
- // In this workaround we explicitly set a EXPRESSION dependency.
- /*
- * if( def != null ) { final ICompilationUnit fromCU =
- * m_generator.m_compilationUnit; final CompilerProject
- * compilerProject = (CompilerProject)currentScope.project;
- * final ASProjectScope projectScope =
- * compilerProject.getScope(); final ICompilationUnit toCU =
- * projectScope.getCompilationUnitForDefinition(def); if( fromCU
- * != toCU ) { // sharedData.verboseMessage(
- * "Adding dependency: " + className );
- * compilerProject.addDependency(fromCU, toCU,
- * DependencyGraph.DependencyType.EXPRESSION); } }
- */
-
- // skip imports from the same package.
- if (def.getPackageName().equals(m_packageName))
- importName = null;
- else
- importName = JSGeneratingReducer.definitionToString(currentScope.getProject(), def);
- }
- }
-
- if (importName != null)
- {
- JSEmitter emitter = (JSEmitter)this.currentScope.getEmitter();
- emitter.visitImport(importName, imp.getImportKind());
- }
- }
-
- /**
- * Declare an MXML document.
- */
- @Override
- void declareMXMLDocument(IMXMLDocumentNode d)
- {
- verifySkinning((ClassDefinition)d.getDefinition());
- try
- {
- MXMLClassDirectiveProcessor dp;
- dp = new JSMXMLClassDirectiveProcessor(d, this.currentScope, this.emitter);
- dp.processMainClassDefinitionNode(d);
- dp.finishClassDefinition();
- }
- catch (Error e)
- {
- System.out.print(e);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/c3dce49f/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSInterfaceDirectiveProcessor.java
----------------------------------------------------------------------
diff --git a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSInterfaceDirectiveProcessor.java b/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSInterfaceDirectiveProcessor.java
deleted file mode 100644
index 2241017..0000000
--- a/compiler.js/src/org/apache/flex/compiler/internal/as/codegen/JSInterfaceDirectiveProcessor.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *
- * 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 org.apache.flex.compiler.internal.as.codegen;
-
-import static org.apache.flex.abc.ABCConstants.*;
-
-import org.apache.flex.abc.semantics.MethodInfo;
-import org.apache.flex.abc.semantics.Name;
-import org.apache.flex.abc.visitors.IABCVisitor;
-import org.apache.flex.abc.visitors.IMethodVisitor;
-import org.apache.flex.compiler.definitions.INamespaceDefinition;
-import org.apache.flex.compiler.definitions.references.INamespaceReference;
-import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
-import org.apache.flex.compiler.internal.definitions.InterfaceDefinition;
-import org.apache.flex.compiler.internal.tree.as.FunctionNode;
-import org.apache.flex.compiler.internal.tree.as.InterfaceNode;
-import org.apache.flex.compiler.problems.BadAccessInterfaceMemberProblem;
-import org.apache.flex.compiler.problems.InterfaceNamespaceAttributeProblem;
-
-/**
- * The InterfaceDirectiveProcessor translates an InterfaceNode AST and children
- * into an interface declaration and definition in the ABC and the init script,
- * respectively.
- */
-public class JSInterfaceDirectiveProcessor extends InterfaceDirectiveProcessor
-{
- private JSGenerator m_generator;
-
- /**
- * Create an InterfaceDirectiveProcessor and set up the basic AET
- * structures.
- *
- * @param in - the InterfaceNode.
- * @param enclosing_scope - the lexical scope that encloses this interface
- * declaration. Either the global scope or a package scope.
- * @param emitter - the active ABC emitter.
- */
- public JSInterfaceDirectiveProcessor(JSGenerator jsGenerator, InterfaceNode in, LexicalScope enclosing_scope, IABCVisitor emitter)
- {
- super(in, addDefinition(enclosing_scope, in.getDefinition()), emitter);
- m_generator = jsGenerator;
- }
-
- private static LexicalScope addDefinition(LexicalScope enclosing_scope, InterfaceDefinition idef)
- {
- JSSharedData.instance.registerDefinition(idef);
- return enclosing_scope;
- }
-
- /**
- * Declare a function.
- */
- @Override
- void declareFunction(FunctionNode func)
- {
- verifyFunctionModifiers(func);
-
- INamespaceReference ns_ref = func.getDefinition().getNamespaceReference();
-
- if (ns_ref instanceof INamespaceDefinition.IInterfaceNamespaceDefinition)
- {
- // Allowed, continue
- }
- else if (ns_ref instanceof INamespaceDefinition.ILanguageNamespaceDefinition)
- {
- interfaceScope.addProblem(new BadAccessInterfaceMemberProblem(func));
- }
- else
- // if ( ns_ref instanceof UserDefinedNamespaceDefinition )
- {
- interfaceScope.addProblem(new InterfaceNamespaceAttributeProblem(func));
- }
-
- // workaround for Falcon bug.
- // InterfaceDirectiveProcessor currently does not record return type and default values of optional parameters.
- // In order to do so InterfaceDirectiveProcessor needs to do what ClassDirectiveProcessor::declareFunction
- // is doing, which is letting the ABCGenerator kick off CmcEmitter.burm() etc.
- // This is the stack trace for the JS backend implementation:
- // JSGenerator.generateInstructions()
- // JSGenerator.generateMethodBody()
- // JSGenerator.generateFunction()
- // JSClassDirectiveProcessor.declareFunction()
- // The workaround below achieves the same by directly calling JSGenerator.generateFunction(), which is robust
- // enough to handle situations where there is no IMethodBodyVisitor registered.
-
- // MethodInfo mi = m_generator.createMethodInfo(this.interfaceScope, func);
- MethodInfo mi = m_generator.generateFunction(func, this.interfaceScope, null);
-
- IMethodVisitor mv = this.emitter.visitMethod(mi);
- mv.visit();
- mv.visitEnd();
-
- FunctionDefinition funcDef = func.getDefinition();
- Name funcName = funcDef.getMName(interfaceScope.getProject());
- if (mi.getReturnType() == null && funcDef.getReturnTypeReference() != null)
- mi.setReturnType(funcDef.getReturnTypeReference().getMName(interfaceScope.getProject(), funcDef.getContainedScope()));
-
- itraits.visitMethodTrait(functionTraitKind(func, TRAIT_Method), funcName, 0, mi);
- }
-
-}