diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java
new file mode 100644
index 0000000000..04f90594d5
--- /dev/null
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2016 NumberFour AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * NumberFour AG - Initial API and implementation
+ */
+package org.eclipse.n4js.typesbuilder;
+
+import org.eclipse.n4js.n4JS.FormalParameter;
+import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope;
+import org.eclipse.n4js.ts.typeRefs.TypeRef;
+import org.eclipse.n4js.ts.types.TFormalParameter;
+import org.eclipse.n4js.ts.types.TFunction;
+import org.eclipse.n4js.ts.types.TypesFactory;
+import org.eclipse.n4js.types.utils.TypeUtils;
+
+import com.google.inject.Inject;
+
+class N4JSFormalParameterTypesBuilder {
+
+ @Inject
+ N4JSTypesBuilderHelper _n4JSTypesBuilderHelper;
+
+ boolean relinkFormalParameter(FormalParameter astFormalParameter, TFunction functionType,
+ BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase, int idx) {
+ TFormalParameter formalParameterType = functionType.getFpars().get(idx);
+ _n4JSTypesBuilderHelper.ensureEqualName(astFormalParameter, formalParameterType);
+
+ formalParameterType.setAstElement(astFormalParameter);
+ astFormalParameter.setDefinedVariable(formalParameterType);
+ setFormalParameterType(formalParameterType, astFormalParameter, null, builtInTypeScope, preLinkingPhase);
+
+ return true;
+ }
+
+ TFormalParameter createFormalParameter(FormalParameter n4FormalParameter, BuiltInTypeScope builtInTypeScope,
+ boolean preLinkingPhase) {
+ return createFormalParameter(n4FormalParameter, null, builtInTypeScope, preLinkingPhase);
+ }
+
+ /**
+ * Creates a TFormalParameter for the given FormalParameter from the AST.
+ *
+ * @param defaultTypeRef
+ * will be used in case there is no declared type for the formal parameter; this may be null
+ * and in this case any
will be the formal parameter's actual type.
+ */
+ TFormalParameter createFormalParameter(FormalParameter astFormalParameter, TypeRef defaultTypeRef,
+ BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) {
+ // note: we also build an fpar if astFormalParameter.name===null (otherwise the AST and types model
+ // would have different number of formal parameters in case of a broken AST, messing up indices, etc.)
+ TFormalParameter formalParameterType = TypesFactory.eINSTANCE.createTFormalParameter();
+ formalParameterType.setName(astFormalParameter.getName());
+ formalParameterType.setVariadic(astFormalParameter.isVariadic());
+ formalParameterType.setAstInitializer(null);
+ formalParameterType.setHasInitializerAssignment(astFormalParameter.isHasInitializerAssignment());
+ setFormalParameterType(formalParameterType, astFormalParameter, defaultTypeRef, builtInTypeScope,
+ preLinkingPhase);
+
+ _n4JSTypesBuilderHelper.copyAnnotations(formalParameterType, astFormalParameter, preLinkingPhase);
+
+ formalParameterType.setAstElement(astFormalParameter);
+ astFormalParameter.setDefinedVariable(formalParameterType);
+
+ return formalParameterType;
+ }
+
+ /**
+ * @param formalParameterType
+ * the type system related parameter type to be set
+ * @param astFormalParameter
+ * the AST related parameter which is to be copied to the former
+ */
+ private void setFormalParameterType(TFormalParameter formalParameterType, FormalParameter astFormalParameter,
+ TypeRef defaultTypeRef, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) {
+ if (!preLinkingPhase) {
+ TypeRef copy = TypeUtils.copyWithProxies(astFormalParameter.getDeclaredTypeRefInAST());
+ formalParameterType.setTypeRef(copy != null ? copy
+ : getDefaultParameterType(defaultTypeRef, astFormalParameter, builtInTypeScope));
+ }
+ }
+
+ private TypeRef getDefaultParameterType(TypeRef defaultTypeRef,
+ FormalParameter astFormalParameter, BuiltInTypeScope builtInTypeScope) {
+ if (astFormalParameter.getInitializer() != null) {
+ return TypeUtils.createDeferredTypeRef();
+ } else if (defaultTypeRef == null) {
+ return builtInTypeScope.getAnyTypeRef();
+ } else {
+ return TypeUtils.copy(defaultTypeRef);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend
deleted file mode 100644
index 939b88c359..0000000000
--- a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFormalParameterTypesBuilder.xtend
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * Copyright (c) 2016 NumberFour AG.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * NumberFour AG - Initial API and implementation
- */
-package org.eclipse.n4js.typesbuilder
-
-import com.google.inject.Inject
-import org.eclipse.n4js.n4JS.FormalParameter
-import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope
-import org.eclipse.n4js.ts.typeRefs.TypeRef
-import org.eclipse.n4js.ts.types.TFormalParameter
-import org.eclipse.n4js.ts.types.TFunction
-import org.eclipse.n4js.ts.types.TypesFactory
-import org.eclipse.n4js.types.utils.TypeUtils
-
-package class N4JSFormalParameterTypesBuilder {
-
- @Inject extension N4JSTypesBuilderHelper
-
- def package boolean relinkFormalParameter(FormalParameter astFormalParameter, TFunction functionType, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase, int idx) {
- val formalParameterType = functionType.fpars.get(idx);
- ensureEqualName(astFormalParameter, formalParameterType);
-
- formalParameterType.astElement = astFormalParameter;
- astFormalParameter.definedVariable = formalParameterType;
- setFormalParameterType(formalParameterType, astFormalParameter, null, builtInTypeScope, preLinkingPhase);
-
- return true;
- }
-
- def package TFormalParameter createFormalParameter(FormalParameter n4FormalParameter, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) {
- return createFormalParameter(n4FormalParameter, null, builtInTypeScope, preLinkingPhase);
- }
-
- /**
- * Creates a TFormalParameter for the given FormalParameter from the AST.
- *
- * @param defaultTypeRef will be used in case there is no declared type for the formal parameter;
- * this may be null
and in this case any
will be
- * the formal parameter's actual type.
- */
- def package TFormalParameter createFormalParameter(FormalParameter astFormalParameter, TypeRef defaultTypeRef, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase) {
- // note: we also build an fpar if astFormalParameter.name===null (otherwise the AST and types model
- // would have different number of formal parameters in case of a broken AST, messing up indices, etc.)
- val formalParameterType = TypesFactory::eINSTANCE.createTFormalParameter();
- formalParameterType.name = astFormalParameter.name;
- formalParameterType.variadic = astFormalParameter.variadic;
- formalParameterType.astInitializer = null;
- formalParameterType.hasInitializerAssignment = astFormalParameter.hasInitializerAssignment;
- setFormalParameterType(formalParameterType, astFormalParameter, defaultTypeRef, builtInTypeScope, preLinkingPhase)
-
- copyAnnotations(formalParameterType, astFormalParameter, preLinkingPhase)
-
- formalParameterType.astElement = astFormalParameter;
- astFormalParameter.definedVariable = formalParameterType;
-
- return formalParameterType;
- }
-
- /**
- * @param formalParameterType the type system related parameter type to be set
- * @param astFormalParameter the AST related parameter which is to be copied to the former
- */
- def private void setFormalParameterType(TFormalParameter formalParameterType, FormalParameter astFormalParameter,
- TypeRef defaultTypeRef, BuiltInTypeScope builtInTypeScope, boolean preLinkingPhase
- ) {
- if (!preLinkingPhase)
- formalParameterType.typeRef = TypeUtils.copyWithProxies(astFormalParameter.declaredTypeRefInAST) ?: getDefaultParameterType(defaultTypeRef, astFormalParameter, builtInTypeScope)
- }
-
- def private TypeRef getDefaultParameterType(TypeRef defaultTypeRef,
- FormalParameter astFormalParameter, BuiltInTypeScope builtInTypeScope
- ) {
- if (astFormalParameter.initializer !== null) {
- TypeUtils.createDeferredTypeRef
- } else if (defaultTypeRef === null) {
- builtInTypeScope.anyTypeRef
- } else {
- TypeUtils.copy(defaultTypeRef)
- }
- }
-}
diff --git a/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java
new file mode 100644
index 0000000000..6c00548e43
--- /dev/null
+++ b/plugins/org.eclipse.n4js/src/org/eclipse/n4js/typesbuilder/N4JSFunctionDefinitionTypesBuilder.java
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2016 NumberFour AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * NumberFour AG - Initial API and implementation
+ */
+package org.eclipse.n4js.typesbuilder;
+
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.filterNull;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.map;
+import static org.eclipse.xtext.xbase.lib.IterableExtensions.toList;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.n4js.n4JS.FunctionDeclaration;
+import org.eclipse.n4js.n4JS.FunctionDefinition;
+import org.eclipse.n4js.n4JS.FunctionExpression;
+import org.eclipse.n4js.n4JS.N4JSPackage;
+import org.eclipse.n4js.scoping.builtin.BuiltInTypeScope;
+import org.eclipse.n4js.ts.typeRefs.TypeRef;
+import org.eclipse.n4js.ts.types.AbstractNamespace;
+import org.eclipse.n4js.ts.types.TFunction;
+import org.eclipse.n4js.ts.types.TypesFactory;
+import org.eclipse.n4js.types.utils.TypeUtils;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * Type builder for function declaration or expression builder.
+ */
+// TODO we temporarily create a BuiltInTypeScope in order to get primitive types. This may be changed by passing in this
+// scope, one this method is called by the typesystem
+@Singleton
+public class N4JSFunctionDefinitionTypesBuilder extends AbstractFunctionDefinitionTypesBuilder {
+
+ @Inject
+ N4JSFormalParameterTypesBuilder _n4JSFormalParameterTypesBuilder;
+ @Inject
+ N4JSTypeVariableTypesBuilder _n4JSTypeVariableTypesBuilder;
+ @Inject
+ N4JSVariableStatementTypesBuilder _n4JSVariableStatementTypesBuilder;
+ @Inject
+ N4JSTypesBuilderHelper _n4JSTypesBuilderHelper;
+
+ boolean relinkTFunction(FunctionDeclaration functionDecl, AbstractNamespace target, boolean preLinkingPhase,
+ int idx) {
+ EObject functionDefinedType = (EObject) functionDecl
+ .eGet(N4JSPackage.eINSTANCE.getTypeDefiningElement_DefinedType(), false);
+ if (functionDefinedType != null && !functionDefinedType.eIsProxy()) {
+ throw new IllegalStateException("TFunction already created for FunctionDeclaration");
+ }
+
+ if (functionDecl.getName() == null) {
+ return false;
+ }
+
+ TFunction functionType = target.getFunctions().get(idx);
+ _n4JSTypesBuilderHelper.ensureEqualName(functionDecl, functionType);
+
+ relinkFormalParameters(functionType, functionDecl, preLinkingPhase);
+ functionType.setAstElement(functionDecl);
+ functionDecl.setDefinedType(functionType);
+
+ return true;
+ }
+
+ /**
+ * Creates TFunction for the given function declaration and adds it to the modules top level types (as function
+ * declarations are only allowed on top level).
+ *
+ * @param functionDecl
+ * declaration for which the TFunction is created, must not be linked to a TFunction yet (i.e. its
+ * defined type must be null).
+ * @param target
+ * the module to which the newly created TFunction is added
+ */
+ void createTFunction(FunctionDeclaration functionDecl, AbstractNamespace target, boolean preLinkingPhase) {
+ EObject functionDefinedType = (EObject) functionDecl
+ .eGet(N4JSPackage.eINSTANCE.getTypeDefiningElement_DefinedType(), false);
+ if (functionDefinedType != null && !functionDefinedType.eIsProxy()) {
+ throw new IllegalStateException("TFunction already created for FunctionDeclaration");
+ }
+
+ if (functionDecl.getName() == null) {
+ return;
+ }
+
+ BuiltInTypeScope builtInTypeScope = BuiltInTypeScope.get(functionDecl.eResource().getResourceSet());
+ TFunction functionType = createAndLinkTFunction(functionDecl);
+ _n4JSVariableStatementTypesBuilder.createImplicitArgumentsVariable(functionDecl, target, builtInTypeScope,
+ preLinkingPhase);
+
+ addFormalParameters(functionType, functionDecl, builtInTypeScope, preLinkingPhase);
+ _n4JSTypesBuilderHelper.setTypeAccessModifier(functionType, functionDecl);
+ _n4JSTypesBuilderHelper.setProvidedByRuntime(functionType, functionDecl, preLinkingPhase);
+ setReturnType(functionType, functionDecl, builtInTypeScope, preLinkingPhase);
+ _n4JSTypeVariableTypesBuilder.addTypeParameters(functionType, functionDecl, preLinkingPhase);
+ _n4JSTypesBuilderHelper.setDeclaredThisTypeFromAnnotation(functionType, functionDecl, preLinkingPhase);
+ _n4JSTypesBuilderHelper.copyAnnotations(functionType, functionDecl, preLinkingPhase);
+ functionType.setDeclaredAsync(functionDecl.isAsync());// TODO change to declaredAsync once the annotation is
+ // gone
+ functionType.setDeclaredGenerator(functionDecl.isGenerator());
+
+ // set container
+ target.getFunctions().add(functionType);
+ }
+
+ /**
+ * Creates TFunction for the given function expression and adds it to the module. Note that this method applies only
+ * to expressions that define a function, not to function type expressions that merely define a function type (the
+ * latter are represented in the AST and TModule by a node of type FunctionTypeExpression
from
+ * Types.xcore).
+ *
+ * Creating a TFunction for a function expression becomes a bit tricky when type inference has to be used to infer + * the types of one or more formal parameters and/or the return value. These are the steps involved: + *
FunctionTypeExpression
- * from Types.xcore).
- * - * Creating a TFunction for a function expression becomes a bit tricky when type inference has to be used to - * infer the types of one or more formal parameters and/or the return value. These are the steps involved: - *