Linter Demo Errors: 0Warnings: 2File: /home/fstrocco/Dart/dart/benchmark/compiler/lib/src/native/ssa.dart // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. part of native; final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$'); void handleSsaNative(SsaBuilder builder, Expression nativeBody) { Compiler compiler = builder.compiler; FunctionElement element = builder.work.element; NativeEmitter nativeEmitter = builder.nativeEmitter; JavaScriptBackend backend = builder.backend; HInstruction convertDartClosure(ParameterElement parameter, FunctionType type) { HInstruction local = builder.localsHandler.readLocal(parameter); ConstantValue arityConstant = builder.constantSystem.createInt(type.computeArity()); HInstruction arity = builder.graph.addConstant(arityConstant, compiler); // TODO(ngeoffray): For static methods, we could pass a method with a // defined arity. Element helper = backend.getClosureConverter(); builder.pushInvokeStatic(nativeBody, helper, [local, arity]); HInstruction closure = builder.pop(); return closure; } // Check which pattern this native method follows: // 1) foo() native; // hasBody = false // 2) foo() native "bar"; // No longer supported, this is now done with @JSName('foo') and case 1. // 3) foo() native "return 42"; // hasBody = true bool hasBody = false; assert(element.isNative); String nativeMethodName = element.fixedBackendName; if (nativeBody != null) { LiteralString jsCode = nativeBody.asLiteralString(); String str = jsCode.dartString.slowToString(); if (nativeRedirectionRegExp.hasMatch(str)) { compiler.internalError( nativeBody, "Deprecated syntax, use @JSName('name') instead."); } hasBody = true; } if (!hasBody) { nativeEmitter.nativeMethods.add(element); } FunctionSignature parameters = element.functionSignature; if (!hasBody) { List arguments = []; List inputs = []; String receiver = ''; if (element.isInstanceMember) { receiver = '#.'; inputs.add(builder.localsHandler.readThis()); } parameters.forEachParameter((ParameterElement parameter) { DartType type = parameter.type.unalias(compiler); HInstruction input = builder.localsHandler.readLocal(parameter); if (type is FunctionType) { // The parameter type is a function type either directly or through // typedef(s). input = convertDartClosure(parameter, type); } inputs.add(input); arguments.add('#'); }); String foreignParameters = arguments.join(','); String nativeMethodCall; if (element.kind == ElementKind.FUNCTION) { nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)'; } else if (element.kind == ElementKind.GETTER) { nativeMethodCall = '$receiver$nativeMethodName'; } else if (element.kind == ElementKind.SETTER) { nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters'; } else { builder.compiler.internalError(element, 'Unexpected kind: "${element.kind}".'); } builder.push( new HForeignCode( // TODO(sra): This could be cached. The number of templates should // be proportional to the number of native methods, which is bounded // by the dart: libraries. js.js.uncachedExpressionTemplate(nativeMethodCall), backend.dynamicType, inputs, effects: new SideEffects())); builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); } else { if (parameters.parameterCount != 0) { compiler.internalError(nativeBody, 'native "..." syntax is restricted to ' 'functions with zero parameters.'); } LiteralString jsCode = nativeBody.asLiteralString(); builder.push(new HForeignCode.statement( js.js.statementTemplateYielding( new js.LiteralStatement(jsCode.dartString.slowToString())), [], new SideEffects(), null, backend.dynamicType)); } }