public JsFunction mapFunction(Node fnNode) throws JsParserException { int nodeType = fnNode.getType(); assert nodeType == TokenStream.FUNCTION : "Expected function node, got: " + TokenStream.tokenToName(nodeType); Node fromFnNameNode = fnNode.getFirstChild(); Node fromParamNode = fnNode.getFirstChild().getNext().getFirstChild(); Node fromBodyNode = fnNode.getFirstChild().getNext().getNext(); JsFunction toFn = scopeContext.enterFunction(); // Decide the function's name, if any. // String fnNameIdent = fromFnNameNode.getString(); if (fnNameIdent != null && fnNameIdent.length() > 0) { scopeContext.globalNameFor(fnNameIdent); } while (fromParamNode != null) { String fromParamName = fromParamNode.getString(); JsName name = scopeContext.localNameFor(fromParamName); toFn.getParameters().add(new JsParameter(name)); fromParamNode = fromParamNode.getNext(); } // Map the function's body. // JsBlock toBody = mapBlock(fromBodyNode); toFn.setBody(toBody); scopeContext.exitFunction(); return toFn; }
private void generateRTTImplementsMethod(DartClass x) { ClassElement classElement = x.getSymbol(); // 1) create static type information construction function // function Foo$lookupOrCreateRTT(rtt, typeArgs) { // // // superclass // FooSuper$addTo(rtt, superTypeArg1, ...); // // interfaces // FooInterface1$addTo(rtt, interface1TypeArg1, ...); // // // fill in derived types // rtt.derivedTypes = [ // FirstRef$lookupOrCreateRTT(typearg1, ...), // ... // ] // } boolean hasTypeParams = classElement.getTypeParameters().size() > 0; // Build the function JsFunction implementsFn = new JsFunction(globalScope); implementsFn.setBody(new JsBlock()); List<JsStatement> body = implementsFn.getBody().getStatements(); JsScope scope = new JsScope(globalScope, "temp"); JsName rtt = scope.declareName("rtt"); implementsFn.getParameters().add(new JsParameter(rtt)); JsName typeArgs = null; if (hasTypeParams) { typeArgs = scope.declareName("typeArgs"); implementsFn.getParameters().add(new JsParameter(typeArgs)); } JsInvocation callAddTo = newInvocation(getRTTAddToMethodName(classElement), rtt.makeRef()); if (hasTypeParams) { typeArgs = scope.declareName("typeArgs"); callAddTo.getArguments().add(typeArgs.makeRef()); } body.add(callAddTo.makeStmt()); // Add the derived types if (hasTypeParams) { // Populated the list of derived types JsArrayLiteral derivedTypesArray = new JsArrayLiteral(); // TODO(johnlenz): Add needed types here. JsExpression addDerivedTypes = assign(null, nameref(null, rtt.makeRef(), "derivedTypes"), derivedTypesArray); body.add(addDerivedTypes.makeStmt()); } // Finally, Add the function JsExpression fnDecl = assign(null, getRTTImplementsMethodName(classElement), implementsFn); globalBlock.getStatements().add(fnDecl.makeStmt()); }
@NotNull @Override public JsFunction deepCopy() { JsFunction functionCopy = new JsFunction(scope.getParent(), scope.getDescription(), name); functionCopy.getScope().copyOwnNames(scope); functionCopy.setBody(body.deepCopy()); functionCopy.params = AstUtil.deepCopy(params); return functionCopy.withMetadataFrom(this); }
public void generateDeclarations() { List<JsVar> vars = new SmartList<JsVar>(); List<JsPropertyInitializer> propertyInitializers = new SmartList<JsPropertyInitializer>(); generateOpenClassDeclarations(vars, propertyInitializers); fixUnresolvedClassReferences(); if (vars.isEmpty()) { if (!propertyInitializers.isEmpty()) { classesVar.setInitExpression(new JsObjectLiteral(propertyInitializers, true)); } return; } dummyFunction.setBody( new JsBlock( new JsVars(vars, true), new JsReturn(new JsObjectLiteral(propertyInitializers)))); classesVar.setInitExpression(new JsInvocation(dummyFunction)); }
private void generateRTTLookupMethod(DartClass x) { ClassElement classElement = x.getSymbol(); boolean hasTypeParams = hasTypeParameters(classElement); // 1) create static type information construction function // function Foo$lookupOrCreateRTT(typeargs) { // return $createRTT(name, Foo$RTTimplements, typeargs) ; // } // Build the function JsFunction lookupFn = new JsFunction(globalScope); lookupFn.setBody(new JsBlock()); List<JsStatement> body = lookupFn.getBody().getStatements(); JsScope scope = new JsScope(globalScope, "temp"); JsProgram program = translationContext.getProgram(); JsInvocation invokeCreate = call(null, newQualifiedNameRef("RTT.create"), getRTTClassId(classElement)); List<JsExpression> callArgs = invokeCreate.getArguments(); if (hasRTTImplements(classElement)) { callArgs.add(getRTTImplementsMethodName(classElement)); } else if (hasTypeParams) { // need a placeholder param if the typeArgs are needed. callArgs.add(program.getNullLiteral()); } if (hasTypeParams) { JsName typeArgs = scope.declareName("typeArgs"); lookupFn.getParameters().add(new JsParameter(typeArgs)); callArgs.add(typeArgs.makeRef()); } body.add(new JsReturn(invokeCreate)); // Finally, Add the function JsExpression fnDecl = assign(null, getRTTLookupMethodName(classElement), lookupFn); globalBlock.getStatements().add(fnDecl.makeStmt()); }
private void generateRTTAddToMethod(DartClass x) { ClassElement classElement = x.getSymbol(); // 2) create "addTo" method // Foo$Type$addTo(target, typeargs) { // var rtt = Foo$lookupOrCreateRTT(typeargs) // target.implementedTypes[rtt.classkey] = rtt; // } // Build the function JsFunction addToFn = new JsFunction(globalScope); addToFn.setBody(new JsBlock()); JsScope scope = new JsScope(globalScope, "temp"); JsName targetType = scope.declareName("target"); addToFn.getParameters().add(new JsParameter(targetType)); // Get the RTT info object JsName rtt = scope.declareName("rtt"); List<JsStatement> body = addToFn.getBody().getStatements(); JsInvocation callLookup = newInvocation(getRTTLookupMethodName(classElement)); if (hasTypeParameters(classElement)) { JsName typeArgs = scope.declareName("typeArgs"); addToFn.getParameters().add(new JsParameter(typeArgs)); callLookup.getArguments().add(new JsNameRef(typeArgs)); } JsStatement rttLookup = newVar((SourceInfo) null, rtt, callLookup); body.add(rttLookup); // store it. JsExpression addToTypes = newAssignment( new JsArrayAccess( newNameRef(targetType.makeRef(), "implementedTypes"), newNameRef(rtt.makeRef(), "classKey")), rtt.makeRef()); body.add(addToTypes.makeStmt()); InterfaceType superType = classElement.getSupertype(); if (superType != null && !superType.getElement().isObject()) { ClassElement interfaceElement = superType.getElement(); JsInvocation callAddTo = newInvocation(getRTTAddToMethodName(interfaceElement), targetType.makeRef()); if (hasTypeParameters(interfaceElement) && !superType.hasDynamicTypeArgs()) { JsArrayLiteral superTypeArgs = new JsArrayLiteral(); List<? extends Type> typeParams = classElement.getTypeParameters(); for (Type arg : superType.getArguments()) { superTypeArgs .getExpressions() .add( buildTypeLookupExpression( arg, typeParams, nameref(null, targetType.makeRef(), "typeArgs"))); } callAddTo.getArguments().add(superTypeArgs); } body.add(callAddTo.makeStmt()); } // Add the interfaces for (InterfaceType interfaceType : classElement.getInterfaces()) { ClassElement interfaceElement = interfaceType.getElement(); JsInvocation callAddTo = call(null, getRTTAddToMethodName(interfaceElement), targetType.makeRef()); if (hasTypeParameters(interfaceElement) && !interfaceType.hasDynamicTypeArgs()) { JsArrayLiteral interfaceTypeArgs = new JsArrayLiteral(); List<? extends Type> typeParams = classElement.getTypeParameters(); for (Type arg : interfaceType.getArguments()) { interfaceTypeArgs .getExpressions() .add( buildTypeLookupExpression( arg, typeParams, nameref(null, targetType.makeRef(), "typeArgs"))); } callAddTo.getArguments().add(interfaceTypeArgs); } body.add(callAddTo.makeStmt()); } // Add the function statement JsExpression fnDecl = newAssignment(getRTTAddToMethodName(classElement), addToFn); globalBlock.getStatements().add(fnDecl.makeStmt()); }