summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2007-06-09 17:00:37 +0000
committerIulian Dragos <jaguarul@gmail.com>2007-06-09 17:00:37 +0000
commitd4cc633ec978a0a6e04e11c2d6d8425e2d3b3725 (patch)
treed4dfc570e0d8fa11f15ee2ae6c4bcc019a1ae975 /src
parent8414ebada9615aac0e8b436e7bdbeee5986ccaa3 (diff)
downloadscala-d4cc633ec978a0a6e04e11c2d6d8425e2d3b3725.tar.gz
scala-d4cc633ec978a0a6e04e11c2d6d8425e2d3b3725.tar.bz2
scala-d4cc633ec978a0a6e04e11c2d6d8425e2d3b3725.zip
Added patch to allow definition of native metho...
Added patch to allow definition of native methods in Scala (contribution from Stepan Koltsov)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala5
-rw-r--r--src/library/scala/native.scala24
8 files changed, 54 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index fd396acd37..09935b69e6 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -109,8 +109,10 @@ abstract class GenICode extends SubComponent {
var ctx1 = ctx.enterMethod(m, tree.asInstanceOf[DefDef])
addMethodParams(ctx1, vparamss)
+ val NativeAttr = atPhase(currentRun.typerPhase)(definitions.getClass("scala.native").tpe)
+ m.native = m.symbol.hasAttribute(NativeAttr)
- if (!m.isDeferred) {
+ if (!m.isDeferred && !m.native) {
ctx1 = genLoad(rhs, ctx1, m.returnType);
// reverse the order of the local variables, to match the source-order
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index bc8f4b1dd9..0203d73f39 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -404,6 +404,10 @@ abstract class GenJVM extends SubComponent {
if (jclass.isInterface())
flags = flags | JAccessFlags.ACC_ABSTRACT;
+ // native methods of objects are generated in mirror classes
+ if (method.native)
+ flags = flags | JAccessFlags.ACC_NATIVE
+
jmethod = jclass.addNewMethod(flags,
javaName(m.symbol),
resTpe,
@@ -421,7 +425,7 @@ abstract class GenJVM extends SubComponent {
m.symbol.attributes = ainfo :: m.symbol.attributes;
}
- if (!jmethod.isAbstract()) {
+ if (!jmethod.isAbstract() && !method.native) {
jcode = jmethod.getCode().asInstanceOf[JExtendedCode]
// add a fake local for debugging purpuses
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index a4a3b0ce79..566568b16a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -99,6 +99,7 @@ trait Definitions {
var PredefModule: Symbol = _
def Predef_classOf = getMember(PredefModule, nme.classOf)
def Predef_identity = getMember(PredefModule, nme.identity)
+ def Predef_error = getMember(PredefModule, nme.error)
var ConsoleModule: Symbol = _
var MatchErrorClass: Symbol = _
//var MatchErrorModule: Symbol = _
@@ -369,6 +370,7 @@ trait Definitions {
var DeprecatedAttr: Symbol = _
var BeanPropertyAttr: Symbol = _
var AnnotationDefaultAttr: Symbol = _
+ var NativeAttr: Symbol = _
def getModule(fullname: Name): Symbol = getModuleOrClass(fullname, true)
@@ -937,6 +939,7 @@ trait Definitions {
SerializableAttr = getClass("scala.serializable")
BeanPropertyAttr = if (forCLDC || forMSIL) null else getClass("scala.reflect.BeanProperty")
DeprecatedAttr = getClass("scala.deprecated")
+ NativeAttr = getClass("scala.native")
SyntheticClasses = new HashSet[Symbol]
SyntheticClasses ++= List(
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 12fbe8cf80..60caa722a8 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -259,6 +259,7 @@ trait StdNames {
val equals_ = newTermName("equals")
val _equals = newTermName("_equals")
val _equalsWithVarArgs = newTermName("_equalsWithVarArgs")
+ val error = newTermName("error")
val ex = newTermName("ex")
val fail = newTermName("fail")
val false_ = newTermName("false")
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index c21a606ec4..f3f48d3c72 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -81,6 +81,11 @@ trait Symbols {
}
var attributes: List[AnnotationInfo] = List()
+ def hasAttribute(Tpe: Type): Boolean =
+ attributes.exists {
+ case AnnotationInfo(Tpe, _, _) => true
+ case _ => false
+ }
var privateWithin: Symbol = _
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 944d271d1d..9494b3bba6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -741,7 +741,7 @@ trait Namers { self: Analyzer =>
* - `abstract' modifier only for classes
* - `override' modifier never for classes
* - `def' modifier never for parameters of case classes
- * - declarations only in mixins or abstract classes
+ * - declarations only in mixins or abstract classes (when not @native)
*/
def validate(sym: Symbol): unit = {
def checkNoConflict(flag1: int, flag2: int): unit =
@@ -769,12 +769,14 @@ trait Namers { self: Analyzer =>
sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE))
context.error(sym.pos, "pass-by-name arguments not allowed for case class parameters");
if ((sym.flags & DEFERRED) != 0) {
- if (!sym.isValueParameter && !sym.isTypeParameterOrSkolem &&
- !context.tree.isInstanceOf[ExistentialTypeTree] &&
- (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass)) {
- context.error(sym.pos,
- "only classes can have declared but undefined members" + varNotice(sym))
+ if (sym.hasAttribute(definitions.NativeAttr.tpe))
sym.resetFlag(DEFERRED)
+ else if (!sym.isValueParameter && !sym.isTypeParameterOrSkolem &&
+ !context.tree.isInstanceOf[ExistentialTypeTree] &&
+ (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass)) {
+ context.error(sym.pos,
+ "only classes can have declared but undefined members" + varNotice(sym))
+ sym.resetFlag(DEFERRED)
}
}
checkNoConflict(DEFERRED, PRIVATE)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index c81e28a398..f178590a42 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -692,6 +692,11 @@ abstract class RefChecks extends InfoTransform {
validateVariance(sym, sym.info, CoVariance)
validateVariance(sym, sym.typeOfThis, CoVariance)
+ case DefDef(mods, name, tparams, vparams, tpt, EmptyTree) if tree.symbol.hasAttribute(definitions.NativeAttr.tpe) =>
+ tree.symbol.resetFlag(DEFERRED)
+ result = transform(copy.DefDef(tree, mods, name, tparams, vparams, tpt,
+ typed(Apply(gen.mkAttributedRef(definitions.Predef_error), List(Literal("native method stub"))))))
+
case DefDef(_, _, _, _, _, _) =>
validateVariance(sym, sym.tpe, CoVariance) //@M TODO: might be affected by change in tpe --> can't use tree.tpe though
checkDeprecatedOvers()
diff --git a/src/library/scala/native.scala b/src/library/scala/native.scala
new file mode 100644
index 0000000000..c49f0a0579
--- /dev/null
+++ b/src/library/scala/native.scala
@@ -0,0 +1,24 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: $
+
+
+package scala
+
+/**
+ * Marker for native methods.
+ * <p>
+ * <code>@native def f(x: Int, y: List[Long]): String = ..</code>
+ * </p>
+ * <p>
+ * Method body is not generated if method is marked with <code>@native</code>,
+ * but it is type checked when present.
+ * </p>
+ */
+class native extends Annotation {}