diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTemplate/TranslationTemplate.cs b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTemplate/TranslationTemplate.cs index 2da28d9..0a587d9 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTemplate/TranslationTemplate.cs +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTemplate/TranslationTemplate.cs @@ -722,13 +722,38 @@ namespace Twiglet.CS2J.Translator.TypeRep } // isStatic method? + private bool _isStatic = false; [XmlAttribute("static")] [System.ComponentModel.DefaultValueAttribute(false)] - public bool IsStatic{ get; set; } + public bool IsStatic { + get + { + return _isStatic; + } + set + { + _isStatic = value; + } + } + + private bool _isPartialDefiner = false; + [XmlAttribute("partial")] + [System.ComponentModel.DefaultValueAttribute(false)] + public bool IsPartialDefiner { + get + { + return _isPartialDefiner; + } + set + { + _isPartialDefiner = value; + } + } public MethodRepTemplate() { IsStatic = false; + IsPartialDefiner = false; } public MethodRepTemplate(TypeRepTemplate parent, MethodRepTemplate copyFrom) : base(parent, copyFrom) @@ -762,6 +787,7 @@ namespace Twiglet.CS2J.Translator.TypeRep } IsStatic = copyFrom.IsStatic; + IsPartialDefiner = copyFrom.IsPartialDefiner; } public MethodRepTemplate(string retType, string methodName, string[] tParams, List pars, string[] imps, string javaRep) @@ -771,6 +797,7 @@ namespace Twiglet.CS2J.Translator.TypeRep TypeParams = tParams; Return = retType; IsStatic = false; + IsPartialDefiner = false; } public MethodRepTemplate (string retType, string methodName, string[] tParams, List pars) : this(retType, methodName, tParams, pars, null, null) @@ -788,6 +815,13 @@ namespace Twiglet.CS2J.Translator.TypeRep public override string mkJava() { StringBuilder methStr = new StringBuilder(); + + // if we only have the definition, not the implementation, then don't emit any calls in the Java + if (IsPartialDefiner) + { + return String.Empty; + } + if (IsStatic) { if (SurroundingType != null) { methStr.Append(SurroundingType.TypeName.Substring(SurroundingType.TypeName.LastIndexOf('.') + 1) + "."); @@ -854,7 +888,7 @@ namespace Twiglet.CS2J.Translator.TypeRep } } - return Return == other.Return && Name == other.Name && IsStatic == other.IsStatic && base.Equals(other); + return Return == other.Return && Name == other.Name && IsStatic == other.IsStatic && IsPartialDefiner == other.IsPartialDefiner && base.Equals(other); } public override bool Equals (object obj) @@ -891,7 +925,7 @@ namespace Twiglet.CS2J.Translator.TypeRep } } - return hashCode ^ (Return ?? String.Empty).GetHashCode () ^ (Name ?? String.Empty).GetHashCode () ^ IsStatic.GetHashCode() ^ base.GetHashCode(); + return hashCode ^ (Return ?? String.Empty).GetHashCode () ^ (Name ?? String.Empty).GetHashCode () ^ IsStatic.GetHashCode() ^ IsPartialDefiner.GetHashCode() ^ base.GetHashCode(); } #endregion @@ -2805,6 +2839,7 @@ namespace Twiglet.CS2J.Translator.TypeRep if (Methods != null) { + ResolveResult res = null; foreach (MethodRepTemplate m in Methods) { if (m.Name == name) @@ -2837,13 +2872,20 @@ namespace Twiglet.CS2J.Translator.TypeRep } if (matchingArgs) { - ResolveResult res = new ResolveResult(); + res = new ResolveResult(); res.Result = m; res.ResultType = BuildType(m.Return, AppEnv); - return res; + if (!m.IsPartialDefiner) + return res; } } } + if (res != null) + { + // We must have only found a partial result, nothing to implement it, so return the partial result + return res; + } + } // Look for a property which holds a delegate with the right type if (Properties != null) diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g index dba1f72..0b47ef8 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/JavaPrettyPrint.g @@ -1203,7 +1203,7 @@ embedded_statement returns [bool isSemi, bool isIf, bool indent] -> unsupported(comments = { preComments }, reason = {"unsafe blocks are not supported"}, text = { someText } ) | fixed_statement | expression_statement { preComments = CollectedComments; } - -> op(comments = { preComments }, pre={ $expression_statement.st }, op={ ";" }) // make an expression a statement, need to terminate with semi + -> op(comments = { preComments }, pre={ $expression_statement.st }, op={ ($expression_statement.st.ToString() == "" ? "" : ";") }) // make an expression a statement, if non-empty (e.g. unimplemented partial methods) need to terminate with semi ; fixed_statement: 'fixed' '(' pointer_type fixed_pointer_declarators ')' embedded_statement ; diff --git a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/TemplateExtracter.g b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/TemplateExtracter.g index 65f3e16..35d3b8d 100644 --- a/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/TemplateExtracter.g +++ b/CSharpTranslator/antlr3/src/CS2JTranslator/CS2JTransform/TemplateExtracter.g @@ -255,13 +255,13 @@ class_member_declaration: m=modifiers? ( 'const' ct=type constant_declarators[$ct.thetext] ';' | event_declaration // 'event' - | p='partial' ({ Warning($p.line, "[UNSUPPORTED] 'partial' method definition"); } method_declaration["/* partial */"] + | p='partial' ('void' method_declaration[true, "System.Void"] | interface_declaration[true] | class_declaration[true] | struct_declaration[true]) | interface_declaration[false] // 'interface' - | 'void' method_declaration["System.Void"] - | rt=type ( (member_name '(') => method_declaration[$rt.thetext] + | 'void' method_declaration[false, "System.Void"] + | rt=type ( (member_name '(') => method_declaration[false, $rt.thetext] | (member_name '{') => property_declaration[$rt.thetext] | (member_name '.' 'this') => type_name '.' indexer_declaration[$rt.thetext, $type_name.thetext+"."] | indexer_declaration[$rt.thetext, ""] //this @@ -561,9 +561,9 @@ pointer_type: /////////////////////////////////////////////////////// // Statement Section /////////////////////////////////////////////////////// -block: - ';' - | '{' statement_list? '}'; +block returns [bool isEmpty]: + ';' {$isEmpty = true;} + | '{' statement_list? '}' {$isEmpty = false;}; statement_list: statement+ ; @@ -856,16 +856,23 @@ variable_declarator [string type, bool isEvent]: ; // eg. event EventHandler IInterface.VariableName = Foo; /////////////////////////////////////////////////////// -method_declaration [string returnType]: - method_header[$returnType] method_body ; -method_header [string returnType]: +method_declaration [bool isPartial, string returnType]: + method_header[$returnType] method_body + { + if ($isPartial && $method_body.isEmpty) { + $method_header.meth.IsPartialDefiner = true; + } + ((InterfaceRepTemplate)$NSContext::currentTypeRep).Methods.Add($method_header.meth); + } + ; +method_header [string returnType] returns [MethodRepTemplate meth]: member_name '(' fpl=formal_parameter_list? ')' - { ((InterfaceRepTemplate)$NSContext::currentTypeRep).Methods.Add(new MethodRepTemplate($returnType, $member_name.name, ($member_name.tyargs == null ? null : $member_name.tyargs.ToArray()), $fpl.paramlist)); } type_parameter_constraints_clauses? { DebugDetail("Processing method declaration: " + $member_name.name); } + { $meth = new MethodRepTemplate($returnType, $member_name.name, ($member_name.tyargs == null ? null : $member_name.tyargs.ToArray()), $fpl.paramlist); } ; -method_body: - block ; +method_body returns[bool isEmpty]: + block {$isEmpty = $block.isEmpty; }; member_name returns [string name, List tyargs]: qid { $name = $qid.name; $tyargs = $qid.tyargs; } ; // IInterface.Method logic added. @@ -1268,15 +1275,15 @@ struct_member_declaration: attributes? m=modifiers? ( 'const' ct=type constant_declarators[$ct.thetext] ';' | event_declaration // 'event' - | p='partial' ({ Warning($p.line, "[UNSUPPORTED] 'partial' method definition"); } method_declaration["/* partial */"] + | p='partial' ('void' method_declaration[true, "System.Void"] | interface_declaration[true] | class_declaration[true] | struct_declaration[true]) | interface_declaration[false] // 'interface' | class_declaration[false] // 'class' - | 'void' method_declaration["System.Void"] - | rt=type ( (member_name '(') => method_declaration[$rt.thetext] + | 'void' method_declaration[false, "System.Void"] + | rt=type ( (member_name '(') => method_declaration[false, $rt.thetext] | (member_name '{') => property_declaration[$rt.thetext] | (member_name '.' 'this') => type_name '.' indexer_declaration[$rt.thetext, $type_name.thetext+"."] | indexer_declaration[$rt.thetext, ""] //this