├── .hgignore ├── .hgtags ├── NEWS ├── README.md ├── ctest ├── .cproject └── .project ├── feature ├── .project ├── build.properties └── feature.xml ├── lib └── j2c.cpp ├── plugin ├── .classpath ├── .project ├── .settings │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.ltk.core.refactoring.prefs ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── icons │ └── sample.gif ├── plugin.xml └── src │ └── se │ └── arnetheduck │ └── j2c │ ├── Activator.java │ ├── handlers │ ├── HandlerHelper.java │ ├── TestHandler.java │ └── TransformHandler.java │ ├── resources │ ├── Array.hpp │ ├── Main.cpp.tmpl │ ├── Makefile.tmpl │ ├── ObjectArray.hpp │ ├── SubArray.hpp │ ├── finally.hpp │ ├── java_cast.hpp │ ├── npc.hpp │ └── synchronized.hpp │ ├── snippets │ ├── GetSetSnippet.java │ └── ReplaceInvocation.java │ └── transform │ ├── BindingComparator.java │ ├── CName.java │ ├── DepInfo.java │ ├── EmptySnippet.java │ ├── FileUtil.java │ ├── ForwardWriter.java │ ├── Header.java │ ├── HeaderWriter.java │ ├── Impl.java │ ├── ImplWriter.java │ ├── InitInfo.java │ ├── MainWriter.java │ ├── MakefileWriter.java │ ├── Predicate.java │ ├── Snippet.java │ ├── Stats.java │ ├── StubWriter.java │ ├── TransformUtil.java │ ├── TransformWriter.java │ ├── Transformer.java │ ├── TypeBindingHeaderWriter.java │ ├── TypeInfo.java │ ├── TypeInfoVisitor.java │ ├── TypeUtil.java │ └── UnitInfo.java └── test ├── .classpath ├── .project ├── .settings └── org.eclipse.jdt.ui.prefs └── src ├── Sort.java └── se └── arnetheduck └── j2c └── test ├── Annot.java ├── BoxTest.java ├── BridgeTest.java ├── CastTest.java ├── ClassLiteralTest.java ├── ConstructorTest.java ├── DefaultVirtual.java ├── Empty.java ├── EnumTest.java ├── ExtendsTest.java ├── ForTest.java ├── Friends.java ├── GenericTest.java ├── Hello.java ├── IEmpty.java ├── ISub.java ├── ITest.java ├── IfElseTest.java ├── Infix.java ├── InitTest.java ├── LabelTest.java ├── LiteralTest.java ├── LocalClassTest.java ├── MainTest.java ├── Method.java ├── Names.java ├── NestedAccessTest.java ├── NestedTest.java ├── Object.java ├── ParamConstructor.java ├── PrimitiveTest.java ├── ReturnTest.java ├── ShiftTest.java ├── StaticImportTest.java ├── StringTest.java ├── Sub.java ├── SuperTest.java ├── SyncTest.java ├── SyntheticTest.java ├── TryTest.java ├── VarargTest.java ├── Volatile.java ├── a └── Empty.java ├── array ├── Classes.java ├── Covariance.java ├── Interfaces.java ├── Mixed.java ├── MultiArray.java ├── Primitives.java ├── TestArray.java └── TestArrayArray.java ├── asm └── int32_t.java ├── b └── OtherArrayTest.java ├── enums ├── AnonymousConstants.java ├── Ctor.java ├── EnumBridge.java ├── ImplicitMethods.java └── SimpleEnum.java ├── generics ├── BaseCall.java ├── DiamondImplements.java ├── Fields.java ├── GenHiding.java ├── GenericBoxing.java ├── Implement.java ├── MethodInvocationCast.java ├── MultiBound.java ├── NamedLocal.java ├── Raw.java ├── ReturnCovariance.java └── SuperBridgeCall.java ├── hiding ├── A.java ├── B.java ├── HiddenByType.java ├── HiddenField.java └── HiddenMethod.java ├── init ├── ConstExpr.java ├── Constructor.java ├── InitBeforeCons.java ├── Instance.java ├── PrivateConstructor.java ├── Static.java ├── StaticClosure.java └── StringDep.java ├── interfaces ├── SameName.java ├── SameNameOverload.java └── UnqualifiedInterfaceField.java ├── methods ├── AbstractWithInterface.java ├── AmbiguousOverloads.java ├── AmbiguousSuper.java ├── BaseCall.java ├── BaseFinalImpl.java ├── BaseImplements.java ├── ConstVars.java ├── CovariantCircular.java ├── CovariantCircularDeep.java ├── CovariantInterface.java ├── CovariantReturn.java ├── CrossCovariant.java ├── DefaultVirtualOverride.java ├── DiamondImplements.java ├── DoubleImplements.java ├── DoubleInheritedImplements.java ├── GenericBaseImplements.java ├── GenericDoubleImplements.java ├── Hiding.java ├── HidingStatic.java ├── Implement.java ├── ImplementOverloads.java ├── ImportStaticCall.java ├── InheritedCovariant.java ├── Overrides.java ├── SimpleImplements.java ├── StaticInvokes.java ├── UnrelatedCovariant.java └── Using.java ├── nesting ├── Annot.java ├── ClosureInInitializer.java ├── ClosureNames.java ├── Deep.java ├── DeepSiblings.java ├── DoubleAnon.java ├── FieldInit.java ├── GenericQualifiedThis.java ├── LocalNamed.java ├── LocalNested.java ├── LocalOverload.java ├── LocalPrivateCtor.java ├── MethodParam.java ├── NewPrimary.java ├── OuterSubclass.java ├── QualifiedThisSuper.java ├── SameName.java ├── Siblings.java ├── StaticNonStatic.java └── Subclass.java └── switchx ├── Empty.java ├── InterfaceValues.java ├── NestedEnumSwitch.java ├── SwitchEnum.java └── SwitchTest.java /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | bin/* 3 | *.o 4 | 5 | syntax: regexp 6 | ^ctest/[^.].+ 7 | -------------------------------------------------------------------------------- /.hgtags: -------------------------------------------------------------------------------- 1 | 3004f66e087bd43824775f245874d25dd79ea337 0.1.0 2 | 33a86471b626184e3cb1955e2490756178ea3665 0.2.0 3 | b102a36aa2a5b8c82445c5472133f279632028c9 0.2.1 4 | 6c1f84ab525058f7759d97f3610d545c63d8c4df 0.2.2 5 | fcbc91b7c0b96a12a683dde1918ca88a380f8a35 0.3.0 6 | 92411fafce421efc3d39a6e9bae82e3a6034d3fe 0.3.1 7 | 1208612a2e6c2f0409a61f976fa7dac26fcd0c02 0.4.0 8 | 301a66667950e7b7b1fee1fb178a320f58c45321 0.5.0 9 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 0.5.0 2 | ----- 3 | * Multiselect translates all selected items (have to be from same project) 4 | * Initialize members in headers, don't generate default constructors that shouldn't be there 5 | * Implement values and valueOf for enums, and fix their name / ordinal 6 | * Range-for-loops when looping over arrays 7 | * Use auto when declaring variables 8 | * Use single template class for arrays instead of generated .hpp/.cpp pairs 9 | * Bugfixes 10 | * Drop unused CDT dependency (might come back) 11 | * Release through update site 12 | 13 | 0.4.0 14 | ----- 15 | * Source and header files are now both generated in the src directory 16 | * Avoid generating unnecessary clinit's/ctor:s 17 | * Report name of unimplemented stubs 18 | * Implement volatile using std::atomic 19 | * Other small fixes 20 | 21 | 0.3.1 22 | ----- 23 | * Fix too few stubs and too many natives being generated in certain cases 24 | 25 | 0.3.0 26 | ----- 27 | * No more mangling of variable names (unless unavoidable) 28 | * Handle more corner cases 29 | * Static initalization / construction fixes 30 | * Better switch break handling 31 | * Throw correct exception on cast failure 32 | * Null checking 33 | * Handle cyclic dependencies due to return type covariance 34 | * Minimum Java required version is now 1.6 (instead of 1.7) 35 | 36 | 0.2.2 37 | ----- 38 | * Handle more selection types in the project explorer 39 | 40 | 0.2.1 41 | ----- 42 | * Also show translate menu item in project explorer 43 | 44 | 0.2.0 45 | ----- 46 | * Successfully converts most of OpenJDK 6! 47 | 48 | 0.1.0 49 | ----- 50 | * Initial release 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Introduction 2 | -- 3 | J2C will convert Java code into hopefully compilable C++(11) code. It works on 4 | source level, translating Java source code constructs into their rough 5 | equivalents in C++ . The output will be reasonably valid C++ code that looks a 6 | lot like its Java counterpart and hopefully works mostly the same. 7 | 8 | The translation is based on The Java Language Specification, Third Edition, by 9 | Gosling, James and Joy, Bill and Steele, Guy and Bracha, Gilad (that's 10 | Java 1.6). The translated code should be valid as specified by the ISO/IEC 11 | 14882:2011 C++ standard (or C++11 as the rest of the world knows it). 12 | 13 | *The generated code won't work out of the box - you need to remove or implement 14 | dependencies such as the JRE.* 15 | 16 | Status 17 | -- 18 | This project is an idea I've been wanting to try out written down in code. 19 | Think of it as a paper napkin with some notes on, but in this case, the notes 20 | compile and sometimes spit out working stuff. In other words, no guarantees 21 | and no quality control label. 22 | 23 | That said, j2c successfully converts most of OpenJDK 6 and SWT 3.7 to C++ 24 | that compiles and passes a quick ocular inspection. Most *language* features 25 | of Java 1.6 are covered (i e you'll still need a JDK and runtime). 26 | 27 | With a few patches and implementations of native methods in the converted 28 | OpenJDK code, the included Hello test prints it's message. A more complete 29 | example would need a more complete runtime, either by implementing the native 30 | and JVM parts of a class library or by implementing the stubs that are 31 | generated for missing dependencies. 32 | 33 | This is the first time I write an Eclipse plugin, so be nice. 34 | 35 | Install / Run 36 | -- 37 | J2C comes in the form of an Eclipse plugin. You need at least Eclipse 3.8+ and 38 | Java 1.6+ to run this plugin! 39 | 40 | The most recent version of the project is available as source code. You can get 41 | it either from Bitbucket (https://bitbucket.org/arnetheduck/j2c/) 42 | or github (https://github.com/arnetheduck/j2c). 43 | 44 | From time to time, a release may appear at the Bitbucket site - see 45 | https://bitbucket.org/arnetheduck/j2c/downloads . About that same 46 | time, the update site (https://bitbucket.org/arnetheduck/j2c.site/raw/default/) 47 | should be updated. 48 | 49 | If you installed via site, it should just work. 50 | 51 | If you downloaded the jar, copy it to `$ECLIPSE_HOME/dropins`. 52 | 53 | If you downloaded the source code you'll have run the plugin by opening the 54 | project in Eclipse and starting a new Eclipse test instance by using the run 55 | button in the plugin.xml overview. 56 | 57 | Once you have the plugin running, set up your Java code as a Java 58 | Project. Eclipse must be able to compile your code for J2C do to its work! 59 | 60 | Once the Java Project is set up (with all dependencies etc), you can run J2C by 61 | right-clicking the project (or a class/package) in the 'Project Explorer' or 62 | 'Package Explorer' view and choosing the 'Translate to C++' option. You will 63 | need to create a folder for the conversion output - the plugin will tell you 64 | where. 65 | 66 | The generated code will contain references to your JRE (stuff from the `java.*` 67 | packages), as well as some generic helpers. The JRE dependencies will likely be 68 | stubbed out in the ext folder in the generated code, and trivial, non-working 69 | implementations of the rest can be found in j2c.cpp. You'll need to supplant 70 | the converted code with implementations of all JRE features you're using, 71 | or replace them manually to use equivalents from C++ libraries such as STL. 72 | 73 | Testing 74 | -- 75 | The test project contains a few cases which should be handled correctly by the 76 | translator (by correctly, I mean that they compile with g++ 4.7). You'll find 77 | a CDT project in ctest that builds using the generated Makefile after running 78 | the plugin on the test project. 79 | 80 | Output 81 | -- 82 | For each Java class, j2c will output a header file and its implementation. 83 | Inner classes end up in separate .h/.cpp pairs. Native method stubs will be 84 | put in a separate file for your editing pleasure. 85 | 86 | Classes for which there is no source will have a header written as well as 87 | a stub file with empty implementations. Throughout, the heap will be used 88 | to allocate class instances but no attempt is made to collect garbage - 89 | I recommend Boehm's garbage collector for that. 90 | 91 | What's missing (that I can think of right now) 92 | -- 93 | * Reflection 94 | * Anything involving byte code (class loading, dynamic code generation, etc) 95 | * Command line support / build integration 96 | 97 | Helping out 98 | -- 99 | Patches and forks are most welcome, as is testing, but please don't report 100 | issues unless you also attach a simple test case. 101 | 102 | Final words 103 | -- 104 | Send me a note if you manage (or not) to do something useful with this 105 | converter! 106 | 107 | Licensing 108 | -- 109 | The project is licensed under the Eclipse Public License 1.0. 110 | 111 | Thanks 112 | -- 113 | No animals were hurt while writing this code, but the Nightwatchman 114 | might have sore fingers and throat from all that playing... 115 | 116 | Have fun, 117 | Jacek Sieka (arnetheduck using google mail point com) 118 | -------------------------------------------------------------------------------- /ctest/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /ctest/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | se.arnetheduck.j2c.ctest 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?children? 14 | ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\|| 15 | 16 | 17 | ?name? 18 | 19 | 20 | 21 | org.eclipse.cdt.make.core.append_environment 22 | true 23 | 24 | 25 | org.eclipse.cdt.make.core.autoBuildTarget 26 | all 27 | 28 | 29 | org.eclipse.cdt.make.core.buildArguments 30 | -k -j 31 | 32 | 33 | org.eclipse.cdt.make.core.buildCommand 34 | make 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | false 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.core.ccnature 80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 81 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 82 | 83 | 84 | -------------------------------------------------------------------------------- /feature/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | se.arnetheduck.j2c.feature 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.pde.FeatureBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.pde.FeatureNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /feature/build.properties: -------------------------------------------------------------------------------- 1 | bin.includes = feature.xml 2 | -------------------------------------------------------------------------------- /lib/j2c.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | using namespace java::lang; 11 | 12 | void lock(Object*) { } 13 | 14 | void unlock(Object*) { } 15 | 16 | String *java::lang::operator "" _j(const char16_t* p, size_t n) { 17 | auto x = new char16_tArray(p, n); 18 | auto s = new String(x, true); 19 | return s->intern(); 20 | } 21 | 22 | Class *class_(const char16_t *s, int n) { 23 | return Class::forName(operator "" _j(s, n)); 24 | } 25 | 26 | void unimplemented_(const char16_t *name) { 27 | std::wcerr << "call to unimplemented: "; 28 | // Not quite right but good enough ;) 29 | while(*name) std::wcerr << static_cast(*(name++)); 30 | std::wcerr << std::endl; 31 | } 32 | 33 | void init_jvm() { 34 | // This will be called by the generated main file before running any java code 35 | // Use it to initialize system properties and other stuff the JVM should provide 36 | } 37 | 38 | java::lang::StringArray* make_args(int args, char** argv) { 39 | // Helper that should convert strings passed to app into 40 | // StringArray passed to java main 41 | return nullptr; 42 | } 43 | -------------------------------------------------------------------------------- /plugin/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /plugin/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | se.arnetheduck.j2c 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.pde.PluginNature 26 | org.eclipse.jdt.core.javanature 27 | 28 | 29 | -------------------------------------------------------------------------------- /plugin/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.6 12 | -------------------------------------------------------------------------------- /plugin/.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | #Thu Jan 26 22:24:51 CET 2012 2 | eclipse.preferences.version=1 3 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 4 | -------------------------------------------------------------------------------- /plugin/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: j2c 4 | Bundle-SymbolicName: se.arnetheduck.j2c;singleton:=true 5 | Bundle-Version: 0.5.0.qualifier 6 | Bundle-Activator: se.arnetheduck.j2c.Activator 7 | Require-Bundle: org.eclipse.ui, 8 | org.eclipse.core.runtime, 9 | org.eclipse.jdt.core, 10 | org.eclipse.core.resources 11 | Bundle-ActivationPolicy: lazy 12 | Bundle-RequiredExecutionEnvironment: JavaSE-1.6 13 | Export-Package: se.arnetheduck.j2c;uses:="org.eclipse.jface.resource,org.eclipse.ui.plugin,org.osgi.framework", 14 | se.arnetheduck.j2c.handlers;uses:="org.eclipse.jdt.core,org.eclipse.core.commands", 15 | se.arnetheduck.j2c.resources, 16 | se.arnetheduck.j2c.snippets;uses:="org.eclipse.jdt.core.dom,se.arnetheduck.j2c.transform", 17 | se.arnetheduck.j2c.transform;uses:="org.eclipse.jdt.core.dom,org.eclipse.core.runtime,org.eclipse.jdt.core" 18 | -------------------------------------------------------------------------------- /plugin/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/ 2 | output.. = bin/ 3 | bin.includes = plugin.xml,\ 4 | META-INF/,\ 5 | .,\ 6 | icons/ 7 | -------------------------------------------------------------------------------- /plugin/icons/sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arnetheduck/j2c/8ab2e2f7def06a80a4275d773bb09175426ba21a/plugin/icons/sample.gif -------------------------------------------------------------------------------- /plugin/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 10 | 11 | 16 | 17 | 22 | 23 | 24 | 26 | 27 | 29 | 30 | 32 | 34 | 36 | 41 | 42 | 43 | 44 | 47 | 51 | 52 | 53 | 56 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/Activator.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c; 2 | 3 | import org.eclipse.jface.resource.ImageDescriptor; 4 | import org.eclipse.ui.plugin.AbstractUIPlugin; 5 | import org.osgi.framework.BundleContext; 6 | 7 | /** 8 | * The activator class controls the plug-in life cycle 9 | */ 10 | public class Activator extends AbstractUIPlugin { 11 | 12 | // The plug-in ID 13 | public static final String PLUGIN_ID = "se.arnetheduck.j2c"; //$NON-NLS-1$ 14 | 15 | // The shared instance 16 | private static Activator plugin; 17 | 18 | /** 19 | * The constructor 20 | */ 21 | public Activator() { 22 | } 23 | 24 | /* 25 | * (non-Javadoc) 26 | * 27 | * @see 28 | * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext 29 | * ) 30 | */ 31 | public void start(BundleContext context) throws Exception { 32 | super.start(context); 33 | plugin = this; 34 | } 35 | 36 | /* 37 | * (non-Javadoc) 38 | * 39 | * @see 40 | * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext 41 | * ) 42 | */ 43 | public void stop(BundleContext context) throws Exception { 44 | plugin = null; 45 | super.stop(context); 46 | } 47 | 48 | /** 49 | * Returns the shared instance 50 | * 51 | * @return the shared instance 52 | */ 53 | public static Activator getDefault() { 54 | return plugin; 55 | } 56 | 57 | /** 58 | * Returns an image descriptor for the image file at the given plug-in 59 | * relative path 60 | * 61 | * @param path 62 | * the path 63 | * @return the image descriptor 64 | */ 65 | public static ImageDescriptor getImageDescriptor(String path) { 66 | return imageDescriptorFromPlugin(PLUGIN_ID, path); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/handlers/HandlerHelper.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.handlers; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collection; 6 | import java.util.List; 7 | 8 | import org.eclipse.core.runtime.IPath; 9 | import org.eclipse.core.runtime.IProgressMonitor; 10 | import org.eclipse.core.runtime.IStatus; 11 | import org.eclipse.core.runtime.Status; 12 | import org.eclipse.core.runtime.jobs.Job; 13 | import org.eclipse.jdt.core.ICompilationUnit; 14 | import org.eclipse.jdt.core.IJavaElement; 15 | import org.eclipse.jdt.core.IJavaProject; 16 | import org.eclipse.jdt.core.IPackageFragment; 17 | import org.eclipse.jdt.core.IPackageFragmentRoot; 18 | import org.eclipse.jdt.core.JavaModelException; 19 | import org.eclipse.jface.dialogs.MessageDialog; 20 | import org.eclipse.ui.handlers.HandlerUtil; 21 | 22 | import se.arnetheduck.j2c.transform.Transformer; 23 | 24 | public class HandlerHelper { 25 | public static Collection units(IJavaProject project) 26 | throws JavaModelException { 27 | List units = new ArrayList(); 28 | IPackageFragment[] packages = project.getPackageFragments(); 29 | for (IPackageFragment pf : packages) { 30 | add(units, pf); 31 | } 32 | 33 | return units; 34 | } 35 | 36 | public static Collection units(IPackageFragmentRoot pfr) 37 | throws JavaModelException { 38 | List units = new ArrayList(); 39 | for (IJavaElement pf : pfr.getChildren()) { 40 | if (pf instanceof IPackageFragment) { 41 | add(units, (IPackageFragment) pf); 42 | } 43 | } 44 | 45 | return units; 46 | } 47 | 48 | public static Collection units(IPackageFragment pf) 49 | throws JavaModelException { 50 | List units = new ArrayList(); 51 | add(units, pf); 52 | return units; 53 | } 54 | 55 | public static Collection units(ICompilationUnit unit) { 56 | List units = new ArrayList(); 57 | 58 | if (unit != null) { 59 | units.add(unit); 60 | } 61 | 62 | return units; 63 | } 64 | 65 | private static void add(Collection units, 66 | IPackageFragment pf) throws JavaModelException { 67 | if (pf.getKind() == IPackageFragmentRoot.K_SOURCE) { 68 | add(units, pf.getCompilationUnits()); 69 | } 70 | } 71 | 72 | private static void add(Collection units, 73 | ICompilationUnit... u) { 74 | units.addAll(Arrays.asList(u)); 75 | } 76 | 77 | public static void process(final IJavaProject project, 78 | final Collection units) { 79 | if (units.isEmpty()) { 80 | MessageDialog.openInformation(HandlerUtil.getActiveShell(null), 81 | "No sources", "No Java source code found in selection"); 82 | return; 83 | } 84 | 85 | // We will write to the source folder prefixed with "c" 86 | final IPath p = project.getProject().getLocation() 87 | .removeLastSegments(1) 88 | .append("c" + project.getProject().getLocation().lastSegment()) 89 | .addTrailingSeparator(); 90 | 91 | if (!p.toFile().exists()) { 92 | MessageDialog.openError(null, "Output directory missing", p 93 | .toFile().getAbsolutePath() 94 | + " does not exist, create it before running plugin.!"); 95 | } else { 96 | Job job = new Job("C++ translation") { 97 | @Override 98 | protected IStatus run(IProgressMonitor monitor) { 99 | // Set total number of work units 100 | monitor.beginTask("Translating to C++", 101 | IProgressMonitor.UNKNOWN); 102 | try { 103 | Transformer t = new Transformer(project, project 104 | .getProject().getName(), p); 105 | 106 | t.process(monitor, 107 | units.toArray(new ICompilationUnit[0])); 108 | } catch (Exception e) { 109 | e.printStackTrace(); 110 | return Status.CANCEL_STATUS; 111 | } 112 | 113 | return Status.OK_STATUS; 114 | } 115 | }; 116 | 117 | job.setPriority(Job.BUILD); 118 | job.schedule(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/handlers/TestHandler.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.handlers; 2 | 3 | import java.util.Collection; 4 | 5 | import org.eclipse.core.commands.AbstractHandler; 6 | import org.eclipse.core.commands.ExecutionEvent; 7 | import org.eclipse.core.commands.ExecutionException; 8 | import org.eclipse.core.resources.IProject; 9 | import org.eclipse.core.resources.IWorkspace; 10 | import org.eclipse.core.resources.IWorkspaceRoot; 11 | import org.eclipse.core.resources.ResourcesPlugin; 12 | import org.eclipse.jdt.core.ICompilationUnit; 13 | import org.eclipse.jdt.core.IJavaProject; 14 | import org.eclipse.jdt.core.JavaCore; 15 | 16 | public class TestHandler extends AbstractHandler { 17 | 18 | @Override 19 | public Object execute(ExecutionEvent event) throws ExecutionException { 20 | IWorkspace workspace = ResourcesPlugin.getWorkspace(); 21 | IWorkspaceRoot root = workspace.getRoot(); 22 | // Get all projects in the workspace 23 | IProject[] projects = root.getProjects(); 24 | // Loop over all projects 25 | for (IProject project : projects) { 26 | try { 27 | if (!project.isOpen() 28 | || !project.isNatureEnabled(JavaCore.NATURE_ID)) { 29 | continue; 30 | } 31 | 32 | if (!project.getName().endsWith("j2c.test")) { 33 | continue; 34 | } 35 | 36 | IJavaProject jp = JavaCore.create(project); 37 | Collection units = HandlerHelper.units(jp); 38 | HandlerHelper.process(jp, units); 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/handlers/TransformHandler.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.handlers; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Iterator; 6 | 7 | import org.eclipse.core.commands.AbstractHandler; 8 | import org.eclipse.core.commands.ExecutionEvent; 9 | import org.eclipse.core.commands.ExecutionException; 10 | import org.eclipse.core.resources.IProject; 11 | import org.eclipse.jdt.core.ICompilationUnit; 12 | import org.eclipse.jdt.core.IJavaProject; 13 | import org.eclipse.jdt.core.IPackageFragment; 14 | import org.eclipse.jdt.core.IPackageFragmentRoot; 15 | import org.eclipse.jdt.core.JavaCore; 16 | import org.eclipse.jface.dialogs.MessageDialog; 17 | import org.eclipse.jface.viewers.IStructuredSelection; 18 | import org.eclipse.ui.handlers.HandlerUtil; 19 | 20 | public class TransformHandler extends AbstractHandler { 21 | public TransformHandler() { 22 | } 23 | 24 | @Override 25 | public Object execute(ExecutionEvent event) throws ExecutionException { 26 | try { 27 | IStructuredSelection selection = (IStructuredSelection) HandlerUtil 28 | .getActiveMenuSelection(event); 29 | 30 | Collection units = new ArrayList(); 31 | IJavaProject project = null; 32 | 33 | Iterator iter = selection.iterator(); 34 | while (iter.hasNext()) { 35 | Object element = iter.next(); 36 | 37 | if (element instanceof IJavaProject) { 38 | project = (IJavaProject) element; 39 | units.addAll(HandlerHelper.units(project)); 40 | } else if (element instanceof IPackageFragmentRoot) { 41 | IPackageFragmentRoot pfr = (IPackageFragmentRoot) element; 42 | project = pfr.getJavaProject(); 43 | units.addAll(HandlerHelper.units(pfr)); 44 | } else if (element instanceof IPackageFragment) { 45 | IPackageFragment pf = (IPackageFragment) element; 46 | project = pf.getJavaProject(); 47 | units.addAll(HandlerHelper.units(pf)); 48 | } else if (element instanceof ICompilationUnit) { 49 | ICompilationUnit cu = (ICompilationUnit) element; 50 | project = cu.getJavaProject(); 51 | units.addAll(HandlerHelper.units(cu)); 52 | } else if (element instanceof IProject) { 53 | IProject p = (IProject) element; 54 | if (p.isOpen() && p.hasNature(JavaCore.NATURE_ID)) { 55 | project = JavaCore.create(p); 56 | units.addAll(HandlerHelper.units(project)); 57 | } 58 | } 59 | } 60 | 61 | if (project != null && units != null) { 62 | HandlerHelper.process(project, units); 63 | } else { 64 | MessageDialog.openInformation( 65 | HandlerUtil.getActiveShell(event), "Invalid selection", 66 | "Please select a Java project, package or source file"); 67 | } 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | MessageDialog.openError(HandlerUtil.getActiveShell(event), 71 | "Error processing selection", e.getMessage()); 72 | } 73 | 74 | return null; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/Array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | extern java::lang::Class *class_(const char16_t *c, int n); 11 | 12 | template 13 | class Array 14 | : public virtual ::java::lang::Object 15 | , public ::java::lang::Cloneable 16 | , public ::java::io::Serializable 17 | { 18 | public: 19 | static ::java::lang::Class *class_(); 20 | 21 | typedef T value_type; 22 | typedef value_type *pointer_type; 23 | typedef pointer_type iterator; 24 | typedef const value_type *const_pointer_type; 25 | typedef const_pointer_type const_iterator; 26 | 27 | typedef int size_type; 28 | 29 | Array() : length(0), p(nullptr) { } 30 | Array(int n) : length(n), p(n == 0 ? nullptr : new value_type[n]) 31 | { 32 | for(auto x = p; x != p + length; ++x) *x = value_type(); 33 | } 34 | 35 | Array(const value_type *values, int n) : length(n), p(new value_type[n]) 36 | { 37 | auto x = p; 38 | for(auto v = values; v != values + n; ++v) *x++ = *v; 39 | } 40 | 41 | template 42 | Array(std::initializer_list l) : length(l.size()), p(new value_type[l.size()]) 43 | { 44 | auto x = p; 45 | for(auto v : l) *x++ = v; 46 | } 47 | 48 | Array(const Array &rhs) : Array(rhs.p, rhs.length) { } 49 | 50 | Array(Array &&rhs) : length(rhs.length), p(rhs.p) 51 | { 52 | const_cast(rhs.p) = 0; 53 | } 54 | 55 | Array &operator=(const Array &rhs) 56 | { 57 | if(&rhs != this) { 58 | if(length != rhs.length) { 59 | delete p; 60 | const_cast(p) = 0; 61 | const_cast(length) = rhs.length; 62 | const_cast(p) = new value_type[length]; 63 | } 64 | 65 | auto x = p; 66 | for(auto v = rhs.p; v != rhs.p + rhs.length; ++v) *x++ = *v; 67 | } 68 | 69 | return *this; 70 | } 71 | 72 | Array &operator=(Array &&rhs) 73 | { 74 | if(&rhs != this) { 75 | delete p; 76 | const_cast(length) = rhs.length; 77 | const_cast(p) = rhs.p; 78 | const_cast(rhs.p) = 0; 79 | } 80 | 81 | return *this; 82 | } 83 | 84 | virtual ~Array() { delete p; } 85 | 86 | Array* clone() override { return new Array(*this); } 87 | 88 | value_type operator[](size_type i) const { return p[i]; } 89 | value_type &operator[](size_type i) { return p[i]; } 90 | 91 | value_type get(size_type i) const { return p[i]; } 92 | value_type &set(size_type i, value_type x) { return (p[i] = x); } 93 | 94 | iterator begin() { return p; } 95 | const_iterator begin() const { return p; } 96 | const_iterator cbegin() const { return begin(); } 97 | 98 | iterator end() { return p + length; } 99 | const_iterator end() const { return p + length; } 100 | const_iterator cend() const { return end(); } 101 | 102 | const size_type length; 103 | const pointer_type p; 104 | 105 | private: 106 | ::java::lang::Class *getClass0() override { return class_(); } 107 | }; 108 | 109 | typedef Array boolArray; 110 | typedef Array char16_tArray; 111 | typedef Array int8_tArray; 112 | typedef Array int16_tArray; 113 | typedef Array int32_tArray; 114 | typedef Array int64_tArray; 115 | typedef Array doubleArray; 116 | typedef Array floatArray; 117 | 118 | template<> 119 | inline java::lang::Class* boolArray::class_() { 120 | static ::java::lang::Class* c = ::class_(u"boolean[]", 9); 121 | return c; 122 | } 123 | template<> 124 | inline java::lang::Class* char16_tArray::class_() { 125 | static ::java::lang::Class* c = ::class_(u"char[]", 9); 126 | return c; 127 | } 128 | template<> 129 | inline java::lang::Class* int8_tArray::class_() { 130 | static ::java::lang::Class* c = ::class_(u"byte[]", 9); 131 | return c; 132 | } 133 | template<> 134 | inline java::lang::Class* int16_tArray::class_() { 135 | static ::java::lang::Class* c = ::class_(u"short[]", 9); 136 | return c; 137 | } 138 | template<> 139 | inline java::lang::Class* int32_tArray::class_() { 140 | static ::java::lang::Class* c = ::class_(u"int[]", 9); 141 | return c; 142 | } 143 | template<> 144 | inline java::lang::Class* int64_tArray::class_() { 145 | static ::java::lang::Class* c = ::class_(u"long[]", 9); 146 | return c; 147 | } 148 | template<> 149 | inline java::lang::Class* doubleArray::class_() { 150 | static ::java::lang::Class* c = ::class_(u"double[]", 9); 151 | return c; 152 | } 153 | template<> 154 | inline java::lang::Class* floatArray::class_() { 155 | static ::java::lang::Class* c = ::class_(u"float[]", 9); 156 | return c; 157 | } 158 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/Main.cpp.tmpl: -------------------------------------------------------------------------------- 1 | %1$s 2 | 3 | extern void init_jvm(); 4 | extern java::lang::StringArray* make_args(int args, char** argv); 5 | 6 | int main(int argc, char** argv) 7 | { 8 | init_jvm(); 9 | 10 | %2$s::main(make_args(argc, argv)); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/Makefile.tmpl: -------------------------------------------------------------------------------- 1 | INCLUDES := $(INCLUDES) -Isrc -Iext/src 2 | EXTRA_LIBS ?= -l$(NAME)-ext 3 | 4 | CPPFLAGS := $(CPPFLAGS) $(INCLUDES) 5 | CFLAGS := $(CFLAGS) -g -pipe -MMD -MP 6 | CXXFLAGS := $(CFLAGS) -std=gnu++11 7 | 8 | BIN := bin 9 | OBJ := obj 10 | 11 | NAME := %1$s 12 | 13 | LIB = lib$(NAME).a 14 | EXT_LIB = lib$(NAME)-ext.a 15 | 16 | LIBS = $(BIN)/$(LIB) $(BIN)/$(EXT_LIB) 17 | 18 | SRC = src 19 | STUB = stub 20 | NATIVE = native 21 | 22 | SRCS = \ 23 | %2$s 24 | 25 | STUB_SRCS = \ 26 | %3$s 27 | 28 | NATIVE_SRCS = \ 29 | %4$s 30 | 31 | EXT_SRCS = \ 32 | %5$s 33 | 34 | EXT_STUB_SRCS = \ 35 | %6$s 36 | 37 | EXT_NATIVE_SRCS = \ 38 | %7$s 39 | 40 | MAIN_SRCS = \ 41 | %8$s 42 | 43 | MAINS = $(MAIN_SRCS:$(SRC)/%%-main.cpp=$(BIN)/%%) 44 | OBJS = $(SRCS:$(SRC)/%%.cpp=$(OBJ)/%%.o) 45 | STUB_OBJS = $(STUB_SRCS:$(STUB)/%%.cpp=$(OBJ)/%%.o) 46 | NATIVE_OBJS = $(NATIVE_SRCS:$(NATIVE)/%%.cpp=$(OBJ)/%%.o) 47 | 48 | EXT_OBJS = $(EXT_SRCS:ext/$(SRC)/%%.cpp=$(OBJ)/%%.o) 49 | EXT_STUB_OBJS = $(EXT_STUB_SRCS:ext/$(STUB)/%%.cpp=$(OBJ)/%%.o) 50 | EXT_NATIVE_OBJS = $(EXT_NATIVE_SRCS:ext/$(NATIVE)/%%.cpp=$(OBJ)/%%.o) 51 | 52 | all: $(LIBS) 53 | 54 | define cc-command 55 | @mkdir -p $(dir $@); 56 | @echo Compile $<; $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< 57 | endef 58 | 59 | $(OBJS):$(OBJ)/%%.o: $(SRC)/%%.cpp | print-opts 60 | $(cc-command) 61 | 62 | $(STUB_OBJS):$(OBJ)/%%.o: $(STUB)/%%.cpp | print-opts 63 | $(cc-command) 64 | 65 | $(NATIVE_OBJS):$(OBJ)/%%.o: $(NATIVE)/%%.cpp | print-opts 66 | $(cc-command) 67 | 68 | $(EXT_OBJS):$(OBJ)/%%.o: ext/$(SRC)/%%.cpp | print-opts 69 | $(cc-command) 70 | 71 | $(EXT_STUB_OBJS):$(OBJ)/%%.o: ext/$(STUB)/%%.cpp | print-opts 72 | $(cc-command) 73 | 74 | $(EXT_NATIVE_OBJS):$(OBJ)/%%.o: ext/$(NATIVE)/%%.cpp | print-opts 75 | $(cc-command) 76 | 77 | %%.a: 78 | @echo Archive $@ 79 | @mkdir -p $(dir $@) 80 | @rm -f $@ 81 | @ar rcs $@ $^ 82 | 83 | $(BIN)/$(LIB): $(OBJS) $(STUB_OBJS) $(NATIVE_OBJS) 84 | 85 | $(BIN)/$(EXT_LIB): $(EXT_OBJS) $(EXT_STUB_OBJS) $(EXT_NATIVE_OBJS) 86 | 87 | $(MAINS):$(BIN)/%%:$(SRC)/%%-main.cpp $(LIBS) 88 | @mkdir -p $(dir $@); 89 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -L$(BIN) -o $@ $< -l$(NAME) $(EXTRA_LIBS) 90 | 91 | mains: $(MAINS) 92 | 93 | clean: 94 | rm -rf $(OBJ) $(BIN) 95 | 96 | print-opts: 97 | @echo Building with \"$(CXX) $(CPPFLAGS) $(CXXFLAGS)\" 98 | 99 | .PHONY: all mains clean print-opts 100 | 101 | -include $(OBJS:%%.o=%%.d) 102 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/ObjectArray.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace java 11 | { 12 | namespace lang 13 | { 14 | class ObjectArray; 15 | } 16 | } 17 | 18 | extern java::lang::Class *class_(const char16_t *c, int n); 19 | 20 | class java::lang::ObjectArray 21 | : public virtual ::java::lang::Object 22 | , public virtual ::java::lang::Cloneable 23 | , public virtual ::java::io::Serializable 24 | { 25 | public: 26 | static ::java::lang::Class *class_() { 27 | static ::java::lang::Class* c = ::class_(u"java.lang.Object[]", 31); 28 | return c; 29 | } 30 | 31 | typedef ::java::lang::Object super; 32 | 33 | typedef Object *value_type; 34 | typedef value_type *pointer_type; 35 | typedef pointer_type iterator; 36 | typedef const value_type *const_pointer_type; 37 | typedef const_pointer_type const_iterator; 38 | 39 | typedef int size_type; 40 | 41 | ObjectArray() : length(0), p(nullptr) { } 42 | ObjectArray(int n) : length(n), p(n == 0 ? nullptr : new value_type[n]) 43 | { 44 | for(auto x = p; x != p + length; ++x) *x = value_type(); 45 | } 46 | 47 | ObjectArray(const value_type *values, int n) : length(n), p(new value_type[n]) 48 | { 49 | auto x = p; 50 | for(auto v = values; v != values + n; ++v) *x++ = *v; 51 | } 52 | 53 | template 54 | ObjectArray(std::initializer_list l) : length(l.size()), p(new value_type[l.size()]) 55 | { 56 | auto x = p; 57 | for(auto v : l) *x++ = v; 58 | } 59 | 60 | ObjectArray(const ObjectArray &rhs) : ObjectArray(rhs.p, rhs.length) 61 | { 62 | } 63 | 64 | ObjectArray(ObjectArray &&rhs) : length(rhs.length), p(rhs.p) 65 | { 66 | const_cast(rhs.p) = 0; 67 | } 68 | 69 | ObjectArray &operator=(const ObjectArray &rhs) 70 | { 71 | if(&rhs != this) { 72 | if(length != rhs.length) { 73 | delete p; 74 | const_cast(p) = 0; 75 | const_cast(length) = rhs.length; 76 | const_cast(p) = new value_type[length]; 77 | } 78 | 79 | auto x = p; 80 | for(auto v = rhs.p; v != rhs.p + rhs.length; ++v) *x++ = *v; 81 | } 82 | 83 | return *this; 84 | } 85 | 86 | ObjectArray &operator=(ObjectArray &&rhs) 87 | { 88 | if(&rhs != this) { 89 | delete p; 90 | const_cast(length) = rhs.length; 91 | const_cast(p) = rhs.p; 92 | const_cast(rhs.p) = 0; 93 | } 94 | 95 | return *this; 96 | } 97 | 98 | virtual ~ObjectArray() { delete p; } 99 | 100 | ObjectArray* clone() override { return new ObjectArray(*this); } 101 | 102 | value_type operator[](size_type i) const { return get(i); } 103 | value_type get(size_type i) const { return p[i]; } 104 | 105 | template 106 | T set(size_type i, T x) { set0(i, x); return x; } 107 | 108 | iterator begin() { return p; } 109 | const_iterator begin() const { return p; } 110 | const_iterator cbegin() const { return begin(); } 111 | 112 | iterator end() { return p + length; } 113 | const_iterator end() const { return p + length; } 114 | const_iterator cend() const { return end(); } 115 | 116 | const size_type length; 117 | const pointer_type p; 118 | 119 | private: 120 | ::java::lang::Class *getClass0() override { return class_(); } 121 | 122 | virtual void set0(size_type i, Object *x) { p[i] = x; } 123 | }; 124 | 125 | template 126 | ArrayType* __newMultiArray(int dim) { 127 | return new ArrayType(dim); 128 | } 129 | 130 | template 131 | ArrayType* __newMultiArray(int dim, Dims... dims) { 132 | auto ret = new ArrayType(dim); 133 | for (auto i = 0; i < dim; ++i) { 134 | ret->p[i] = __newMultiArray::type>(dims...); 135 | } 136 | return ret; 137 | } 138 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/SubArray.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | template 10 | struct SubArray : public virtual Bases... { 11 | static ::java::lang::Class *class_() { 12 | static ::java::lang::Class* c = ::class_(u"TODO[]", 31); 13 | return c; 14 | } 15 | 16 | typedef ComponentType* value_type; 17 | typedef int size_type; 18 | 19 | struct iterator { 20 | typedef SubArray::value_type value_type; 21 | typedef std::ptrdiff_t difference_type; 22 | typedef value_type* pointer; 23 | typedef value_type reference; // Good enough for input iterator 24 | typedef std::input_iterator_tag iterator_category; 25 | 26 | iterator() : p() {} 27 | explicit iterator(::java::lang::Object** p) : p(p) {} 28 | 29 | pointer operator->() { return &dynamic_cast(*p); } 30 | reference operator*() { return dynamic_cast(*p); } 31 | 32 | iterator& operator++() { ++p; return *this; } 33 | iterator operator++(int) { iterator tmp(p); ++*this; return tmp; } 34 | iterator& operator--() { --p; return *this; } 35 | iterator operator--(int) { iterator tmp(p); --*this; return tmp; } 36 | 37 | bool operator==(iterator rhs) { return p == rhs.p; } 38 | bool operator!=(iterator rhs) { return !(*this == rhs); } 39 | 40 | ::java::lang::Object** p; 41 | }; 42 | 43 | SubArray() { } 44 | SubArray(int n) : ::java::lang::ObjectArray(n) { } 45 | 46 | SubArray(const value_type *values, int n) : ::java::lang::ObjectArray(n) 47 | { 48 | auto x = this->p; 49 | for(auto v = values; v != values + n; ++v) *x++ = *v; 50 | } 51 | 52 | template 53 | SubArray(std::initializer_list l) : ::java::lang::ObjectArray(l.size()) 54 | { 55 | auto x = this->p; 56 | for(auto v : l) *x++ = v; 57 | } 58 | 59 | SubArray(const SubArray &rhs) : ::java::lang::ObjectArray(rhs) { } 60 | SubArray(SubArray &&rhs) : ::java::lang::ObjectArray(std::move(rhs)) { } 61 | virtual ~SubArray() {} 62 | 63 | SubArray &operator=(const SubArray &rhs) 64 | { 65 | ::java::lang::ObjectArray::operator=(rhs); 66 | return *this; 67 | } 68 | 69 | SubArray &operator=(SubArray &&rhs) 70 | { 71 | ::java::lang::ObjectArray::operator=(std::move(rhs)); 72 | return *this; 73 | } 74 | 75 | SubArray* clone() override { return new SubArray(*this); } 76 | 77 | value_type operator[](size_type i) const { return get(i); } 78 | value_type get(size_type i) const { return dynamic_cast(this->p[i]); } 79 | 80 | iterator begin() { return iterator(this->p); } 81 | iterator end() { return iterator(this->p + this->length); } 82 | 83 | private: 84 | ::java::lang::Class *getClass0() override { return class_(); } 85 | 86 | void set0(size_type i, ::java::lang::Object *x) override 87 | { 88 | if(x && !dynamic_cast(x)) { 89 | throw new ::java::lang::ArrayStoreException(); 90 | } 91 | 92 | this->p[i] = x; 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/finally.hpp: -------------------------------------------------------------------------------- 1 | namespace 2 | { 3 | template 4 | struct finally_ 5 | { 6 | finally_(F f) : f(f), moved(false) { } 7 | finally_(finally_ &&x) : f(x.f), moved(false) { x.moved = true; } 8 | ~finally_() { if(!moved) f(); } 9 | private: 10 | finally_(const finally_&); finally_& operator=(const finally_&); 11 | F f; 12 | bool moved; 13 | }; 14 | 15 | template finally_ finally(F f) { return finally_(f); } 16 | } 17 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/java_cast.hpp: -------------------------------------------------------------------------------- 1 | template 2 | static T java_cast(U* u) 3 | { 4 | if(!u) return static_cast(nullptr); 5 | auto t = dynamic_cast(u); 6 | if(!t) throw new ::java::lang::ClassCastException(); 7 | return t; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/npc.hpp: -------------------------------------------------------------------------------- 1 | template 2 | static T* npc(T* t) 3 | { 4 | if(!t) throw new ::java::lang::NullPointerException(); 5 | return t; 6 | } 7 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/resources/synchronized.hpp: -------------------------------------------------------------------------------- 1 | extern void lock(::java::lang::Object *); 2 | extern void unlock(::java::lang::Object *); 3 | 4 | namespace 5 | { 6 | struct synchronized 7 | { 8 | synchronized(::java::lang::Object *o) : o(o) { ::lock(o); } 9 | ~synchronized() { ::unlock(o); } 10 | private: 11 | synchronized(const synchronized&); synchronized& operator=(const synchronized&); 12 | ::java::lang::Object *o; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/snippets/GetSetSnippet.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.snippets; 2 | 3 | import org.eclipse.jdt.core.dom.IMethodBinding; 4 | import org.eclipse.jdt.core.dom.ITypeBinding; 5 | import org.eclipse.jdt.core.dom.IVariableBinding; 6 | 7 | import se.arnetheduck.j2c.transform.CName; 8 | import se.arnetheduck.j2c.transform.EmptySnippet; 9 | import se.arnetheduck.j2c.transform.StubWriter; 10 | import se.arnetheduck.j2c.transform.TransformUtil; 11 | import se.arnetheduck.j2c.transform.Transformer; 12 | 13 | public class GetSetSnippet extends EmptySnippet { 14 | 15 | @Override 16 | public boolean body(Transformer ctx, StubWriter w, IMethodBinding mb) { 17 | String name = mb.getName(); 18 | if (name.length() < 4) 19 | return true; 20 | 21 | boolean getter = name.startsWith("get"); 22 | boolean setter = name.startsWith("set"); 23 | if (!getter && !setter) 24 | return true; 25 | 26 | char[] vname = name.substring(3).toCharArray(); 27 | vname[0] = Character.toLowerCase(vname[0]); 28 | ITypeBinding tb = mb.getDeclaringClass(); 29 | if (tb == null) 30 | return true; 31 | 32 | String v = new String(vname); 33 | boolean ms = TransformUtil.isStatic(mb); 34 | 35 | for (IVariableBinding vb : tb.getDeclaredFields()) { 36 | if (ms == TransformUtil.isStatic(vb) && vb.getName().equals(v)) { 37 | boolean asMethod = TransformUtil.asMethod(vb); 38 | if (getter 39 | && mb.getReturnType().isAssignmentCompatible( 40 | vb.getType())) { 41 | w.println("return " + CName.of(vb) + (asMethod ? "()" : "") 42 | + " ; /* getter */"); 43 | } else if (setter 44 | && mb.getReturnType().getName().equals("void") 45 | && mb.getParameterTypes().length == 1 46 | && vb.getType().isAssignmentCompatible( 47 | mb.getParameterTypes()[0])) { 48 | w.print(TransformUtil.indent(1)); 49 | if (ms) { 50 | w.print(CName.of(tb) + "::"); 51 | } else { 52 | w.print("this->"); 53 | } 54 | 55 | w.println(CName.of(vb) + (asMethod ? "()" : "") + " = " 56 | + TransformUtil.paramName(mb, 0) + "; /* setter */"); 57 | } 58 | 59 | return false; 60 | } 61 | } 62 | 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/snippets/ReplaceInvocation.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.snippets; 2 | 3 | import org.eclipse.jdt.core.dom.ASTNode; 4 | import org.eclipse.jdt.core.dom.IMethodBinding; 5 | import org.eclipse.jdt.core.dom.ITypeBinding; 6 | import org.eclipse.jdt.core.dom.MethodInvocation; 7 | import org.eclipse.jdt.core.dom.TypeLiteral; 8 | 9 | import se.arnetheduck.j2c.transform.CName; 10 | import se.arnetheduck.j2c.transform.EmptySnippet; 11 | import se.arnetheduck.j2c.transform.ImplWriter; 12 | import se.arnetheduck.j2c.transform.Transformer; 13 | 14 | public class ReplaceInvocation extends EmptySnippet { 15 | 16 | @Override 17 | public boolean node(Transformer ctx, ImplWriter w, ASTNode node) { 18 | if (node instanceof MethodInvocation) { 19 | return replace(w, (MethodInvocation) node); 20 | } 21 | 22 | return super.node(ctx, w, node); 23 | } 24 | 25 | private static boolean replace(ImplWriter w, MethodInvocation node) { 26 | if (replaceEnsureClassInitialized(w, node)) { 27 | return false; 28 | } 29 | 30 | return true; 31 | } 32 | 33 | private static boolean replaceEnsureClassInitialized(ImplWriter w, 34 | MethodInvocation node) { 35 | if (!node.getName().getIdentifier().equals("ensureClassInitialized")) { 36 | return false; 37 | } 38 | 39 | if (node.arguments().size() != 1 40 | || !(node.arguments().get(0) instanceof TypeLiteral)) { 41 | return false; 42 | } 43 | 44 | IMethodBinding mb = node.resolveMethodBinding(); 45 | if (!mb.getDeclaringClass().getQualifiedName() 46 | .equals("sun.misc.Unsafe")) { 47 | return false; 48 | } 49 | 50 | TypeLiteral tl = (TypeLiteral) node.arguments().get(0); 51 | ITypeBinding tb = tl.getType().resolveBinding(); 52 | w.hardDep(tb); 53 | w.print(CName.relative(tb, w.type, true) + "::clinit()"); 54 | 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/BindingComparator.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.util.Comparator; 4 | 5 | import org.eclipse.jdt.core.dom.IBinding; 6 | 7 | public final class BindingComparator implements Comparator { 8 | @Override 9 | public int compare(IBinding o1, IBinding o2) { 10 | return o1.getKey().compareTo(o2.getKey()); 11 | } 12 | } -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/DepInfo.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.Serializable; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.Set; 9 | import java.util.Stack; 10 | import java.util.TreeSet; 11 | 12 | import org.eclipse.jdt.core.dom.ITypeBinding; 13 | 14 | public class DepInfo { 15 | private final Transformer ctx; 16 | 17 | private final Set hardDeps = new TreeSet( 18 | new BindingComparator()); 19 | private final Set softDeps = new TreeSet( 20 | new BindingComparator()); 21 | 22 | private boolean javaCast; 23 | private boolean npc; 24 | private boolean atomic; 25 | 26 | private boolean finally_; 27 | 28 | private boolean synchronized_; 29 | private boolean fmod; 30 | 31 | public DepInfo(Transformer ctx) { 32 | this.ctx = ctx; 33 | } 34 | 35 | /** Soft dependency, forward declaration sufficient */ 36 | public void soft(ITypeBinding dep) { 37 | if (TransformUtil.addDep(dep, softDeps)) { 38 | ctx.softDep(dep); 39 | } 40 | 41 | checkArray(dep, false); 42 | } 43 | 44 | /** Hard dependency, class declaration required */ 45 | public void hard(ITypeBinding dep) { 46 | if (TransformUtil.addDep(dep, hardDeps)) { 47 | ctx.hardDep(dep); 48 | soft(dep); 49 | } 50 | 51 | checkArray(dep, true); 52 | } 53 | 54 | private void checkArray(ITypeBinding dep, boolean hard) { 55 | if (!dep.isArray()) 56 | return; 57 | 58 | ITypeBinding ct = dep.getComponentType(); 59 | if (ct.isPrimitive()) 60 | return; 61 | 62 | if (TransformUtil.same(ct, Object.class)) 63 | return; 64 | 65 | if (hard) { 66 | hard(ct); 67 | } else { 68 | soft(ct); 69 | } 70 | 71 | List bases = arrayBases(ct); 72 | for (ITypeBinding base : bases) { 73 | if (hard) { 74 | hard(base); 75 | } else { 76 | soft(base); 77 | } 78 | } 79 | 80 | if (hard) { 81 | hard(ctx.resolve(ArrayStoreException.class)); 82 | } 83 | } 84 | 85 | public Set getHardDeps() { 86 | return hardDeps; 87 | } 88 | 89 | public Set getSoftDeps() { 90 | return softDeps; 91 | } 92 | 93 | public boolean needsJavaCast() { 94 | return javaCast; 95 | } 96 | 97 | public void setJavaCast() { 98 | javaCast = true; 99 | hard(ctx.resolve(ClassCastException.class)); 100 | } 101 | 102 | public boolean needsNpc() { 103 | return npc; 104 | } 105 | 106 | public void setNpc() { 107 | npc = true; 108 | hard(ctx.resolve(NullPointerException.class)); 109 | } 110 | 111 | public boolean needsAtomic() { 112 | return atomic; 113 | } 114 | 115 | public void setNeedsAtomic() { 116 | atomic = true; 117 | } 118 | 119 | public boolean needsFinally() { 120 | return finally_; 121 | } 122 | 123 | public void setNeedsFinally() { 124 | finally_ = true; 125 | } 126 | 127 | public boolean needsSynchronized() { 128 | return synchronized_; 129 | } 130 | 131 | public void setNeedsSynchronized() { 132 | synchronized_ = true; 133 | } 134 | 135 | public boolean needsFmod() { 136 | return fmod; 137 | } 138 | 139 | public void setNeedsFmod() { 140 | fmod = true; 141 | } 142 | 143 | public void printArrays(PrintWriter out) { 144 | Set done = new TreeSet( 145 | new BindingComparator()); 146 | 147 | boolean printed = false; 148 | Stack cur = new Stack(); 149 | for (ITypeBinding dep : softDeps) { 150 | printed |= printArray(out, dep, done, cur); 151 | } 152 | 153 | TransformUtil.setNs(out, new ArrayList(), cur); 154 | if (printed) { 155 | out.println(); 156 | } 157 | } 158 | 159 | private boolean printArray(PrintWriter out, ITypeBinding dep, 160 | Set done, Stack cur) { 161 | dep = dep.getErasure(); 162 | 163 | if (done.contains(dep)) 164 | return false; 165 | 166 | if (!dep.isArray()) 167 | return false; 168 | 169 | ITypeBinding ct = dep.getComponentType(); 170 | if (ct.isPrimitive() || TransformUtil.same(ct, Object.class)) 171 | return false; 172 | 173 | printArray(out, ct, done, cur); 174 | 175 | List bases = arrayBases(ct); 176 | for (ITypeBinding base : bases) { 177 | printArray(out, base, done, cur); 178 | } 179 | 180 | if (done.isEmpty()) { 181 | out.print("template struct SubArray;"); 182 | } 183 | 184 | TransformUtil.setNs(out, 185 | Arrays.asList(CName.packageOf(ct).split("\\.")), cur); 186 | 187 | out.print("typedef ::SubArray< " + CName.qualified(ct, true)); 188 | 189 | for (ITypeBinding base : bases) { 190 | out.print(", " + CName.relative(base, ct, true)); 191 | } 192 | 193 | out.println(" > " + CName.of(dep) + ";"); 194 | 195 | done.add(dep); 196 | 197 | return true; 198 | } 199 | 200 | private List arrayBases(ITypeBinding ct) { 201 | List ret = new ArrayList(); 202 | if (ct.isArray()) { 203 | ret.add(ctx.resolve(Cloneable.class).createArrayType(1)); 204 | ret.add(ctx.resolve(Serializable.class).createArrayType(1)); 205 | return ret; 206 | } 207 | 208 | if (ct.getSuperclass() == null) { 209 | ret.add(ctx.resolve(Object.class).createArrayType(1)); 210 | } else { 211 | ret.add(ct.getSuperclass().createArrayType(1)); 212 | } 213 | 214 | for (ITypeBinding cti : ct.getInterfaces()) { 215 | ret.add(cti.createArrayType(1)); 216 | } 217 | 218 | return ret; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/EmptySnippet.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import org.eclipse.jdt.core.dom.ASTNode; 4 | import org.eclipse.jdt.core.dom.IMethodBinding; 5 | import org.eclipse.jdt.core.dom.ITypeBinding; 6 | import org.eclipse.jdt.core.dom.IVariableBinding; 7 | 8 | public class EmptySnippet implements Snippet { 9 | @Override 10 | public boolean node(Transformer ctx, HeaderWriter w, ASTNode node) { 11 | return true; 12 | } 13 | 14 | @Override 15 | public boolean node(Transformer ctx, ImplWriter w, ASTNode node) { 16 | return true; 17 | } 18 | 19 | @Override 20 | public boolean type(Transformer ctx, TypeBindingHeaderWriter w, 21 | ITypeBinding tb) { 22 | return true; 23 | } 24 | 25 | @Override 26 | public boolean field(Transformer ctx, TypeBindingHeaderWriter w, 27 | IVariableBinding vb) { 28 | return true; 29 | } 30 | 31 | @Override 32 | public boolean method(Transformer ctx, TypeBindingHeaderWriter w, 33 | IMethodBinding mb) { 34 | return true; 35 | } 36 | 37 | @Override 38 | public boolean prefix(Transformer ctx, StubWriter w, boolean natives) { 39 | return true; 40 | } 41 | 42 | @Override 43 | public boolean suffix(Transformer ctx, StubWriter w, boolean natives) { 44 | return true; 45 | } 46 | 47 | @Override 48 | public boolean field(Transformer ctx, StubWriter w, IVariableBinding vb) { 49 | return true; 50 | } 51 | 52 | @Override 53 | public boolean method(Transformer ctx, StubWriter w, IMethodBinding mb) { 54 | return true; 55 | } 56 | 57 | @Override 58 | public boolean body(Transformer ctx, StubWriter w, IMethodBinding mb) { 59 | return true; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/FileUtil.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | import java.io.PrintWriter; 11 | import java.util.Scanner; 12 | 13 | public class FileUtil { 14 | public static void copy(File source, File target) throws IOException { 15 | InputStream is = null; 16 | OutputStream os = null; 17 | byte[] buf = new byte[4096]; 18 | try { 19 | is = new FileInputStream(source); 20 | try { 21 | os = new FileOutputStream(target); 22 | for (int n = is.read(buf); n != -1; n = is.read(buf)) { 23 | os.write(buf, 0, n); 24 | } 25 | } finally { 26 | is.close(); 27 | } 28 | } finally { 29 | if (os != null) { 30 | os.close(); 31 | } 32 | } 33 | } 34 | 35 | public static String readResource(String resource) { 36 | InputStream is = null; 37 | try { 38 | is = FileUtil.class.getResourceAsStream(resource); 39 | return FileUtil.read(is); 40 | } catch (Exception e) { 41 | throw new RuntimeException(e); 42 | } finally { 43 | if (is != null) { 44 | try { 45 | is.close(); 46 | } catch (IOException e) { 47 | throw new RuntimeException(e); 48 | } 49 | } 50 | } 51 | } 52 | 53 | private static String read(InputStream resource) { 54 | return new Scanner(resource).useDelimiter("\\A").next(); 55 | } 56 | 57 | public static PrintWriter open(File target) throws FileNotFoundException { 58 | if (!target.getParentFile().exists()) { 59 | target.getParentFile().mkdirs(); 60 | } 61 | 62 | FileOutputStream fos = new FileOutputStream(target); 63 | return new PrintWriter(fos); 64 | } 65 | 66 | public static void writeResource(String name, File target) 67 | throws IOException { 68 | InputStream is = null; 69 | try { 70 | is = FileUtil.class.getResourceAsStream(name); 71 | writeResource(is, target); 72 | } finally { 73 | if (is != null) { 74 | is.close(); 75 | } 76 | } 77 | } 78 | 79 | private static void writeResource(InputStream resource, File target) 80 | throws IOException { 81 | PrintWriter pw = null; 82 | String txt = FileUtil.read(resource); 83 | 84 | try { 85 | pw = open(target); 86 | pw.write(txt); 87 | } finally { 88 | if (pw != null) { 89 | pw.close(); 90 | } 91 | } 92 | } 93 | 94 | public static void writeTemplate(String resource, File target, 95 | Object... params) throws IOException { 96 | InputStream is = null; 97 | try { 98 | is = FileUtil.class.getResourceAsStream(resource); 99 | writeTemplate(is, target, params); 100 | } finally { 101 | if (is != null) { 102 | is.close(); 103 | } 104 | } 105 | } 106 | 107 | private static void writeTemplate(InputStream template, File target, 108 | Object... params) throws IOException { 109 | String format = read(template); 110 | 111 | PrintWriter pw = null; 112 | try { 113 | pw = open(target); 114 | pw.format(format, params); 115 | } finally { 116 | if (pw != null) { 117 | pw.close(); 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/ForwardWriter.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Stack; 11 | import java.util.TreeSet; 12 | 13 | import org.eclipse.core.runtime.IPath; 14 | import org.eclipse.jdt.core.dom.ITypeBinding; 15 | 16 | public class ForwardWriter { 17 | public static class Info implements Comparable { 18 | public String packageName; 19 | public String className; 20 | public boolean isInterface; 21 | public boolean isPrimitive; 22 | public boolean isPrimitiveArray; 23 | 24 | public Info(ITypeBinding tb) { 25 | isInterface = tb.isInterface(); 26 | isPrimitive = tb.isPrimitive(); 27 | isPrimitiveArray = TransformUtil.isPrimitiveArray(tb); 28 | 29 | packageName = CName.packageOf(tb); 30 | className = CName.of(isPrimitiveArray ? tb.getComponentType() : tb); 31 | } 32 | 33 | @Override 34 | public int compareTo(Info o) { 35 | int c = packageName.compareTo(o.packageName); 36 | c = c == 0 ? -Boolean.valueOf(isPrimitive).compareTo(o.isPrimitive) 37 | : c; 38 | return c == 0 ? className.compareTo(o.className) : c; 39 | } 40 | } 41 | 42 | private final IPath root; 43 | 44 | private Stack cur = new Stack(); 45 | 46 | private final Transformer ctx; 47 | 48 | public ForwardWriter(Transformer ctx, IPath root) { 49 | this.ctx = ctx; 50 | this.root = root; 51 | } 52 | 53 | public void write(Collection infos) throws IOException { 54 | Map> types = new HashMap>(); 55 | for (Info info : infos) { 56 | TreeSet l = types.get(info.packageName); 57 | if (l == null) { 58 | types.put(info.packageName, l = new TreeSet()); 59 | } 60 | 61 | l.add(info); 62 | } 63 | 64 | for (Map.Entry> e : types.entrySet()) { 65 | boolean hasArray = false; 66 | boolean hasPrimitive = false; 67 | 68 | PrintWriter pw = null; 69 | try { 70 | pw = FileUtil.open(root 71 | .append("src") 72 | .append(TransformUtil.packageHeader(ctx.getName(), 73 | e.getKey())).toFile()); 74 | 75 | pw.println("// Forward declarations for " + e.getKey()); 76 | 77 | pw.println("#pragma once"); 78 | pw.println(); 79 | 80 | TransformUtil.setNs(pw, 81 | e.getKey().length() == 0 ? new ArrayList() 82 | : Arrays.asList(e.getKey().split("\\.")), cur); 83 | 84 | String i = TransformUtil.indent(cur.size()); 85 | for (Info info : e.getValue()) { 86 | if (info.isPrimitive) { 87 | if (!hasPrimitive) { 88 | pw.println("#include "); 89 | pw.println("#include "); 90 | pw.println(); 91 | 92 | hasPrimitive = true; 93 | } 94 | 95 | continue; 96 | } 97 | 98 | if (info.isPrimitiveArray) { 99 | if (!hasArray) { 100 | pw.println(i + "template class Array;"); 101 | hasArray = true; 102 | } 103 | 104 | pw.format("%stypedef Array<%2$s> %2$sArray;\n", i, 105 | info.className); 106 | 107 | continue; 108 | } 109 | 110 | pw.format("%s%s %s;\n", i, info.isInterface ? "struct" 111 | : "class", info.className); 112 | } 113 | 114 | TransformUtil.setNs(pw, new ArrayList(), cur); 115 | } finally { 116 | if (pw != null) { 117 | pw.close(); 118 | } 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/HeaderWriter.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.lang.reflect.Modifier; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.Iterator; 9 | import java.util.List; 10 | 11 | import org.eclipse.core.runtime.IPath; 12 | import org.eclipse.jdt.core.dom.ASTNode; 13 | import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 14 | import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; 15 | import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 16 | import org.eclipse.jdt.core.dom.Block; 17 | import org.eclipse.jdt.core.dom.BodyDeclaration; 18 | import org.eclipse.jdt.core.dom.EnumConstantDeclaration; 19 | import org.eclipse.jdt.core.dom.EnumDeclaration; 20 | import org.eclipse.jdt.core.dom.FieldDeclaration; 21 | import org.eclipse.jdt.core.dom.IBinding; 22 | import org.eclipse.jdt.core.dom.IMethodBinding; 23 | import org.eclipse.jdt.core.dom.ITypeBinding; 24 | import org.eclipse.jdt.core.dom.IVariableBinding; 25 | import org.eclipse.jdt.core.dom.Initializer; 26 | import org.eclipse.jdt.core.dom.Javadoc; 27 | import org.eclipse.jdt.core.dom.MethodDeclaration; 28 | import org.eclipse.jdt.core.dom.QualifiedName; 29 | import org.eclipse.jdt.core.dom.QualifiedType; 30 | import org.eclipse.jdt.core.dom.SimpleName; 31 | import org.eclipse.jdt.core.dom.SimpleType; 32 | import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 33 | import org.eclipse.jdt.core.dom.Statement; 34 | import org.eclipse.jdt.core.dom.TypeDeclaration; 35 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 36 | 37 | public class HeaderWriter extends TransformWriter { 38 | private final IPath root; 39 | 40 | private final Header header; 41 | private String access; 42 | 43 | public HeaderWriter(IPath root, Transformer ctx, UnitInfo unitInfo, 44 | TypeInfo typeInfo) { 45 | super(ctx, unitInfo, typeInfo); 46 | this.root = root; 47 | 48 | access = Header.initialAccess(type); 49 | 50 | header = new Header(ctx, type, deps); 51 | } 52 | 53 | public void write(AnnotationTypeDeclaration node) throws Exception { 54 | writeType(node.bodyDeclarations()); 55 | } 56 | 57 | public void write(AnonymousClassDeclaration node) throws Exception { 58 | writeType(node.bodyDeclarations()); 59 | } 60 | 61 | public void write(EnumDeclaration node) throws Exception { 62 | writeType(node.enumConstants(), node.bodyDeclarations()); 63 | } 64 | 65 | public void write(TypeDeclaration node) throws Exception { 66 | writeType(node.bodyDeclarations()); 67 | } 68 | 69 | private void writeType(List declarations) { 70 | writeType(new ArrayList(), declarations); 71 | } 72 | 73 | private void writeType(List enums, 74 | List declarations) { 75 | try { 76 | String body = getBody(enums, declarations); 77 | 78 | header.write(root, body, typeInfo.closures(), typeInfo.hasClinit(), 79 | typeInfo.hasInit(), unitInfo.types.keySet(), access); 80 | } catch (Exception e) { 81 | throw new Error(e); 82 | } 83 | } 84 | 85 | private String getBody(List enums, 86 | List declarations) { 87 | StringWriter sw = new StringWriter(); 88 | out = new PrintWriter(sw); 89 | 90 | indent++; 91 | 92 | visitAll(enums); 93 | 94 | visitAll(declarations); // This will gather constructors 95 | 96 | indent--; 97 | 98 | out.close(); 99 | out = null; 100 | return sw.toString(); 101 | } 102 | 103 | @Override 104 | public boolean preVisit2(ASTNode node) { 105 | for (Snippet snippet : ctx.snippets) { 106 | if (!snippet.node(ctx, this, node)) { 107 | return false; 108 | } 109 | } 110 | 111 | return super.preVisit2(node); 112 | } 113 | 114 | private List> handledBlocks = new ArrayList>( 115 | Arrays.asList(TypeDeclaration.class)); 116 | 117 | @Override 118 | public boolean visit(AnnotationTypeDeclaration node) { 119 | return false; 120 | } 121 | 122 | @Override 123 | public boolean visit(AnnotationTypeMemberDeclaration node) { 124 | printi(); 125 | TransformUtil.printSignature(ctx, out, type, node.resolveBinding(), 126 | deps, false); 127 | // TODO defaults 128 | println(" = 0;"); 129 | return false; 130 | } 131 | 132 | @Override 133 | public boolean visit(Block node) { 134 | if (!handledBlocks.contains(node.getParent().getClass())) { 135 | printlni("{"); 136 | 137 | indent++; 138 | 139 | for (Object o : node.statements()) { 140 | Statement s = (Statement) o; 141 | s.accept(this); 142 | } 143 | 144 | indent--; 145 | printlni("}"); 146 | println(); 147 | } 148 | 149 | return false; 150 | } 151 | 152 | @Override 153 | public boolean visit(EnumDeclaration node) { 154 | return false; 155 | } 156 | 157 | @Override 158 | public boolean visit(EnumConstantDeclaration node) { 159 | access = Header.printAccess(out, node.getModifiers(), access); 160 | printi("static " + CName.of(type) + " *"); 161 | 162 | node.getName().accept(this); 163 | println(";"); 164 | 165 | return false; 166 | } 167 | 168 | @Override 169 | public boolean visit(FieldDeclaration node) { 170 | if (node.getJavadoc() != null) { 171 | node.getJavadoc().accept(this); 172 | } 173 | 174 | List fragments = node.fragments(); 175 | 176 | int modifiers = node.getModifiers(); 177 | if (TransformWriter.isAnySpecial(fragments)) { 178 | for (VariableDeclarationFragment f : fragments) { 179 | IVariableBinding vb = f.resolveBinding(); 180 | boolean asMethod = TransformUtil.asMethod(vb); 181 | access = Header.printAccess(out, asMethod ? Modifier.PRIVATE 182 | : vb.getModifiers(), access); 183 | 184 | Object cv = TransformUtil.constexprValue(f); 185 | printi(TransformUtil.fieldModifiers(type, modifiers, true, 186 | cv != null)); 187 | 188 | print(TransformUtil.varTypeCName(modifiers, vb.getType(), type, 189 | deps) + " "); 190 | 191 | f.accept(this); 192 | 193 | println(asMethod ? "_;" : ";"); 194 | } 195 | } else { 196 | access = Header.printAccess(out, modifiers, access); 197 | 198 | printi(TransformUtil.fieldModifiers(type, modifiers, true, false)); 199 | 200 | ITypeBinding tb = node.getType().resolveBinding(); 201 | print(TransformUtil.varTypeCName(modifiers, tb, type, deps)); 202 | 203 | print(" "); 204 | 205 | visitAllCSV(fragments, false); 206 | 207 | println(";"); 208 | } 209 | 210 | return false; 211 | } 212 | 213 | @Override 214 | public boolean visit(Initializer node) { 215 | return false; 216 | } 217 | 218 | @Override 219 | public boolean visit(Javadoc node) { 220 | if (true) 221 | return false; 222 | printi("/** "); 223 | for (Iterator it = node.tags().iterator(); it.hasNext();) { 224 | ASTNode e = (ASTNode) it.next(); 225 | e.accept(this); 226 | } 227 | println("\n */"); 228 | return false; 229 | } 230 | 231 | @Override 232 | public boolean visit(MethodDeclaration node) { 233 | if (node.getJavadoc() != null) { 234 | node.getJavadoc().accept(this); 235 | } 236 | 237 | IMethodBinding mb = node.resolveBinding(); 238 | if (TransformUtil.baseDeclared(ctx, type, mb)) { 239 | // Defining once more will lead to virtual inheritance issues 240 | printi("/*"); 241 | TransformUtil.printSignature(ctx, out, type, mb, deps, false); 242 | println("; (already declared) */"); 243 | return false; 244 | } 245 | 246 | header.method(mb); 247 | 248 | if (node.isConstructor()) { 249 | access = Header.printProtected(out, access); 250 | 251 | printi("void " + CName.CTOR + "("); 252 | String sep = TransformUtil.printEnumCtorParams(ctx, out, type, "", 253 | deps); 254 | if (!node.parameters().isEmpty()) { 255 | print(sep); 256 | } 257 | } else { 258 | access = Header.printAccess(out, mb, access); 259 | 260 | printi(TransformUtil.methodModifiers(mb)); 261 | print(TransformUtil.typeParameters(node.typeParameters())); 262 | 263 | ITypeBinding rt = TransformUtil.returnType(type, node); 264 | softDep(rt); 265 | print(TransformUtil.relativeRef(rt, type, true) + " "); 266 | 267 | node.getName().accept(this); 268 | print("("); 269 | 270 | for (ITypeBinding rd : TransformUtil.returnDeps(type, mb, 271 | ctx.resolve(Object.class))) { 272 | hardDep(rd); 273 | } 274 | } 275 | 276 | visitAllCSV(node.parameters(), false); 277 | 278 | print(")"); 279 | 280 | print(TransformUtil.throwsDecl(node.thrownExceptions())); 281 | 282 | print(TransformUtil.methodSpecifiers(mb)); 283 | 284 | println(";"); 285 | 286 | return false; 287 | } 288 | 289 | @Override 290 | public boolean visit(SimpleName node) { 291 | IBinding b = node.resolveBinding(); 292 | if (b instanceof ITypeBinding) { 293 | softDep((ITypeBinding) b); 294 | print(CName.relative((ITypeBinding) b, type, false)); 295 | return false; 296 | } 297 | return super.visit(node); 298 | } 299 | 300 | @Override 301 | public boolean visit(SimpleType node) { 302 | ITypeBinding b = node.resolveBinding(); 303 | softDep(b); 304 | print(CName.relative(b, type, false)); 305 | return false; 306 | } 307 | 308 | @Override 309 | public boolean visit(QualifiedName node) { 310 | IBinding b = node.resolveBinding(); 311 | if (b instanceof ITypeBinding) { 312 | softDep((ITypeBinding) b); 313 | print(CName.relative((ITypeBinding) b, type, false)); 314 | return false; 315 | } 316 | return super.visit(node); 317 | } 318 | 319 | @Override 320 | public boolean visit(QualifiedType node) { 321 | ITypeBinding b = node.resolveBinding(); 322 | softDep(b); 323 | print(CName.relative(b, type, false)); 324 | return false; 325 | } 326 | 327 | @Override 328 | public boolean visit(SingleVariableDeclaration node) { 329 | ITypeBinding tb = node.getType().resolveBinding(); 330 | 331 | if (node.getExtraDimensions() > 0) { 332 | softDep(tb); 333 | tb = tb.createArrayType(node.getExtraDimensions()); 334 | } 335 | 336 | if (node.isVarargs()) { 337 | tb = tb.createArrayType(1); 338 | print(TransformUtil.relativeRef(tb, type, true)); 339 | print("/*...*/"); 340 | } else { 341 | print(TransformUtil.varTypeCName(node.getModifiers(), tb, type, 342 | deps)); 343 | } 344 | 345 | print(" "); 346 | 347 | node.getName().accept(this); 348 | 349 | return false; 350 | } 351 | 352 | @Override 353 | public boolean visit(TypeDeclaration node) { 354 | return false; 355 | } 356 | 357 | @Override 358 | public boolean visit(VariableDeclarationFragment node) { 359 | IVariableBinding vb = node.resolveBinding(); 360 | ITypeBinding tb = vb.getType(); 361 | header.field(vb); 362 | softDep(tb); 363 | 364 | node.getName().accept(this); 365 | 366 | String iv = TransformUtil.initialValue(vb); 367 | if (iv != null) { 368 | print(" { " + iv + " }"); 369 | } 370 | 371 | return false; 372 | } 373 | } 374 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/InitInfo.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.eclipse.jdt.core.dom.ASTNode; 7 | import org.eclipse.jdt.core.dom.Initializer; 8 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 9 | 10 | /** init() or clinit() contents */ 11 | public class InitInfo { 12 | /** 13 | * Strings constants that cannot be initialized directly in the header 14 | */ 15 | public List strings = new ArrayList(); 16 | public List nodes = new ArrayList(); 17 | 18 | public InitInfo() { 19 | } 20 | 21 | public void add(Initializer initializer) { 22 | nodes.add(initializer); 23 | } 24 | 25 | public void add(VariableDeclarationFragment fragment) { 26 | assert (TransformUtil.initInInit(fragment)); 27 | if (TransformUtil.constantValue(fragment) instanceof String) { 28 | strings.add(fragment); 29 | } else { 30 | nodes.add(fragment); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/MainWriter.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.eclipse.core.runtime.IPath; 7 | import org.eclipse.jdt.core.dom.ITypeBinding; 8 | 9 | public class MainWriter { 10 | private static final String MAIN_CPP_TMPL = "/se/arnetheduck/j2c/resources/Main.cpp.tmpl"; 11 | 12 | public static String write(IPath root, ITypeBinding tb) throws IOException { 13 | String filename = TransformUtil.mainName(tb); 14 | String include = TransformUtil.include(tb); 15 | String qcname = CName.qualified(tb, true); 16 | 17 | File target = root.append("src").append(filename).toFile(); 18 | FileUtil.writeTemplate(MAIN_CPP_TMPL, target, include, qcname); 19 | return filename; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/MakefileWriter.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.IOException; 4 | import java.util.Collection; 5 | import java.util.Set; 6 | import java.util.TreeSet; 7 | 8 | import org.eclipse.core.runtime.IPath; 9 | 10 | public class MakefileWriter { 11 | private static final String MAKEFILE_TMPL = "/se/arnetheduck/j2c/resources/Makefile.tmpl"; 12 | 13 | public static class Info { 14 | public final Set impls = new TreeSet(); 15 | public final Set stubs = new TreeSet(); 16 | public final Set natives = new TreeSet(); 17 | public final Set mains = new TreeSet(); 18 | } 19 | 20 | private final IPath root; 21 | 22 | public MakefileWriter(IPath root) { 23 | this.root = root; 24 | } 25 | 26 | public void write(String name, Info sel, Info ext) throws IOException { 27 | FileUtil.writeTemplate(MAKEFILE_TMPL, root.append("Makefile").toFile(), 28 | name, list(sel.impls, ""), list(sel.stubs, ""), 29 | list(sel.natives, ""), list(ext.impls, "ext/"), 30 | list(ext.stubs, "ext/"), list(ext.natives, "ext/"), 31 | list(sel.mains, "")); 32 | } 33 | 34 | private static String list(Collection items, String prefix) { 35 | StringBuilder sb = new StringBuilder(); 36 | for (String item : items) { 37 | sb.append("\t" + prefix + item + " \\\n"); 38 | } 39 | 40 | return sb.toString(); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/Predicate.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | public interface Predicate { 4 | boolean apply(T t); 5 | } 6 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/Snippet.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import org.eclipse.jdt.core.dom.ASTNode; 4 | import org.eclipse.jdt.core.dom.IMethodBinding; 5 | import org.eclipse.jdt.core.dom.ITypeBinding; 6 | import org.eclipse.jdt.core.dom.IVariableBinding; 7 | 8 | public interface Snippet { 9 | boolean node(Transformer ctx, HeaderWriter w, ASTNode node); 10 | 11 | boolean node(Transformer ctx, ImplWriter w, ASTNode node); 12 | 13 | boolean type(Transformer ctx, TypeBindingHeaderWriter w, ITypeBinding tb); 14 | 15 | boolean field(Transformer ctx, TypeBindingHeaderWriter w, 16 | IVariableBinding vb); 17 | 18 | boolean method(Transformer ctx, TypeBindingHeaderWriter w, IMethodBinding mb); 19 | 20 | boolean prefix(Transformer ctx, StubWriter w, boolean natives); 21 | 22 | boolean suffix(Transformer ctx, StubWriter w, boolean natives); 23 | 24 | boolean field(Transformer ctx, StubWriter w, IVariableBinding vb); 25 | 26 | boolean method(Transformer ctx, StubWriter w, IMethodBinding mb); 27 | 28 | boolean body(Transformer ctx, StubWriter w, IMethodBinding mb); 29 | } 30 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/Stats.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import org.eclipse.jdt.core.dom.ITypeBinding; 4 | 5 | public class Stats { 6 | private enum Nesting { 7 | TOP_LEVEL, NESTED, LOCAL, ANONYMOUS 8 | } 9 | 10 | private enum Type { 11 | CLASS, INTERFACE, ENUM, ANNOTATION, 12 | } 13 | 14 | public int stats[][] = new int[Nesting.values().length][Type.values().length]; 15 | 16 | public void add(ITypeBinding tb) { 17 | if (tb.isPrimitive() || tb.isArray()) { 18 | return; 19 | } 20 | 21 | Nesting nesting = Nesting.TOP_LEVEL; 22 | if (tb.isAnonymous()) { 23 | nesting = Nesting.ANONYMOUS; 24 | } else if (tb.isLocal()) { 25 | nesting = Nesting.LOCAL; 26 | } else if (tb.isNested()) { 27 | nesting = Nesting.NESTED; 28 | } else { 29 | if (!tb.isTopLevel()) { 30 | System.out.println(tb + " nesting?"); 31 | } 32 | } 33 | 34 | Type type = Type.CLASS; 35 | if (tb.isAnnotation()) { 36 | type = Type.ANNOTATION; 37 | } else if (tb.isEnum()) { 38 | type = Type.ENUM; 39 | } else if (tb.isInterface()) { 40 | type = Type.INTERFACE; 41 | } else { 42 | if (!tb.isClass()) { 43 | System.out.println(tb + " type?"); 44 | } 45 | } 46 | 47 | stats[nesting.ordinal()][type.ordinal()]++; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | StringBuilder sb = new StringBuilder(); 53 | sb.append(String.format("%15s", "")); 54 | ; 55 | for (Nesting n : Nesting.values()) { 56 | sb.append(String.format("%15s", n)); 57 | } 58 | 59 | sb.append('\n'); 60 | for (Type t : Type.values()) { 61 | sb.append(String.format("%15s", t)); 62 | for (Nesting n : Nesting.values()) { 63 | sb.append(String.format("%15s", stats[n.ordinal()][t.ordinal()])); 64 | } 65 | 66 | sb.append('\n'); 67 | } 68 | 69 | return sb.toString(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/StubWriter.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.lang.reflect.Modifier; 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | 9 | import org.eclipse.core.runtime.IPath; 10 | import org.eclipse.jdt.core.dom.IMethodBinding; 11 | import org.eclipse.jdt.core.dom.ITypeBinding; 12 | import org.eclipse.jdt.core.dom.IVariableBinding; 13 | 14 | public class StubWriter { 15 | private static final String i1 = TransformUtil.indent(1); 16 | 17 | private final IPath root; 18 | private final Transformer ctx; 19 | private final ITypeBinding type; 20 | 21 | private final DepInfo deps; 22 | 23 | private Collection constructors = new ArrayList(); 24 | 25 | private final Impl impl; 26 | private final String qcname; 27 | private final String name; 28 | 29 | private PrintWriter out; 30 | 31 | public StubWriter(IPath root, Transformer ctx, ITypeBinding type) { 32 | if (type.isInterface()) { 33 | throw new UnsupportedOperationException(); 34 | } 35 | 36 | this.root = root; 37 | this.ctx = ctx; 38 | this.type = type; 39 | 40 | deps = new DepInfo(ctx); 41 | impl = new Impl(ctx, type, deps); 42 | qcname = CName.qualified(type, false); 43 | name = CName.of(type); 44 | } 45 | 46 | public void write(boolean natives, boolean privates) throws Exception { 47 | String body = getBody(natives, privates); 48 | String extras = getPrefix(natives); 49 | String suffix = getSuffix(natives); 50 | 51 | if (natives) { 52 | ctx.addNative(type); 53 | impl.write(root, extras + body + suffix, TransformUtil.NATIVE, 54 | null, null, natives); 55 | } else { 56 | ctx.addStub(type); 57 | impl.write(root, extras + body + suffix, TransformUtil.STUB, null, 58 | null, natives); 59 | } 60 | } 61 | 62 | private String getPrefix(boolean natives) { 63 | StringWriter sw = new StringWriter(); 64 | out = new PrintWriter(sw); 65 | 66 | for (Snippet snippet : ctx.snippets) { 67 | if (!snippet.prefix(ctx, this, natives)) { 68 | return ""; 69 | } 70 | } 71 | 72 | out.println("extern void unimplemented_(const char16_t* name);"); 73 | 74 | if (!natives) { 75 | printDefaultInitCtor(); 76 | printCtors(); 77 | } 78 | 79 | out.close(); 80 | out = null; 81 | 82 | return sw.toString(); 83 | } 84 | 85 | private String getSuffix(boolean natives) { 86 | StringWriter sw = new StringWriter(); 87 | out = new PrintWriter(sw); 88 | 89 | for (Snippet snippet : ctx.snippets) { 90 | if (!snippet.suffix(ctx, this, natives)) { 91 | return ""; 92 | } 93 | } 94 | 95 | out.close(); 96 | out = null; 97 | 98 | return sw.toString(); 99 | } 100 | 101 | private String getBody(boolean natives, boolean privates) throws Exception { 102 | StringWriter ret = new StringWriter(); 103 | out = new PrintWriter(ret); 104 | 105 | if (!natives) { 106 | for (IVariableBinding vb : type.getDeclaredFields()) { 107 | printField(vb); 108 | } 109 | } 110 | 111 | println(); 112 | 113 | for (IMethodBinding mb : type.getDeclaredMethods()) { 114 | if (Modifier.isNative(mb.getModifiers()) == natives) { 115 | printMethod(mb, privates); 116 | } 117 | } 118 | 119 | out.close(); 120 | 121 | out = null; 122 | 123 | return ret.toString(); 124 | } 125 | 126 | private void printCtors() { 127 | if (!TypeUtil.isClassLike(type)) { 128 | return; 129 | } 130 | 131 | if (type.isAnonymous()) { 132 | Header.getAnonCtors(type, constructors); 133 | } 134 | 135 | boolean hasEmpty = false; 136 | for (IMethodBinding mb : constructors) { 137 | print(qcname + "::" + name + "("); 138 | 139 | String sep = TransformUtil.printExtraCtorParams(ctx, out, type, 140 | null, deps, false, mb); 141 | 142 | if (mb.getParameterTypes().length > 0) { 143 | print(sep); 144 | TransformUtil.printParams(out, type, mb, false, deps); 145 | } else { 146 | hasEmpty = true; 147 | } 148 | 149 | println(")"); 150 | 151 | print(i1 + ": " + name + "("); 152 | sep = ""; 153 | if (TransformUtil.hasOuterThis(type)) { 154 | print(TransformUtil.outerThisName(type)); 155 | sep = ", "; 156 | } 157 | 158 | println(sep + TransformUtil.makeDefaultInitTag() + ")"); 159 | 160 | println("{"); 161 | print(i1 + CName.CTOR + "("); 162 | 163 | sep = TransformUtil.printEnumCtorCallParams(out, type, ""); 164 | for (int i = 0; i < mb.getParameterTypes().length; ++i) { 165 | print(sep + TransformUtil.paramName(mb, i)); 166 | sep = ", "; 167 | } 168 | 169 | println(");"); 170 | 171 | println("}"); 172 | println(); 173 | } 174 | 175 | if (TransformUtil.needsEmptyCtor(hasEmpty, false, type)) { 176 | printEmptyCtor(); 177 | } 178 | } 179 | 180 | private void printDefaultInitCtor() { 181 | if (!TypeUtil.isClassLike(type) || type.isAnonymous()) { 182 | return; 183 | } 184 | 185 | print(qcname + "::" + name + "("); 186 | TransformUtil.printExtraCtorParams(ctx, out, type, null, deps, true, 187 | null); 188 | println(")"); 189 | 190 | printFieldInit(": "); 191 | 192 | println("{"); 193 | printClInitCall(); 194 | println("}"); 195 | println(); 196 | 197 | } 198 | 199 | private void printClInitCall() { 200 | println(i1 + CName.STATIC_INIT + "();"); 201 | } 202 | 203 | private void printEmptyCtor() { 204 | print("void " + qcname + "::" + CName.CTOR + "("); 205 | TransformUtil.printEnumCtorParams(ctx, out, type, "", deps); 206 | println(")"); 207 | println("{"); 208 | if (type.getSuperclass() != null) { 209 | print(i1 + "super::"); 210 | TransformUtil.printEmptyCtorCall(out, type); 211 | println(";"); 212 | } 213 | 214 | println("}"); 215 | println(); 216 | } 217 | 218 | private void printFieldInit(String sep) { 219 | ITypeBinding sb = type.getSuperclass(); 220 | if (sb != null) { 221 | print(i1 + sep); 222 | print("super("); 223 | if (TransformUtil.hasOuterThis(sb)) { 224 | String sepx = ""; 225 | for (ITypeBinding tb = type; tb.getDeclaringClass() != null; tb = tb 226 | .getDeclaringClass().getErasure()) { 227 | print(sepx); 228 | sepx = "->"; 229 | hardDep(tb.getDeclaringClass()); 230 | print(TransformUtil.outerThisName(tb)); 231 | if (tb.getDeclaringClass() 232 | .getErasure() 233 | .isSubTypeCompatible( 234 | sb.getDeclaringClass().getErasure())) { 235 | break; 236 | } 237 | 238 | } 239 | 240 | print(", "); 241 | } 242 | 243 | println(TransformUtil.makeDefaultInitTag() + ")"); 244 | sep = ", "; 245 | } 246 | 247 | if (TransformUtil.hasOuterThis(type) 248 | && (sb == null || sb.getDeclaringClass() == null || !type 249 | .getDeclaringClass().getErasure() 250 | .isEqualTo(sb.getDeclaringClass().getErasure()))) { 251 | print(i1 + sep); 252 | hardDep(type.getDeclaringClass()); 253 | printInit(TransformUtil.outerThisName(type)); 254 | sep = ", "; 255 | } 256 | 257 | for (IVariableBinding vb : type.getDeclaredFields()) { 258 | if (TransformUtil.isStatic(vb)) { 259 | continue; 260 | } 261 | 262 | if (TransformUtil.initialValue(vb) != null) { 263 | continue; 264 | } 265 | 266 | // TODO Init string literals 267 | print(i1 + sep + CName.of(vb)); 268 | 269 | println("()"); 270 | sep = ", "; 271 | 272 | } 273 | } 274 | 275 | private void printInit(String n) { 276 | println(n + "(" + n + ")"); 277 | } 278 | 279 | private void printField(IVariableBinding vb) { 280 | for (Snippet snippet : ctx.snippets) { 281 | if (!snippet.field(ctx, this, vb)) { 282 | return; 283 | } 284 | } 285 | 286 | if (!TransformUtil.isStatic(vb)) { 287 | return; 288 | } 289 | 290 | Object cv = TransformUtil.constexprValue(vb); 291 | boolean asMethod = TransformUtil.asMethod(vb); 292 | 293 | ITypeBinding vt = vb.getType(); 294 | String vname = CName.of(vb); 295 | String qvtname = TransformUtil 296 | .varTypeCName(vb.getModifiers(), vt, deps); 297 | if (asMethod) { 298 | print(qvtname); 299 | println("& " + qcname + "::" + vname + "()"); 300 | println("{"); 301 | printClInitCall(); 302 | println(i1 + "return " + vname + "_;"); 303 | println("}"); 304 | } 305 | 306 | print(TransformUtil.fieldModifiers(type, vb.getModifiers(), false, 307 | cv != null && !(cv instanceof String))); 308 | 309 | print(qvtname + " " + qcname + "::" + vname); 310 | println(asMethod ? "_;" : ";"); 311 | } 312 | 313 | private void printMethod(IMethodBinding mb, boolean privates) 314 | throws Exception { 315 | for (Snippet snippet : ctx.snippets) { 316 | if (!snippet.method(ctx, this, mb)) { 317 | return; 318 | } 319 | } 320 | 321 | if (Modifier.isPrivate(mb.getModifiers()) && !privates) { 322 | if (Modifier.isAbstract(mb.getModifiers())) { 323 | return; 324 | } 325 | 326 | print("/* private: "); 327 | TransformUtil.printSignature(ctx, out, type, mb, deps, true); 328 | println(" */"); 329 | return; 330 | } 331 | 332 | impl.method(mb); 333 | 334 | if (Modifier.isAbstract(mb.getModifiers())) { 335 | return; 336 | } 337 | 338 | if (mb.isConstructor()) { 339 | constructors.add(mb); 340 | } 341 | 342 | TransformUtil.printSignature(ctx, out, type, mb, deps, true); 343 | 344 | println(); 345 | print("{"); 346 | if (Modifier.isNative(mb.getModifiers())) { 347 | println(" /* native */"); 348 | } else { 349 | println(" /* stub */"); 350 | } 351 | 352 | if (TransformUtil.isStatic(mb)) { 353 | printClInitCall(); 354 | } 355 | 356 | if (mb.isConstructor() && type.getSuperclass() != null) { 357 | // Remind the user that this has to be done one way or another 358 | // TODO Maybe try to find a suitable candidate to pass as many 359 | // parameters as possible 360 | println(i1 + "/* super::" + CName.CTOR + "(); */"); 361 | } 362 | 363 | boolean hasBody = false; 364 | for (Snippet snippet : ctx.snippets) { 365 | if (!snippet.body(ctx, this, mb)) { 366 | hasBody = true; 367 | break; 368 | } 369 | } 370 | 371 | if (!hasBody) { 372 | print(i1 + "unimplemented_(u\""); 373 | TransformUtil.printSignature(ctx, out, type, mb, deps, true); 374 | println("\");"); 375 | if (!TransformUtil.isVoid(mb.getReturnType())) { 376 | println(i1 + "return 0;"); 377 | } 378 | } 379 | 380 | println("}"); 381 | println(); 382 | 383 | TransformUtil.defineBridge(ctx, out, type, mb, deps); 384 | } 385 | 386 | public void hardDep(ITypeBinding dep) { 387 | deps.hard(dep); 388 | } 389 | 390 | public void print(String string) { 391 | out.print(string); 392 | } 393 | 394 | public void println(String string) { 395 | out.println(string); 396 | } 397 | 398 | public void println() { 399 | out.println(); 400 | } 401 | 402 | public ITypeBinding type() { 403 | return type; 404 | } 405 | } 406 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/TypeBindingHeaderWriter.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.lang.reflect.Modifier; 6 | import java.util.ArrayList; 7 | 8 | import org.eclipse.core.runtime.IPath; 9 | import org.eclipse.jdt.core.dom.IMethodBinding; 10 | import org.eclipse.jdt.core.dom.ITypeBinding; 11 | import org.eclipse.jdt.core.dom.IVariableBinding; 12 | 13 | public class TypeBindingHeaderWriter { 14 | private final IPath root; 15 | private final ITypeBinding type; 16 | private final Transformer ctx; 17 | 18 | private final DepInfo deps; 19 | 20 | private String access; 21 | private final Header header; 22 | private static final String i1 = TransformUtil.indent(1); 23 | 24 | public TypeBindingHeaderWriter(IPath root, Transformer ctx, 25 | ITypeBinding type) { 26 | this.root = root; 27 | this.ctx = ctx; 28 | this.type = type; 29 | 30 | deps = new DepInfo(ctx); 31 | access = Header.initialAccess(type); 32 | softDep(type); 33 | header = new Header(ctx, type, deps); 34 | } 35 | 36 | public void write() throws Exception { 37 | writeType(); 38 | 39 | if (!type.isInterface()) { 40 | StubWriter sw = new StubWriter(root, ctx, type); 41 | sw.write(false, false); 42 | if (hasNatives()) { 43 | sw = new StubWriter(root, ctx, type); 44 | sw.write(true, false); 45 | } 46 | } 47 | } 48 | 49 | private boolean hasNatives() { 50 | for (IMethodBinding mb : type.getDeclaredMethods()) { 51 | if (Modifier.isNative(mb.getModifiers())) { 52 | return true; 53 | } 54 | } 55 | 56 | return false; 57 | } 58 | 59 | private void writeType() throws Exception { 60 | for (ITypeBinding nb : type.getDeclaredTypes()) { 61 | TypeBindingHeaderWriter hw = new TypeBindingHeaderWriter(root, ctx, 62 | nb); 63 | hw.write(); 64 | } 65 | 66 | try { 67 | String body = getBody(); 68 | 69 | header.write(root, body, new ArrayList(), false, 70 | false, new ArrayList(), access); 71 | } catch (Exception e) { 72 | throw new Error(e); 73 | } 74 | } 75 | 76 | private String getBody() { 77 | StringWriter sw = new StringWriter(); 78 | PrintWriter out = new PrintWriter(sw); 79 | 80 | for (IVariableBinding vb : type.getDeclaredFields()) { 81 | header.field(vb); 82 | printField(out, vb); 83 | } 84 | 85 | out.println(); 86 | 87 | for (IMethodBinding mb : type.getDeclaredMethods()) { 88 | printMethod(out, mb); 89 | } 90 | 91 | return sw.toString(); 92 | } 93 | 94 | private void printField(PrintWriter pw, IVariableBinding vb) { 95 | ITypeBinding tb = vb.getType(); 96 | softDep(tb); 97 | 98 | boolean asMethod = TransformUtil.asMethod(vb); 99 | int modifiers = vb.getModifiers(); 100 | access = Header.printAccess(pw, 101 | asMethod ? Modifier.PRIVATE : modifiers, access); 102 | pw.print(TransformUtil.indent(1)); 103 | 104 | Object cv = TransformUtil.constexprValue(vb); 105 | pw.print(TransformUtil 106 | .fieldModifiers(type, modifiers, true, cv != null)); 107 | 108 | pw.print(TransformUtil.varTypeCName(modifiers, tb, 109 | vb.getDeclaringClass(), deps)); 110 | pw.print(" "); 111 | 112 | pw.print(CName.of(vb)); 113 | pw.print(asMethod ? "_" : ""); 114 | 115 | String iv = TransformUtil.initialValue(vb); 116 | if (iv != null) { 117 | pw.print(" { " + iv + " }"); 118 | } 119 | 120 | pw.println(";"); 121 | } 122 | 123 | private void printMethod(PrintWriter pw, IMethodBinding mb) { 124 | if (TransformUtil.baseDeclared(ctx, type, mb)) { 125 | // Defining once more will lead to virtual inheritance issues 126 | pw.print(i1 + "/*"); 127 | TransformUtil.printSignature(ctx, pw, type, mb, deps, false); 128 | pw.println("; (already declared) */"); 129 | return; 130 | } 131 | 132 | if (Modifier.isPrivate(mb.getModifiers())) { 133 | // Skip implementation details 134 | pw.print(i1 + "/*"); 135 | TransformUtil.printSignature(ctx, pw, type, mb, deps, false); 136 | pw.println("; (private) */"); 137 | return; 138 | } 139 | 140 | if (mb.isConstructor()) { 141 | // The fake ctor should always be protected 142 | access = Header.printProtected(pw, access); 143 | } else { 144 | access = Header.printAccess(pw, mb.getModifiers(), access); 145 | } 146 | 147 | header.method(mb); 148 | 149 | pw.print(i1); 150 | TransformUtil.printSignature(ctx, pw, type, mb, deps, false); 151 | 152 | pw.print(TransformUtil.methodSpecifiers(mb)); 153 | 154 | pw.println(";"); 155 | 156 | for (ITypeBinding rd : TransformUtil.returnDeps(type, mb, 157 | ctx.resolve(Object.class))) { 158 | hardDep(rd); 159 | } 160 | } 161 | 162 | public void hardDep(ITypeBinding dep) { 163 | deps.hard(dep); 164 | } 165 | 166 | public void softDep(ITypeBinding dep) { 167 | deps.soft(dep); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/TypeInfo.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.util.LinkedHashSet; 4 | import java.util.Set; 5 | 6 | import org.eclipse.jdt.core.dom.ITypeBinding; 7 | import org.eclipse.jdt.core.dom.IVariableBinding; 8 | import org.eclipse.jdt.core.dom.Initializer; 9 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 10 | 11 | /** Contextual info about a type */ 12 | public class TypeInfo { 13 | private final TypeInfo parent; 14 | private final ITypeBinding type; 15 | 16 | private InitInfo init = new InitInfo(); 17 | private InitInfo clinit = new InitInfo(); 18 | 19 | private final Set closures; 20 | private boolean natives; 21 | private boolean main; 22 | 23 | public TypeInfo(TypeInfo parent, ITypeBinding type) { 24 | this.parent = parent; 25 | this.type = type; 26 | 27 | closures = type.isLocal() ? new LinkedHashSet() 28 | : null; 29 | } 30 | 31 | public TypeInfo parent() { 32 | return parent; 33 | } 34 | 35 | public ITypeBinding type() { 36 | return type; 37 | } 38 | 39 | public boolean hasNatives() { 40 | return natives; 41 | } 42 | 43 | public void setHasNatives() { 44 | natives = true; 45 | } 46 | 47 | public boolean hasMain() { 48 | return main; 49 | } 50 | 51 | public void setHasMain() { 52 | main = true; 53 | } 54 | 55 | public void addInit(VariableDeclarationFragment fragment) { 56 | getInit(TransformUtil.isStatic(fragment)).add(fragment); 57 | } 58 | 59 | public void addInit(Initializer initializer) { 60 | getInit(TransformUtil.isStatic(initializer)).add(initializer); 61 | } 62 | 63 | public InitInfo getInit(boolean static_) { 64 | return static_ ? clinit : init; 65 | } 66 | 67 | public boolean hasInit() { 68 | // strings are not part of init() 69 | return !init.nodes.isEmpty(); 70 | } 71 | 72 | public boolean hasClinit() { 73 | return !clinit.nodes.isEmpty() || !clinit.strings.isEmpty(); 74 | } 75 | 76 | public void addClosure(IVariableBinding closure) { 77 | closures.add(closure); 78 | } 79 | 80 | public Set closures() { 81 | return closures; 82 | } 83 | 84 | public boolean isClosure(IVariableBinding vb) { 85 | return closures != null && closures.contains(vb); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/TypeInfoVisitor.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import org.eclipse.jdt.core.IJavaElement; 4 | import org.eclipse.jdt.core.IType; 5 | import org.eclipse.jdt.core.dom.ASTNode; 6 | import org.eclipse.jdt.core.dom.ASTVisitor; 7 | import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 8 | import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 9 | import org.eclipse.jdt.core.dom.EnumDeclaration; 10 | import org.eclipse.jdt.core.dom.IBinding; 11 | import org.eclipse.jdt.core.dom.IMethodBinding; 12 | import org.eclipse.jdt.core.dom.ITypeBinding; 13 | import org.eclipse.jdt.core.dom.IVariableBinding; 14 | import org.eclipse.jdt.core.dom.Initializer; 15 | import org.eclipse.jdt.core.dom.MethodDeclaration; 16 | import org.eclipse.jdt.core.dom.Modifier; 17 | import org.eclipse.jdt.core.dom.SimpleName; 18 | import org.eclipse.jdt.core.dom.TypeDeclaration; 19 | import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 20 | 21 | public class TypeInfoVisitor extends ASTVisitor { 22 | private UnitInfo unitInfo; 23 | private TypeInfo typeInfo; 24 | 25 | public TypeInfoVisitor(UnitInfo unitInfo) { 26 | this.unitInfo = unitInfo; 27 | } 28 | 29 | @Override 30 | public boolean visit(AnnotationTypeDeclaration node) { 31 | typeInfo = new TypeInfo(typeInfo, node.resolveBinding()); 32 | unitInfo.types.put(typeInfo.type(), typeInfo); 33 | return true; 34 | } 35 | 36 | @Override 37 | public void endVisit(AnnotationTypeDeclaration node) { 38 | typeInfo = typeInfo.parent(); 39 | } 40 | 41 | @Override 42 | public boolean visit(AnonymousClassDeclaration node) { 43 | typeInfo = new TypeInfo(typeInfo, node.resolveBinding()); 44 | unitInfo.types.put(typeInfo.type(), typeInfo); 45 | return true; 46 | } 47 | 48 | @Override 49 | public void endVisit(AnonymousClassDeclaration node) { 50 | TypeInfo anonType = typeInfo; 51 | typeInfo = typeInfo.parent(); 52 | 53 | if (typeInfo.closures() != null && anonType.closures() != null) { 54 | for (IVariableBinding vb : anonType.closures()) { 55 | if (!vb.getDeclaringMethod().getDeclaringClass() 56 | .isEqualTo(typeInfo.type())) { 57 | typeInfo.addClosure(vb); 58 | } 59 | } 60 | } 61 | } 62 | 63 | @Override 64 | public boolean visit(EnumDeclaration node) { 65 | typeInfo = new TypeInfo(typeInfo, node.resolveBinding()); 66 | unitInfo.types.put(typeInfo.type(), typeInfo); 67 | return true; 68 | } 69 | 70 | @Override 71 | public void endVisit(EnumDeclaration node) { 72 | typeInfo = typeInfo.parent(); 73 | } 74 | 75 | @Override 76 | public boolean visit(MethodDeclaration node) { 77 | if (Modifier.isNative(node.getModifiers())) { 78 | typeInfo.setHasNatives(); 79 | } 80 | 81 | if (TransformUtil.isMain(node.resolveBinding())) { 82 | typeInfo.setHasMain(); 83 | } 84 | 85 | return true; 86 | } 87 | 88 | @Override 89 | public boolean visit(TypeDeclaration node) { 90 | typeInfo = new TypeInfo(typeInfo, node.resolveBinding()); 91 | unitInfo.types.put(typeInfo.type(), typeInfo); 92 | return true; 93 | } 94 | 95 | @Override 96 | public void endVisit(TypeDeclaration node) { 97 | typeInfo = typeInfo.parent(); 98 | } 99 | 100 | 101 | @Override 102 | public boolean visit(Initializer node) { 103 | typeInfo.addInit(node); 104 | return super.visit(node); 105 | } 106 | 107 | @Override 108 | public boolean visit(SimpleName node) { 109 | IBinding b = node.resolveBinding(); 110 | if (b instanceof IVariableBinding) { 111 | IVariableBinding vb = (IVariableBinding) b; 112 | 113 | if (isClosure(node, vb)) { 114 | typeInfo.addClosure(vb); 115 | } 116 | } 117 | 118 | return super.visit(node); 119 | } 120 | 121 | @Override 122 | public boolean visit(VariableDeclarationFragment node) { 123 | if (TransformUtil.initInInit(node)) { 124 | typeInfo.addInit(node); 125 | } 126 | 127 | return super.visit(node); 128 | } 129 | 130 | private boolean isClosure(SimpleName node, IVariableBinding vb) { 131 | if (vb.isField()) { 132 | return false; 133 | } 134 | 135 | if (vb.getDeclaringMethod() == null) { 136 | IJavaElement je = vb.getJavaElement().getAncestor( 137 | IJavaElement.INITIALIZER); 138 | 139 | // Could be a variable in an initializer block 140 | if (je == null 141 | || (((IType) je.getAncestor(IJavaElement.TYPE)) 142 | .getFullyQualifiedName().equals(((IType) type() 143 | .getJavaElement()).getFullyQualifiedName()))) { 144 | return false; 145 | } 146 | } 147 | 148 | if (!Modifier.isFinal(vb.getModifiers())) { 149 | return false; 150 | } 151 | VariableDeclarationFragment vdf = initializer(node); 152 | if (vdf == null && vb.getDeclaringMethod() != null) { 153 | IMethodBinding pmb = parentMethod(node); 154 | if (pmb.isEqualTo(vb.getDeclaringMethod())) { 155 | // Final local variable 156 | return false; 157 | } 158 | } 159 | return true; 160 | } 161 | 162 | private static IMethodBinding parentMethod(ASTNode node) { 163 | for (ASTNode n = node; n != null; n = n.getParent()) { 164 | if (n instanceof MethodDeclaration) { 165 | return ((MethodDeclaration) n).resolveBinding(); 166 | } 167 | } 168 | 169 | return null; 170 | } 171 | 172 | private VariableDeclarationFragment initializer(ASTNode node) { 173 | for (ASTNode n = node; n != null; n = n.getParent()) { 174 | if (n.getParent() instanceof VariableDeclarationFragment) { 175 | VariableDeclarationFragment vdf = (VariableDeclarationFragment) n 176 | .getParent(); 177 | if (type().isEqualTo(vdf.resolveBinding().getDeclaringClass()) 178 | && vdf.getInitializer() == n) { 179 | return vdf; 180 | } 181 | } 182 | } 183 | 184 | return null; 185 | } 186 | 187 | private ITypeBinding type() { 188 | return typeInfo.type(); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/TypeUtil.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import org.eclipse.jdt.core.dom.IMethodBinding; 8 | import org.eclipse.jdt.core.dom.ITypeBinding; 9 | import org.eclipse.jdt.core.dom.IVariableBinding; 10 | 11 | /** Utilities for traversing the type hierarchy */ 12 | public class TypeUtil { 13 | public static Predicate named(final String name) { 14 | return new Predicate() { 15 | @Override 16 | public boolean apply(Object t) { 17 | if (t instanceof ITypeBinding) { 18 | ITypeBinding tb = (ITypeBinding) t; 19 | return tb.getName().equals(name); 20 | } 21 | 22 | if (t instanceof IMethodBinding) { 23 | IMethodBinding mb = (IMethodBinding) t; 24 | return mb.getName().equals(name); 25 | } 26 | 27 | if (t instanceof IVariableBinding) { 28 | IVariableBinding vb = (IVariableBinding) t; 29 | return vb.getName().equals(name); 30 | } 31 | 32 | return false; 33 | } 34 | }; 35 | } 36 | 37 | /** Predicate that returns true for any method that mb overrides */ 38 | public static Predicate overrides(final IMethodBinding mb) { 39 | return new Predicate() { 40 | @Override 41 | public boolean apply(IMethodBinding t) { 42 | return !mb.isConstructor() 43 | && mb.getMethodDeclaration().overrides( 44 | t.getMethodDeclaration()); 45 | } 46 | }; 47 | } 48 | 49 | /** tb and all bases */ 50 | public static List types(ITypeBinding tb, ITypeBinding object) { 51 | List ret = new ArrayList(); 52 | ret.add(tb); 53 | ret.addAll(allBases(tb, object)); 54 | return ret; 55 | } 56 | 57 | /** Superclasses of tb, including java.lang.Object but not tb itself */ 58 | public static List superClasses(ITypeBinding tb) { 59 | List ret = new ArrayList(); 60 | superClasses(tb, ret); 61 | return ret; 62 | } 63 | 64 | public static void superClasses(ITypeBinding tb, Collection c) { 65 | ITypeBinding superclass = tb.getSuperclass(); 66 | if (superclass == null) { 67 | return; 68 | } 69 | 70 | c.add(superclass); 71 | superClasses(superclass, c); 72 | } 73 | 74 | /** 75 | * The interfaces a particular type implements including recursive 76 | * superinterfaces (but not the interfaces of any super class) 77 | */ 78 | public static List interfaces(ITypeBinding tb) { 79 | List ret = new ArrayList(); 80 | interfaces(tb, ret); 81 | return ret; 82 | } 83 | 84 | public static void interfaces(ITypeBinding tb, Collection c) { 85 | for (ITypeBinding ib : tb.getInterfaces()) { 86 | c.add(ib); 87 | interfaces(ib, c); 88 | } 89 | } 90 | 91 | /** Union of all methods defined by the supplied types */ 92 | public static List methods(Collection types) { 93 | return methods(types, null); 94 | } 95 | 96 | /** Union of all methods defined by the supplied types matching p */ 97 | public static List methods(Collection types, 98 | Predicate predicate) { 99 | 100 | List ret = new ArrayList(); 101 | for (ITypeBinding tb : types) { 102 | for (IMethodBinding mb : tb.getDeclaredMethods()) { 103 | if (predicate == null || predicate.apply(mb)) { 104 | ret.add(mb); 105 | } 106 | } 107 | } 108 | 109 | return ret; 110 | } 111 | 112 | /** Direct bases (superclass and interfaces) of a type */ 113 | public static List bases(ITypeBinding tb, ITypeBinding object) { 114 | List ret = new ArrayList(); 115 | 116 | if (tb.getSuperclass() != null) { 117 | ret.add(tb.getSuperclass()); 118 | } 119 | 120 | for (ITypeBinding ib : tb.getInterfaces()) { 121 | ret.add(ib); 122 | } 123 | 124 | if (object != null && ret.isEmpty() 125 | && !TransformUtil.same(tb, Object.class)) { 126 | ret.add(object); 127 | } 128 | 129 | return ret; 130 | } 131 | 132 | public static ITypeBinding commonBase(ITypeBinding tb0, ITypeBinding tb1, 133 | ITypeBinding object) { 134 | if (tb0.isEqualTo(tb1)) { 135 | return tb0; 136 | } 137 | 138 | if (tb0.isNullType()) { 139 | return tb1; 140 | } 141 | 142 | if (tb1.isNullType()) { 143 | return tb0; 144 | } 145 | 146 | List b0 = types(tb0, object); 147 | List b1 = types(tb1, object); 148 | for (ITypeBinding x0 : b0) { 149 | for (ITypeBinding x1 : b1) { 150 | if (x0.isEqualTo(x1)) { 151 | return x0; 152 | } 153 | } 154 | } 155 | 156 | throw new Error("Huh? Where's Object?"); 157 | } 158 | 159 | /** Recursive bases (superclasses and interfaces) of a type */ 160 | public static List allBases(ITypeBinding tb, 161 | ITypeBinding object) { 162 | List ret = new ArrayList(); 163 | 164 | List supers = superClasses(tb); 165 | ret.addAll(supers); 166 | interfaces(tb, ret); 167 | 168 | for (ITypeBinding b : supers) { 169 | interfaces(b, ret); 170 | } 171 | 172 | if (object != null && !TransformUtil.same(tb, Object.class) 173 | && !ret.contains(object)) { 174 | ret.add(object); 175 | } 176 | 177 | return ret; 178 | } 179 | 180 | public static boolean isClassLike(ITypeBinding type) { 181 | return type.isClass() || type.isEnum(); 182 | } 183 | 184 | public static int countBases(ITypeBinding type, ITypeBinding base) { 185 | int ret = 0; 186 | 187 | base = base.getErasure(); 188 | ITypeBinding superclass = type.getSuperclass(); 189 | if (superclass != null) { 190 | superclass = superclass.getErasure(); 191 | if (superclass.isEqualTo(base)) { 192 | return 1; // Base is a class, can only appear once 193 | } 194 | 195 | ret += countBases(superclass, base); 196 | } 197 | 198 | for (ITypeBinding ib : type.getInterfaces()) { 199 | ib = ib.getErasure(); 200 | if (ib.isEqualTo(base)) { 201 | ret += 1; 202 | } 203 | 204 | ret += countBases(ib, base); 205 | } 206 | 207 | return ret; 208 | } 209 | 210 | public static boolean isOverloaded(IMethodBinding b, ITypeBinding object) { 211 | Collection methods = methods( 212 | types(b.getDeclaringClass(), object), named(b.getName())); 213 | if (methods.size() < 2) { 214 | return false; 215 | } 216 | 217 | for (IMethodBinding mb : methods) { 218 | if (mb.getParameterTypes().length != b.getParameterTypes().length) 219 | continue; 220 | 221 | if (mb.isEqualTo(b)) 222 | continue; 223 | 224 | if (b.overrides(mb)) 225 | continue; 226 | 227 | return true; 228 | } 229 | 230 | return false; 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /plugin/src/se/arnetheduck/j2c/transform/UnitInfo.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.transform; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | import org.eclipse.jdt.core.dom.ITypeBinding; 7 | 8 | /** Contextual information about a CompilationUnit */ 9 | public class UnitInfo { 10 | public final Map types = new LinkedHashMap(); 11 | } 12 | -------------------------------------------------------------------------------- /test/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | se.arnetheduck.j2c.test 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true 3 | sp_cleanup.add_default_serial_version_id=true 4 | sp_cleanup.add_generated_serial_version_id=false 5 | sp_cleanup.add_missing_annotations=true 6 | sp_cleanup.add_missing_deprecated_annotations=true 7 | sp_cleanup.add_missing_methods=false 8 | sp_cleanup.add_missing_nls_tags=false 9 | sp_cleanup.add_missing_override_annotations=true 10 | sp_cleanup.add_missing_override_annotations_interface_methods=true 11 | sp_cleanup.add_serial_version_id=false 12 | sp_cleanup.always_use_blocks=true 13 | sp_cleanup.always_use_parentheses_in_expressions=false 14 | sp_cleanup.always_use_this_for_non_static_field_access=false 15 | sp_cleanup.always_use_this_for_non_static_method_access=false 16 | sp_cleanup.convert_to_enhanced_for_loop=false 17 | sp_cleanup.correct_indentation=true 18 | sp_cleanup.format_source_code=true 19 | sp_cleanup.format_source_code_changes_only=false 20 | sp_cleanup.make_local_variable_final=false 21 | sp_cleanup.make_parameters_final=false 22 | sp_cleanup.make_private_fields_final=true 23 | sp_cleanup.make_type_abstract_if_missing_method=false 24 | sp_cleanup.make_variable_declarations_final=false 25 | sp_cleanup.never_use_blocks=false 26 | sp_cleanup.never_use_parentheses_in_expressions=true 27 | sp_cleanup.on_save_use_additional_actions=true 28 | sp_cleanup.organize_imports=true 29 | sp_cleanup.qualify_static_field_accesses_with_declaring_class=false 30 | sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true 31 | sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true 32 | sp_cleanup.qualify_static_member_accesses_with_declaring_class=false 33 | sp_cleanup.qualify_static_method_accesses_with_declaring_class=false 34 | sp_cleanup.remove_private_constructors=true 35 | sp_cleanup.remove_trailing_whitespaces=true 36 | sp_cleanup.remove_trailing_whitespaces_all=true 37 | sp_cleanup.remove_trailing_whitespaces_ignore_empty=false 38 | sp_cleanup.remove_unnecessary_casts=false 39 | sp_cleanup.remove_unnecessary_nls_tags=false 40 | sp_cleanup.remove_unused_imports=true 41 | sp_cleanup.remove_unused_local_variables=false 42 | sp_cleanup.remove_unused_private_fields=true 43 | sp_cleanup.remove_unused_private_members=false 44 | sp_cleanup.remove_unused_private_methods=true 45 | sp_cleanup.remove_unused_private_types=true 46 | sp_cleanup.sort_members=false 47 | sp_cleanup.sort_members_all=false 48 | sp_cleanup.use_blocks=false 49 | sp_cleanup.use_blocks_only_for_return_and_throw=false 50 | sp_cleanup.use_parentheses_in_expressions=false 51 | sp_cleanup.use_this_for_non_static_field_access=false 52 | sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true 53 | sp_cleanup.use_this_for_non_static_method_access=false 54 | sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true 55 | -------------------------------------------------------------------------------- /test/src/Sort.java: -------------------------------------------------------------------------------- 1 | public class Sort { 2 | public static void mergeSort(Comparable[] a) { 3 | Comparable[] tmpArray = new Comparable[a.length]; 4 | mergeSort(a, tmpArray, 0, a.length - 1); 5 | } 6 | 7 | private static void mergeSort(Comparable[] a, Comparable[] tmpArray, 8 | int left, int right) { 9 | if (left < right) { 10 | int center = (left + right) / 2; 11 | mergeSort(a, tmpArray, left, center); 12 | mergeSort(a, tmpArray, center + 1, right); 13 | merge(a, tmpArray, left, center + 1, right); 14 | } 15 | } 16 | 17 | private static void merge(Comparable[] a, Comparable[] tmpArray, 18 | int leftPos, int rightPos, int rightEnd) { 19 | int leftEnd = rightPos - 1; 20 | int tmpPos = leftPos; 21 | int numElements = rightEnd - leftPos + 1; 22 | 23 | // Main loop 24 | while (leftPos <= leftEnd && rightPos <= rightEnd) 25 | if (a[leftPos].compareTo(a[rightPos]) <= 0) 26 | tmpArray[tmpPos++] = a[leftPos++]; 27 | else 28 | tmpArray[tmpPos++] = a[rightPos++]; 29 | 30 | while (leftPos <= leftEnd) 31 | tmpArray[tmpPos++] = a[leftPos++]; 32 | 33 | while (rightPos <= rightEnd) 34 | tmpArray[tmpPos++] = a[rightPos++]; 35 | 36 | // Copy tmpArray back 37 | for (int i = 0; i < numElements; i++, rightEnd--) 38 | a[rightEnd] = tmpArray[rightEnd]; 39 | } 40 | 41 | public static void main(String[] args) { 42 | mergeSort(args); 43 | 44 | String separator = ""; 45 | for (String s : args) { 46 | System.out.println(separator + s); 47 | separator = ", "; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Annot.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public @interface Annot { 4 | String value(); 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/BoxTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class BoxTest { 4 | int k; 5 | 6 | void m() { 7 | Integer i = 42; 8 | int j = i; 9 | j = Integer.valueOf(j); 10 | i = Integer.bitCount(i); 11 | j = m2(i); 12 | i = m2(j); 13 | 14 | Short s = 42; 15 | Byte b = 33; 16 | 17 | java.lang.Object o = '\u0000'; 18 | } 19 | 20 | int m2(Integer i) { 21 | return i; 22 | } 23 | 24 | static void x() { 25 | BoxTest bt = new BoxTest(); 26 | Integer i = bt.k; 27 | } 28 | 29 | public java.lang.Object m0() { 30 | return (k); 31 | } 32 | 33 | public java.lang.Object m1(java.lang.Object o) { 34 | return ((BoxTest) o).k; 35 | } 36 | 37 | static void genericBox() { 38 | gbox('c'); 39 | gbox(0l); 40 | gbox(0); 41 | gbox(0.0f); 42 | gbox(0.0); 43 | } 44 | 45 | static void gbox(T o) { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/BridgeTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class BridgeTest { 4 | public interface I { 5 | void t(T x); 6 | } 7 | 8 | public interface J extends I { 9 | @Override 10 | void t(Empty x); 11 | } 12 | 13 | public interface K extends I, J { 14 | // Both unhiding and dupe base method (see dupeNames) 15 | void t(Object o); 16 | } 17 | 18 | public static class A extends Empty { 19 | 20 | } 21 | 22 | public static class B extends A { 23 | 24 | } 25 | 26 | public static class ImplA implements I { 27 | @Override 28 | public void t(A x) { 29 | 30 | } 31 | } 32 | 33 | public static class ImplB implements I { 34 | @Override 35 | public void t(B x) { 36 | 37 | } 38 | } 39 | 40 | public void m() { 41 | new ImplA(); 42 | new ImplB(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/CastTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class CastTest { 4 | int m(int a, int b) { 5 | return a > b ? a : b; 6 | } 7 | 8 | double m(double a, double b) { 9 | return a > b ? a : b; 10 | } 11 | 12 | double x() { 13 | return m(1, 1.0); 14 | } 15 | 16 | double y1() { 17 | return 1. % 5; 18 | } 19 | 20 | float y2() { 21 | return 1.f % 5; 22 | } 23 | 24 | double y3() { 25 | return 1 % 5.; 26 | } 27 | 28 | float y4() { 29 | return 1 % 5.f; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ClassLiteralTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class ClassLiteralTest { 4 | interface A { 5 | } 6 | 7 | Class a = ClassLiteralTest.class; 8 | Class b = ClassLiteralTest[].class; 9 | Class c = int.class; 10 | Class d = A.class; 11 | } 12 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ConstructorTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class ConstructorTest { 4 | public int n; 5 | 6 | public ConstructorTest(int i) { 7 | n = i; 8 | new Empty(); 9 | } 10 | 11 | public ConstructorTest(short s) { 12 | this((int) s); 13 | } 14 | 15 | public void ConstructorTest() { 16 | // This is not a constructor! 17 | } 18 | 19 | public void m() { 20 | ConstructorTest(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/DefaultVirtual.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class DefaultVirtual { 4 | // Check that we don't override default access methods in another namespace 5 | NestedTest.Static m() { 6 | return null; 7 | } 8 | 9 | void n() { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Empty.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Empty { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/EnumTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public enum EnumTest { 4 | RED, GREEN, BLUE 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ExtendsTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class ExtendsTest extends LocalClassTest { 4 | public int nestedFieldAccess() { 5 | return new ParamConstructor(3) { 6 | @Override 7 | public int getV() { 8 | return lct.testArrayAccess(); 9 | } 10 | }.getV(); 11 | } 12 | 13 | public int nestedMethodAccess() { 14 | return new ParamConstructor(3) { 15 | @Override 16 | public int getV() { 17 | return testArrayAccess(); 18 | } 19 | }.getV(); 20 | } 21 | 22 | public int testThis(final int x) { 23 | ParamConstructor lpc = new ParamConstructor(3) { 24 | @Override 25 | public int getV() { 26 | return ExtendsTest.this.testArrayAccess(); 27 | } 28 | }; 29 | 30 | return lpc.getV(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ForTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ForTest { 7 | public void simple() { 8 | for (int i = 0; i < 10; ++i) { 9 | i = i + i; 10 | } 11 | } 12 | 13 | public void noBlock() { 14 | for (int i = 0; i < 10; ++i) 15 | i = i + 1; 16 | } 17 | 18 | public int enhancedArray() { 19 | int ret = 0; 20 | int[] x = new int[] { 0, 1, 2 }; 21 | for (int i : x) { 22 | ret += i; 23 | } 24 | 25 | return ret; 26 | } 27 | 28 | public int enhancedObjectArray() { 29 | int ret = 0; 30 | Object[] x = new Object[] { null }; 31 | for (Object i : x) { 32 | ret++; 33 | } 34 | 35 | return ret; 36 | } 37 | 38 | public int enhancedStringArray() { 39 | int ret = 0; 40 | String[] x = new String[] { null }; 41 | for (String i : x) { 42 | ret++; 43 | } 44 | 45 | return ret; 46 | } 47 | 48 | public Empty enhancedList() { 49 | List x = new ArrayList(); 50 | for (Empty i : x) { 51 | return i; 52 | } 53 | return null; 54 | } 55 | 56 | public int enhancedBox() { 57 | List x = new ArrayList(); 58 | for (int i : x) { 59 | return i; 60 | } 61 | return 0; 62 | } 63 | 64 | public int twoInts() { 65 | for (int i = 0, j = 1; i < 10; ++i) 66 | i = i + 1; 67 | return 0; 68 | } 69 | 70 | public int twoStrings() { 71 | for (String i = "", j = null; i.length() < 10; i = i + "1") 72 | i = i + 1; 73 | return 0; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Friends.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Friends { 4 | private int a; 5 | 6 | private static class A { 7 | private static class C { 8 | private static final int e = 0; 9 | } 10 | 11 | private static final int b = 0; 12 | private int c; 13 | } 14 | 15 | private class B extends A { 16 | public int m(java.lang.Object o) { 17 | new A() { 18 | int m() { 19 | return A.C.e; 20 | } 21 | }; 22 | return a + ((A) o).c + A.b + A.C.e; // Access to private vars 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/GenericTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | import java.util.List; 4 | 5 | public class GenericTest { 6 | String cast(List l) { 7 | return l.get(5); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Hello.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Hello { 4 | public static void main(String[] args) { 5 | System.out.println("Goodbye cruel world"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/IEmpty.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public interface IEmpty { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ISub.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public interface ISub extends IEmpty { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ITest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public interface ITest { 4 | int x = 5; // implicitly static & final 5 | 6 | public class NestedI { 7 | int x() { 8 | return 1; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/IfElseTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class IfElseTest { 4 | int m(int x) { 5 | if (x < 0) { 6 | return -1; 7 | } else if (x == 0) { 8 | return 0; 9 | } else { 10 | return 1; 11 | } 12 | } 13 | 14 | int m2(int x) { 15 | if (x < 0) 16 | return -1; 17 | else if (x == 0) 18 | return 0; 19 | else 20 | return 1; 21 | } 22 | 23 | int m3(int x) { 24 | if (x < 0) { 25 | return -1; 26 | } else if (x == 0) { 27 | return 0; 28 | } 29 | return 1; 30 | } 31 | 32 | int m4(int x) { 33 | if (x < 0) 34 | return -1; 35 | else if (x == 0) 36 | return 0; 37 | 38 | return 1; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Infix.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Infix { 4 | public interface I { 5 | 6 | } 7 | 8 | public interface J extends I { 9 | 10 | } 11 | 12 | public class S implements I { 13 | 14 | } 15 | 16 | boolean m(S s, J j) { 17 | // Comparison between distinct pointer types in C++ needs cast 18 | // to common base class 19 | return s == j; 20 | } 21 | 22 | boolean nullComp(Object o) { 23 | // This shouldn't require a cast 24 | return o == null; 25 | } 26 | 27 | boolean m(int i, char c) { 28 | return i == c; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/InitTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class InitTest { 4 | static { 5 | java.lang.Object o = new ParamConstructor(3) { 6 | }; 7 | java.lang.Object o2 = null; 8 | java.lang.Object o3 = o2, o4 = null; 9 | 10 | java.lang.Object x = ""; 11 | x = (InitTest) o; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/LabelTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class LabelTest { 4 | public void nestedFor() { 5 | outer: for (int i = 0; i < 10; ++i) { 6 | mid: for (int j = 0; j < 10; ++j) { 7 | for (int k = 0; k < 10; ++k) { 8 | if (j > 5 && i % 2 == 0) { 9 | break mid; 10 | } else if (j > 5 && i % 2 == 1) { 11 | continue outer; 12 | } 13 | int x = 5; 14 | } 15 | int y = 5; 16 | } 17 | } 18 | } 19 | 20 | public void breakBlock() { 21 | test: { 22 | for (int i = 0; i < 10; ++i) { 23 | break test; 24 | } 25 | 26 | int x = 5; 27 | } 28 | } 29 | 30 | public void contFor() { 31 | test: for (int i = 0; i < 10; ++i) { 32 | for (int j = i; j < 10; ++j) { 33 | continue test; 34 | } 35 | 36 | int x = 5; 37 | } 38 | } 39 | 40 | public void breakFor() { 41 | test: for (int i = 0; i < 10; ++i) { 42 | for (int j = i; j < 10; ++j) { 43 | break test; 44 | } 45 | 46 | int x = 5; 47 | } 48 | } 49 | 50 | public void contSimple() { 51 | test: for (int i = 0; i < 10; ++i) { 52 | continue test; 53 | } 54 | } 55 | 56 | public void breakSimple() { 57 | test: for (int i = 0; i < 10; ++i) { 58 | break test; 59 | } 60 | } 61 | 62 | public void breakEnhForIter(Iterable i) { 63 | outer: for (java.lang.Object o : i) { 64 | for (java.lang.Object o2 : i) { 65 | break outer; 66 | } 67 | } 68 | } 69 | 70 | public void contEnhForIter(Iterable i) { 71 | outer: for (java.lang.Object o : i) { 72 | for (java.lang.Object o2 : i) { 73 | continue outer; 74 | } 75 | } 76 | } 77 | 78 | public void breakEnhForArray(Object[] i) { 79 | outer: for (Object o : i) { 80 | for (Object o2 : i) { 81 | break outer; 82 | } 83 | } 84 | } 85 | 86 | public void contEnhForArray(Object[] i) { 87 | outer: for (Object o : i) { 88 | for (Object o2 : i) { 89 | continue outer; 90 | } 91 | } 92 | } 93 | 94 | public void sameLabel() { 95 | test: { 96 | } 97 | test: { 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/LiteralTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class LiteralTest { 4 | void m() { 5 | char c0 = ' '; 6 | char c1 = '\u2233'; 7 | char[] c2 = new char[] { ' ' }; 8 | char c3 = '\uD800'; // These two are not valid as c++ utf-16 character 9 | char c4 = '\uDFFF'; // literals 10 | char c5 = '\u00f0'; 11 | String s0 = " "; 12 | String s1 = "\u2233"; 13 | String s2 = "\uD800x\uD902"; // Also not valid 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/LocalClassTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class LocalClassTest { 4 | static ParamConstructor staticField = new ParamConstructor(3) { 5 | @Override 6 | public int getV() { 7 | return slct.localVar(); 8 | } 9 | }; 10 | 11 | ParamConstructor field = new ParamConstructor(3) { 12 | @Override 13 | public int getV() { 14 | return lct.localVar(); 15 | } 16 | }; 17 | 18 | LocalClassTest lct; 19 | 20 | static LocalClassTest slct; 21 | 22 | public int testLocalParamConstructor() { 23 | ParamConstructor lpc = new ParamConstructor(3) { 24 | @Override 25 | public int getV() { 26 | return 5; 27 | } 28 | }; 29 | 30 | return lpc.getV(); 31 | } 32 | 33 | public int testClosure(final int p) { 34 | ParamConstructor lpc = new ParamConstructor(3) { 35 | @Override 36 | public int getV() { 37 | return p; 38 | } 39 | }; 40 | 41 | return lpc.getV(); 42 | } 43 | 44 | public int testClassClosure(final Empty p) { 45 | ParamConstructor lpc = new ParamConstructor(3) { 46 | @Override 47 | public int getV() { 48 | return p.hashCode(); 49 | } 50 | }; 51 | 52 | return lpc.getV(); 53 | } 54 | 55 | public int testArrayAccess() { 56 | ParamConstructor lpc = new ParamConstructor(3) { 57 | @Override 58 | public int run(int[] x) { 59 | return testClosure(x[0]); 60 | } 61 | }; 62 | 63 | return lpc.run(new int[] { 5 }); 64 | } 65 | 66 | public int testSameClassAccess() { 67 | ParamConstructor lpc = new ParamConstructor(3) { 68 | @Override 69 | public int run(int[] x) { 70 | LocalClassTest same = lct; 71 | return same.testClosure(4); 72 | } 73 | 74 | public int param2() { 75 | LocalClassTest same = lct.lct; 76 | return same.testClosure(4); 77 | } 78 | }; 79 | 80 | return lpc.run(null); 81 | } 82 | 83 | public int testNestedClass() { 84 | ParamConstructor lpc = new ParamConstructor(3) { 85 | @Override 86 | public int run(int[] x) { 87 | ParamConstructor lpc2 = new ParamConstructor(3) { 88 | @Override 89 | public int run(int[] x) { 90 | return lct.testClosure(x[0]); 91 | } 92 | }; 93 | 94 | return lpc2.run(new int[] { 10 }); 95 | } 96 | }; 97 | 98 | return lpc.run(new int[] { 10 }); 99 | } 100 | 101 | public int testNestedClosure(final int outermost) { 102 | ParamConstructor lpc = new ParamConstructor(3) { 103 | @Override 104 | public int run(int[] x) { 105 | ParamConstructor lpc2 = new ParamConstructor(3) { 106 | @Override 107 | public int run(int[] x) { 108 | return x[0] + outermost; 109 | } 110 | }; 111 | 112 | return lpc2.run(new int[] { 10 }); 113 | } 114 | }; 115 | 116 | return lpc.run(new int[] { 10 }); 117 | } 118 | 119 | public static int testStatic(final int x) { 120 | ParamConstructor lpc = new ParamConstructor(3) { 121 | @Override 122 | public int getV() { 123 | return 5; 124 | } 125 | }; 126 | 127 | return lpc.getV(); 128 | } 129 | 130 | public int testThisMethod(final int x) { 131 | ParamConstructor lpc = new ParamConstructor(3) { 132 | @Override 133 | public int getV() { 134 | return LocalClassTest.this.testArrayAccess(); 135 | } 136 | }; 137 | 138 | return lpc.getV(); 139 | } 140 | 141 | static { 142 | ParamConstructor lpc = new ParamConstructor(3) { 143 | @Override 144 | public int getV() { 145 | return 90; 146 | } 147 | }; 148 | } 149 | 150 | public int localVar() { 151 | final Object o = new Object(); 152 | 153 | class C { 154 | public int m() { 155 | return o.hashCode(); 156 | } 157 | } 158 | 159 | C c = new C(); 160 | return c.m(); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/MainTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class MainTest { 4 | public static void main(String[] args) { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Method.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Method { 4 | public void m() { 5 | } 6 | 7 | public int n() { 8 | return 0; 9 | } 10 | 11 | public void overload() { 12 | } 13 | 14 | public void overload(int x) { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Names.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Names { 4 | public class Private { 5 | private int init; 6 | 7 | private void init() { 8 | this.init = 6; 9 | } 10 | } 11 | 12 | public class Public { 13 | public int init; 14 | protected int m; 15 | 16 | public void init(int init) { 17 | this.init = init; 18 | init(init); 19 | } 20 | 21 | public void x(int x) { 22 | x(x); 23 | } 24 | } 25 | 26 | public class Derived extends Public { 27 | public int x; 28 | 29 | public void m() { 30 | this.init = 5; 31 | this.m = 6; 32 | int init = 5; 33 | init(init); 34 | int x = init; 35 | x(x); // need to find x in base class! 36 | } 37 | } 38 | 39 | public class Test { 40 | Object o; 41 | } 42 | 43 | public static class FieldNamedLikeClass { 44 | public static void m(Empty e) { 45 | // Field below might redefine meaning of name "Empty" if the class 46 | // reference remains unqualified here 47 | e = new Empty(); 48 | } 49 | 50 | // static final field with same name as class 51 | public static final Empty Empty = new Empty(); 52 | } 53 | 54 | public static class MethodNamedLikeClass { 55 | public static void m(Empty e) { 56 | // Field below might redefine meaning of name "Empty" if the class 57 | // reference remains unqualified here 58 | e = new Empty(); 59 | } 60 | 61 | // static final field with same name as class 62 | public static void Empty() { 63 | Empty e = new Empty(); 64 | } 65 | } 66 | } 67 | 68 | // Valid in Java but messes up filenames in Makefile 69 | class Funny$Name { 70 | } -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/NestedAccessTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class NestedAccessTest { 4 | static final int x = NestedTest.Static.Y; 5 | static final int z = NestedTest.Static.s(); 6 | 7 | final int y = 5; 8 | 9 | static final NestedAccessTest NAT = new NestedAccessTest(); 10 | 11 | int m() { 12 | return NestedTest.Static.Y; 13 | } 14 | 15 | static class T { 16 | static final int a = x; 17 | static final int b0 = NAT.m(); 18 | static final int b1 = NAT.NAT.m(); 19 | 20 | static final int c0 = NAT.y; 21 | static final int c1 = NAT.NAT.y; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/NestedTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class NestedTest { 4 | private static int x; 5 | 6 | private static int a() { 7 | return 5; 8 | } 9 | 10 | public static class Static { 11 | public static final int Y = 5; 12 | 13 | static int s() { 14 | return Y; 15 | } 16 | 17 | int m() { 18 | return x; 19 | } 20 | } 21 | 22 | public static class SubStatic extends Static { 23 | int x() { 24 | return m() + a(); 25 | } 26 | } 27 | 28 | public class Inner { 29 | int m() { 30 | return x; 31 | } 32 | } 33 | 34 | public class SubInner extends Inner { 35 | int x() { 36 | return m() + a(); 37 | } 38 | } 39 | 40 | public void m() { 41 | class Local { 42 | int m2() { 43 | return x + a(); 44 | } 45 | } 46 | 47 | Object o = new Object() { 48 | int m3() { 49 | return x + a(); 50 | } 51 | 52 | int m4() { 53 | int y = NestedTest.this.hashCode(); 54 | Object o3 = new Object() { 55 | public int m4() { 56 | return x; 57 | } 58 | }; 59 | 60 | return o3.hashCode(); 61 | } 62 | }; 63 | 64 | new Static(); 65 | new Inner(); 66 | new Local(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Object.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | // check if this name confuses relative names 4 | public class Object { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ParamConstructor.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class ParamConstructor { 4 | private final int v; 5 | 6 | public ParamConstructor(int v) { 7 | this.v = v; 8 | } 9 | 10 | public int getV() { 11 | return v; 12 | } 13 | 14 | public int run(int[] x) { 15 | return 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/PrimitiveTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class PrimitiveTest { 4 | boolean b; 5 | char c; 6 | double d; 7 | float f; 8 | int i; 9 | long l; 10 | short s; 11 | 12 | boolean bi = false; 13 | char ci = 'c'; 14 | double di = 0.1; 15 | float fi = 0.1f; 16 | int ii = 5; 17 | long li = 5l; 18 | short si = 4; 19 | 20 | static boolean sb; 21 | static char sc; 22 | static double sd; 23 | static float sf; 24 | static int six; 25 | static long sl; 26 | static short ss; 27 | 28 | static boolean sbi = false; 29 | static char sci = 'c'; 30 | static double sdi = 0.1; 31 | static float sfi = 0.1f; 32 | static int sii = 5; 33 | static long sli = 5l; 34 | static short ssi = 4; 35 | 36 | void f() { 37 | float f0 = 1; 38 | float f1 = 2; 39 | float f2 = f0 % f1; // fmod in c++ 40 | f2 %= f1; 41 | } 42 | 43 | void d() { 44 | double f0 = 1; 45 | double f1 = 2; 46 | double f2 = f0 % f1; // fmod in c++ 47 | f2 %= f1; 48 | 49 | final int a = 0, b = 1; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ReturnTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | /** Return covariance tests */ 4 | public class ReturnTest { 5 | @Override 6 | protected Void clone() throws CloneNotSupportedException { 7 | return null; 8 | } 9 | 10 | public static class A { 11 | public java.lang.Object a() { 12 | return null; 13 | } 14 | } 15 | 16 | public static class B extends A { 17 | 18 | } 19 | 20 | public static class C extends B { 21 | @Override 22 | public B a() { 23 | return null; 24 | } 25 | } 26 | 27 | public B c(C c) { 28 | return c.a(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/ShiftTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class ShiftTest { 4 | public int left() { 5 | return 1 << 5; 6 | } 7 | 8 | public int right() { 9 | return 1 >> 5; 10 | } 11 | 12 | public int rightUnsigned() { 13 | return -1 >>> 5; 14 | } 15 | 16 | public int rightUnsignedAssign() { 17 | int i = -5; 18 | i >>>= 1; 19 | return i; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/StaticImportTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | import static java.lang.Math.sqrt; 4 | import static java.lang.reflect.Modifier.ABSTRACT; 5 | 6 | public class StaticImportTest { 7 | int x() { 8 | return (int) sqrt(ABSTRACT); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/StringTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class StringTest { 4 | public String field; 5 | 6 | public String fieldInit = "Test"; 7 | 8 | public static String statField; 9 | 10 | public static String statInitField = "Test"; 11 | 12 | public static String[] array; 13 | 14 | public static String[] arrayInit = { "a", "b", "c" }; 15 | 16 | public static String[] newArrayInit = new String[] { "a", "b", "c" }; 17 | 18 | public String ret() { 19 | return "Test"; 20 | } 21 | 22 | public String join() { 23 | return "Test" + "Test2"; 24 | } 25 | 26 | public String multiJoin() { 27 | return join() + "Test3" + "Test4"; 28 | } 29 | 30 | public String builder() { 31 | return "" + new StringBuilder("yy"); 32 | } 33 | 34 | public String assign() { 35 | String str1 = "Test"; 36 | str1 += "Test2"; 37 | str1 += null; 38 | return str1; 39 | } 40 | 41 | public void arrayAssign(String[] x) { 42 | x[0] = x[0] + "Test"; 43 | x[0] += "Test"; 44 | x[0] += null; 45 | } 46 | 47 | public String primitives() { 48 | return "" + 1 + 1.2 + 'c'; 49 | } 50 | 51 | public String objects() { 52 | return "" + this; 53 | } 54 | 55 | public String nulls() { 56 | return "" + null + null + ""; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Sub.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Sub extends Empty { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/SuperTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class SuperTest extends ConstructorTest { 4 | public SuperTest() { 5 | this(6); 6 | } 7 | 8 | public SuperTest(int i) { 9 | super(i); 10 | } 11 | 12 | static class S { 13 | } 14 | 15 | static class T extends S { 16 | T() { 17 | super(); 18 | } 19 | } 20 | 21 | static class Y { 22 | Y(String x) { 23 | } 24 | 25 | static void m() { 26 | } 27 | } 28 | 29 | static class X extends Y { 30 | X() { 31 | super("Test"); 32 | } 33 | 34 | void n() { 35 | super.m(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/SyncTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class SyncTest { 4 | public int m(int x) { 5 | synchronized (this) { 6 | return x * 6; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/SyntheticTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class SyntheticTest { 4 | public Integer testTypeBinding() { 5 | // Integer implements Comparable which needs a compareTo bridge 6 | return new Integer(5); 7 | } 8 | 9 | public StringBuffer testCovariantReturn() { 10 | // StringBuffer has a covariant return type bridge that shouldn't show 11 | // up 12 | return new StringBuffer(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/TryTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class TryTest { 4 | public int tryCatch() { 5 | int i; 6 | try { 7 | throw new Error(); 8 | } catch (Throwable t) { 9 | i = 6; 10 | } 11 | 12 | return i; 13 | } 14 | 15 | public int tryFinally(int i) { 16 | try { 17 | if (i < 5) 18 | throw new Error(); 19 | } finally { 20 | i = 6; 21 | } 22 | 23 | return i; 24 | } 25 | 26 | public int tryCatchFinally(int i) { 27 | try { 28 | if (i < 5) 29 | throw new Error(); 30 | } catch (Throwable t) { 31 | i = 42; 32 | } finally { 33 | i = 6; 34 | } 35 | 36 | return i; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/VarargTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class VarargTest { 4 | public void m(int a, int... b) { 5 | 6 | } 7 | 8 | public void m2() { 9 | m(1); 10 | m(1, 2); 11 | m(1, 2, 3); 12 | m(1, 2, 3, 4); 13 | } 14 | 15 | public void m3() { 16 | m(1, new int[] { 1, 2 }); 17 | } 18 | 19 | public static class VA { 20 | 21 | } 22 | 23 | public void m4(VA... x) { 24 | } 25 | 26 | public void m5() { 27 | VA[] x = new VA[0]; 28 | m4(x); 29 | } 30 | 31 | public void m6(java.lang.Object... x) { 32 | m6(4, "rte"); 33 | m6(new Object[] {}); 34 | m6(new Object[] {}, ""); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/Volatile.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test; 2 | 3 | public class Volatile { 4 | volatile int x; 5 | volatile Volatile v; 6 | static volatile Volatile sv; 7 | static volatile int sx; 8 | 9 | int m() { 10 | x = x++; 11 | x = ++x; 12 | v.x++; 13 | java.lang.Object o = v; 14 | return o.hashCode() + v.hashCode() + x + v.v.hashCode(); 15 | } 16 | 17 | void m2() { 18 | if (!(v instanceof V2)) { 19 | v = v; 20 | } 21 | } 22 | 23 | static int sm() { 24 | sx = sx++; 25 | sx = ++sx; 26 | sv.sx++; 27 | sv.x++; 28 | java.lang.Object o = sv; 29 | return o.hashCode() + sv.hashCode() + sx + sv.x; 30 | } 31 | 32 | static void sm2() { 33 | if (!(sv instanceof V2)) { 34 | sv = sv; 35 | } 36 | } 37 | 38 | public static class V2 extends Volatile { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/a/Empty.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.a; 2 | 3 | public class Empty { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/Classes.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | import se.arnetheduck.j2c.test.Sub; 5 | 6 | public class Classes { 7 | Empty[] h; 8 | 9 | Sub[] h2; 10 | 11 | Object[] x() { 12 | Empty[] ee = h2; 13 | ee[0] = ee[1]; 14 | return ee; 15 | } 16 | 17 | Empty[] hclone() { 18 | return h.clone(); 19 | } 20 | 21 | Empty[] hh() { 22 | return new Empty[] { null, new Empty(), new Sub() }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/Covariance.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class Covariance { 6 | public static abstract class Base { 7 | public abstract Empty[] m(); 8 | } 9 | 10 | public static class Child extends Base { 11 | @Override 12 | public Empty[] m() { 13 | return null; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/Interfaces.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | import se.arnetheduck.j2c.test.IEmpty; 4 | import se.arnetheduck.j2c.test.ISub; 5 | 6 | public class Interfaces { 7 | IEmpty[] h; 8 | 9 | ISub[] h2; 10 | 11 | Object[] x() { 12 | IEmpty[] ee = h2; 13 | return ee; 14 | } 15 | 16 | IEmpty[] hclone() { 17 | return h.clone(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/Mixed.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | import se.arnetheduck.j2c.test.IEmpty; 4 | import se.arnetheduck.j2c.test.ISub; 5 | 6 | public class Mixed { 7 | public static class A implements IEmpty { 8 | 9 | } 10 | 11 | public static class B extends A implements ISub { 12 | 13 | } 14 | 15 | A[] m(B[] a) { 16 | return a; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/MultiArray.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | public class MultiArray { 4 | int[][] a = new int[1][]; 5 | int[][][] b = new int[1][][]; 6 | 7 | MultiArray() { 8 | a = new int[1][1]; 9 | b = new int[1][a.length][2]; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/Primitives.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | public class Primitives { 4 | int[] a; 5 | int b[]; 6 | 7 | int[] c() { 8 | return null; 9 | } 10 | 11 | void d(int[] e) { 12 | } 13 | 14 | void f(int g[]) { 15 | } 16 | 17 | int[] aclone() { 18 | return a.clone(); 19 | } 20 | 21 | int aclone2()[] { 22 | return a.clone(); 23 | } 24 | 25 | char[] cc() { 26 | int a[], b[]; 27 | a = new int[0]; 28 | b = a; 29 | return new char[] { 'a', 10 }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/TestArray.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | // Check name escape rule for arrays 4 | public class TestArray { 5 | TestArray[] a; 6 | 7 | Object m(TestArrayArray b) { 8 | return b.m(this); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/array/TestArrayArray.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.array; 2 | 3 | public class TestArrayArray { 4 | Object m(TestArray a) { 5 | return a.a; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/asm/int32_t.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.asm; 2 | 3 | public class int32_t { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/b/OtherArrayTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.b; 2 | 3 | import se.arnetheduck.j2c.test.a.Empty; 4 | 5 | public class OtherArrayTest { 6 | // Arrays of types from other packages are not imported automagically so 7 | // they should be fully qualified 8 | Empty[] x; 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/enums/AnonymousConstants.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.enums; 2 | 3 | public enum AnonymousConstants { 4 | RED { 5 | @Override 6 | public int i() { 7 | return 0; 8 | } 9 | }, 10 | 11 | GREEN { 12 | @Override 13 | public int i() { 14 | return 1; 15 | } 16 | }, 17 | 18 | BLUE { 19 | @Override 20 | public int i() { 21 | return 2; 22 | } 23 | }; 24 | 25 | public abstract int i(); 26 | 27 | public AnonymousConstants c; 28 | } 29 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/enums/Ctor.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.enums; 2 | 3 | public class Ctor { 4 | public static final boolean B = false; 5 | 6 | public static enum Y { 7 | X(false), Z(B); 8 | 9 | Y(boolean x) { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/enums/EnumBridge.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.enums; 2 | 3 | import java.util.Comparator; 4 | 5 | import se.arnetheduck.j2c.test.Empty; 6 | 7 | public enum EnumBridge implements Comparator { 8 | FORWARD { 9 | @Override 10 | public int compare(Empty f1, Empty f2) { 11 | return 0; 12 | } 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/enums/ImplicitMethods.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.enums; 2 | 3 | // Test that we get values and valueOf when generics are present 4 | public class ImplicitMethods { 5 | enum Y { 6 | X 7 | } 8 | 9 | void m() { 10 | Y x = Y.valueOf("X"); 11 | Y[] y = Y.values(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/enums/SimpleEnum.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.enums; 2 | 3 | public enum SimpleEnum { 4 | RED, GREEN, BLUE 5 | } 6 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/BaseCall.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | public class BaseCall { 4 | public interface I extends Implement.I { 5 | @Override 6 | void m(T t); 7 | 8 | @Override 9 | T m2(); 10 | } 11 | 12 | public static class X extends Implement.S implements I { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/DiamondImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class DiamondImplements { 6 | public interface I { 7 | T m(); 8 | } 9 | 10 | public interface J extends I { 11 | } 12 | 13 | public interface K extends I { 14 | @Override 15 | T m(); 16 | } 17 | 18 | public class A implements J { 19 | @Override 20 | public T m() { 21 | return null; 22 | } 23 | } 24 | 25 | public class B extends A implements K, J { 26 | } 27 | 28 | I m() { 29 | new B(); 30 | return new A(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/Fields.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class Fields { 6 | public static class A { 7 | T t; 8 | } 9 | 10 | public static class B extends A { 11 | Empty m() { 12 | t = new Empty(); 13 | return t; 14 | } 15 | 16 | Empty n() { 17 | this.t = new Empty(); 18 | return this.t; 19 | } 20 | } 21 | 22 | Empty m(A a) { 23 | Empty x = a.t; 24 | return a.t; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/GenHiding.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | 4 | public class GenHiding { 5 | public interface Collection { 6 | boolean addAll(Collection c); 7 | 8 | } 9 | 10 | public static abstract class AbstractCollection implements Collection { 11 | @Override 12 | public boolean addAll(Collection c) { 13 | return true; 14 | } 15 | } 16 | 17 | public interface List extends Collection { 18 | @Override 19 | boolean addAll(Collection c); 20 | 21 | boolean addAll(int index, Collection c); 22 | } 23 | 24 | static public abstract class AbstractList extends AbstractCollection 25 | implements List { 26 | @Override 27 | public boolean addAll(int index, Collection c) { 28 | return true; 29 | } 30 | } 31 | 32 | public static abstract class AbstractSequentialList extends 33 | AbstractList { 34 | @Override 35 | public boolean addAll(int index, Collection c) { 36 | return true; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/GenericBoxing.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | public class GenericBoxing { 4 | public interface T { 5 | X value(); 6 | } 7 | 8 | long m(T t) { 9 | // Auto-unboxing should happen as X is guaranteed to extend Long 10 | return t.value(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/Implement.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | public class Implement { 4 | public interface I { 5 | void m(T t); 6 | 7 | T m2(); 8 | } 9 | 10 | public static class S implements I { 11 | @Override 12 | public void m(T t) { 13 | } 14 | 15 | @Override 16 | public T m2() { 17 | return null; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/MethodInvocationCast.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | import se.arnetheduck.j2c.test.Method; 5 | import se.arnetheduck.j2c.test.StringTest; 6 | 7 | public class MethodInvocationCast { 8 | public interface I { 9 | X m(); 10 | 11 | void m2(X x); 12 | } 13 | 14 | public interface B { 15 | } 16 | 17 | B m(I i) { 18 | return i.m(); 19 | } 20 | 21 | void m2(I x, Fields.A a) { 22 | a.t.m(); 23 | x.m2(null); 24 | } 25 | 26 | private static final I canonicalTypes = null; 27 | 28 | static { 29 | canonicalTypes.m2(new StringTest()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/MultiBound.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | public class MultiBound { 4 | interface A { 5 | void a(); 6 | } 7 | 8 | interface B { 9 | void b(); 10 | } 11 | 12 | void m(T t) { 13 | A a = t; 14 | B b = t; 15 | t.a(); 16 | t.b(); 17 | a(t); 18 | b(t); 19 | } 20 | 21 | void a(A a) { 22 | } 23 | 24 | void b(B b) { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/NamedLocal.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | public class NamedLocal { 4 | public void m() { 5 | class S { 6 | } 7 | new S(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/Raw.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | public class Raw { 4 | Fields.A a; 5 | Implement.I i; 6 | 7 | void m() { 8 | a.t.notify(); 9 | i.m2(); 10 | i.m(null); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/ReturnCovariance.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class ReturnCovariance { 6 | // Generic declaration 7 | interface I { 8 | A m(); 9 | } 10 | 11 | // Simple declaration 12 | interface J { 13 | Empty m(); 14 | } 15 | 16 | public class SI implements I { 17 | @Override 18 | public A m() { 19 | return null; 20 | } 21 | } 22 | 23 | public class SJ implements J { 24 | @Override 25 | public A m() { 26 | return null; 27 | } 28 | } 29 | 30 | public class TI implements I { 31 | @Override 32 | public Empty m() { 33 | return null; 34 | } 35 | } 36 | 37 | public class TJ implements J { 38 | @Override 39 | public Empty m() { 40 | return null; 41 | } 42 | } 43 | 44 | public interface Both extends I, J { 45 | 46 | } 47 | 48 | // Make sure all variants that need it get a dependency on Empty 49 | public class USIJ extends SI implements J { 50 | } 51 | 52 | public class USJJ extends SJ implements J { 53 | } 54 | 55 | public class UTIJ extends TI implements J { 56 | } 57 | 58 | public class UTJJ extends TJ implements J { 59 | } 60 | 61 | public class USII extends SI implements I { 62 | } 63 | 64 | public class USJI extends SJ implements I { 65 | } 66 | 67 | public class UTII extends TI implements I { 68 | } 69 | 70 | public class UTJI extends TJ implements I { 71 | } 72 | 73 | public class UBothI extends TI implements Both { 74 | } 75 | 76 | public class UBothJ extends TJ implements Both { 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/generics/SuperBridgeCall.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.generics; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class SuperBridgeCall { 6 | public interface I { 7 | void m(X i); 8 | } 9 | 10 | public class S { 11 | public void m(Empty e) { 12 | } 13 | } 14 | 15 | public class T extends S implements I { 16 | } 17 | 18 | public class U extends T implements I { 19 | } 20 | 21 | T m(I i) { 22 | i.m(null); 23 | 24 | return new T(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/hiding/A.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.hiding; 2 | 3 | public interface A { 4 | public int B = 42; 5 | } -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/hiding/B.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.hiding; 2 | 3 | public interface B extends A { 4 | 5 | } -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/hiding/HiddenByType.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.hiding; 2 | 3 | public class HiddenByType { 4 | public class C implements B { 5 | int m() { 6 | return B; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/hiding/HiddenField.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.hiding; 2 | 3 | public class HiddenField { 4 | public class A { 5 | int a() { 6 | return 0; 7 | } 8 | } 9 | 10 | public class B extends A { 11 | @Override 12 | int a() { 13 | return 0; 14 | } 15 | } 16 | 17 | public class C extends A { 18 | int a; 19 | } 20 | 21 | int m(A a, B b, C c) { 22 | return a.a() + b.a() + c.a() + c.a; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/hiding/HiddenMethod.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.hiding; 2 | 3 | public class HiddenMethod { 4 | public class A { 5 | int a; 6 | } 7 | 8 | public class B extends A { 9 | int a; 10 | } 11 | 12 | public class C extends A { 13 | int a() { 14 | return a; 15 | } 16 | } 17 | 18 | int m(A a, B b, C c) { 19 | return a.a + b.a + c.a + c.a(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/ConstExpr.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class ConstExpr { 4 | final byte yi = 4; 5 | final boolean bi = false; 6 | final char ci = 'c'; 7 | final double di = 0.1; 8 | final float fi = 0.1f; 9 | final int ii = 5; 10 | final long li = 5l; 11 | final short si = 4; 12 | 13 | static final byte syi = 4; 14 | static final boolean sbi = false; 15 | static final char sci = 'c'; 16 | static final double sdi = 0.1; 17 | static final float sfi = 0.1f; 18 | static final int sii = 5; 19 | static final long sli = 5l; 20 | static final short ssi = 4; 21 | 22 | // Constexpr in java but not c++ 23 | final String s = "hello"; 24 | static final String ss = "helloToo"; 25 | 26 | final Byte byi = 4; 27 | final Boolean bbi = false; 28 | final Character bci = 'c'; 29 | final Double bdi = 0.1; 30 | final Float bfi = 0.1f; 31 | final Integer bii = 5; 32 | final Long bli = 5l; 33 | final Short bsi = 4; 34 | 35 | static final Byte bsyi = 4; 36 | static final Boolean bsbi = false; 37 | static final Character bsci = 'c'; 38 | static final Double bsdi = 0.1; 39 | static final Float bsfi = 0.1f; 40 | static final Integer bsii = 5; 41 | static final Long bsli = 5l; 42 | static final Short bssi = 4; 43 | 44 | void m(Object... o) { 45 | m(bi, ci, di, fi, ii, li, si, s, ss); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/Constructor.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class Constructor { 4 | static class Field { 5 | int x; 6 | 7 | Field() { 8 | x = 5; 9 | } 10 | } 11 | 12 | static class Delegated { 13 | int x; 14 | 15 | Delegated() { 16 | this(5); 17 | } 18 | 19 | Delegated(int x) { 20 | this.x = x; 21 | } 22 | } 23 | 24 | static class Inherited extends Delegated { 25 | Inherited() { 26 | super(); 27 | } 28 | 29 | Inherited(int x) { 30 | super(5); 31 | } 32 | } 33 | 34 | static class PrivateBase extends PrivateConstructor { 35 | public PrivateBase(int x) { 36 | super(x); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/InitBeforeCons.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class InitBeforeCons { 4 | public static class Field { 5 | int x = 5; 6 | 7 | Field() { 8 | x = 6; 9 | } 10 | 11 | Field(int x) { 12 | this.x = x; 13 | } 14 | } 15 | 16 | static class Inherited extends Field { 17 | { 18 | x = 7; 19 | } 20 | 21 | Inherited() { 22 | super(8); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/Instance.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class Instance { 4 | static class Field { 5 | int x = 5; 6 | } 7 | 8 | static class Block { 9 | int x; 10 | { 11 | x = 5; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/PrivateConstructor.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class PrivateConstructor { 4 | private PrivateConstructor() { 5 | } 6 | 7 | public PrivateConstructor(int x) { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/Static.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class Static { 4 | static class Field { 5 | static int x = 5; 6 | } 7 | 8 | static class Block { 9 | static int x; 10 | static { 11 | x = 5; 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/StaticClosure.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class StaticClosure { 4 | static { 5 | final int p = 5; 6 | new Object() { 7 | void run() { 8 | int i = p; 9 | } 10 | }; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/init/StringDep.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.init; 2 | 3 | public class StringDep { 4 | // Check that we get correct includes even if we make no strings 5 | static final String x = ConstExpr.ss + ConstExpr.ss + ConstExpr.ss; 6 | } 7 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/interfaces/SameName.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.interfaces; 2 | 3 | public class SameName { 4 | public interface I { 5 | void m(); 6 | } 7 | 8 | public interface J { 9 | void m(); 10 | } 11 | 12 | public interface K extends I, J { 13 | 14 | } 15 | 16 | public class S implements I, J { 17 | @Override 18 | public void m() { 19 | } 20 | } 21 | 22 | public abstract class T implements K { 23 | } 24 | 25 | void m(I i, J j, K k, S s, T t) { 26 | i.m(); 27 | j.m(); 28 | k.m(); 29 | s.m(); 30 | t.m(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/interfaces/SameNameOverload.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.interfaces; 2 | 3 | public class SameNameOverload { 4 | public interface I { 5 | void m(); 6 | } 7 | 8 | public interface J { 9 | void m(int i); 10 | } 11 | 12 | public interface K extends I, J { 13 | 14 | } 15 | 16 | public class S implements I, J { 17 | @Override 18 | public void m() { 19 | } 20 | 21 | @Override 22 | public void m(int i) { 23 | } 24 | } 25 | 26 | public abstract class T implements K { 27 | } 28 | 29 | void m(I i, J j, K k, S s, T t) { 30 | i.m(); 31 | j.m(1); 32 | k.m(); 33 | k.m(1); 34 | s.m(); 35 | s.m(1); 36 | t.m(); 37 | t.m(1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/interfaces/UnqualifiedInterfaceField.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.interfaces; 2 | 3 | public class UnqualifiedInterfaceField { 4 | public interface I { 5 | int i = 42; 6 | } 7 | 8 | public class S implements I { 9 | int m() { 10 | return i; 11 | } 12 | } 13 | 14 | public class Hidden implements I { 15 | void m(int x) { 16 | } 17 | 18 | int i() { 19 | m(i); 20 | return i; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/AbstractWithInterface.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class AbstractWithInterface { 4 | public interface A { 5 | int m(); 6 | } 7 | 8 | public static abstract class S implements A { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/AmbiguousOverloads.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class AmbiguousOverloads { 4 | public AmbiguousOverloads(AmbiguousOverloads x) { 5 | } 6 | 7 | public AmbiguousOverloads(long v) { 8 | } 9 | 10 | void m() { 11 | new AmbiguousOverloads(0); // ptr vs int ambiguity 12 | new AmbiguousOverloads(0L); // ptr vs long ambiguity 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/AmbiguousSuper.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class AmbiguousSuper { 4 | public interface I { 5 | void m(); 6 | } 7 | 8 | public interface J extends I { 9 | } 10 | 11 | public class S { 12 | public void m() { 13 | } 14 | } 15 | 16 | public abstract class T extends S implements J { 17 | 18 | } 19 | 20 | public class U extends S implements J { 21 | 22 | } 23 | 24 | void m(I i, S s, T t, U u) { 25 | i.m(); 26 | s.m(); 27 | t.m(); 28 | u.m(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/BaseCall.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class BaseCall { 4 | public interface I extends Implement.I { 5 | @Override 6 | void m(Object t); 7 | 8 | @Override 9 | Object m2(); 10 | } 11 | 12 | public static class X extends Implement.S implements I { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/BaseFinalImpl.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class BaseFinalImpl { 4 | public interface I { 5 | void m(); 6 | 7 | void n(); 8 | } 9 | 10 | public interface J { 11 | void m(); 12 | } 13 | 14 | public static class S implements J { 15 | @Override 16 | public final void m() { 17 | } 18 | } 19 | 20 | public abstract static class T extends S { 21 | } 22 | 23 | public abstract static class U extends T implements I { 24 | @Override 25 | public abstract void n(); 26 | } 27 | 28 | public static class V extends U { 29 | @Override 30 | public void n() { 31 | } 32 | } 33 | 34 | void m() { 35 | new S().m(); 36 | new V().m(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/BaseImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class BaseImplements { 4 | public interface I { 5 | void m(); 6 | 7 | void m(int a, int b); 8 | 9 | void n(); 10 | } 11 | 12 | public interface J extends I { 13 | } 14 | 15 | public static class A { 16 | public void m() { 17 | } 18 | } 19 | 20 | public static abstract class B extends A implements I { 21 | // No need to implement I.m() here 22 | void m(int x) { // ...but this could hide m() in C++ 23 | } 24 | 25 | @Override 26 | public abstract void n(); 27 | 28 | public void n(int c) { 29 | n(); 30 | n(5); 31 | } 32 | } 33 | 34 | public static class C implements I { 35 | @Override 36 | public void m() { 37 | } 38 | 39 | @Override 40 | public void n() { 41 | } 42 | 43 | @Override 44 | public void m(int a, int b) { 45 | } 46 | } 47 | 48 | public static class D extends C implements J { 49 | public void m(int i) { 50 | } 51 | } 52 | 53 | public I m() { 54 | return new D(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/ConstVars.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | // Local variables can be both const and constexpr 4 | public class ConstVars { 5 | int m(final int x) { 6 | final int y = x; 7 | final int z = 5; 8 | switch (z) { 9 | case z: 10 | return y; 11 | } 12 | 13 | return 0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/CovariantCircular.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class CovariantCircular { 4 | public class A { 5 | public Object a() { 6 | return null; 7 | } 8 | 9 | public Object b() { 10 | return null; 11 | } 12 | } 13 | 14 | public class B extends A { 15 | @Override 16 | public C a() { // Covariant to subtype 17 | return null; 18 | } 19 | 20 | @Override 21 | public B b() { // Covariant to self 22 | return null; 23 | } 24 | } 25 | 26 | public class C extends B { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/CovariantCircularDeep.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class CovariantCircularDeep { 4 | public static interface I { 5 | } 6 | 7 | public static abstract class A { 8 | public abstract I m(); 9 | } 10 | 11 | public static class B extends A implements I { 12 | @Override 13 | public C m() { 14 | return null; 15 | } // Needs C 16 | } 17 | 18 | public static class C extends A implements I { 19 | @Override 20 | public B m() { // Needs B - circular! 21 | return null; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/CovariantInterface.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class CovariantInterface { 6 | public interface I { 7 | Object m(); 8 | } 9 | 10 | public interface J extends I { 11 | @Override 12 | Empty m(); 13 | } 14 | 15 | public static class S implements I { 16 | @Override 17 | public Object m() { 18 | return null; 19 | } 20 | } 21 | 22 | public static class T extends S implements J { 23 | @Override 24 | public Empty m() { 25 | return null; 26 | } 27 | } 28 | 29 | void m() { 30 | S s = new S(); 31 | T t = new T(); 32 | I i = s; 33 | J j = t; 34 | 35 | Object o = s.m(); 36 | Empty e = t.m(); 37 | o = i.m(); 38 | e = j.m(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/CovariantReturn.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | import se.arnetheduck.j2c.test.DefaultVirtual; 4 | import se.arnetheduck.j2c.test.NestedTest; 5 | 6 | public class CovariantReturn { 7 | public static class Static extends NestedTest.Static { 8 | 9 | } 10 | 11 | public static class C { 12 | NestedTest.Static m() { 13 | return null; 14 | } 15 | } 16 | 17 | public static class D extends C { 18 | @Override 19 | Static m() { 20 | return null; 21 | } 22 | } 23 | 24 | public static class E extends DefaultVirtual { 25 | Static m() { 26 | return null; 27 | } 28 | } 29 | 30 | void m(C c, D d, E e) { 31 | c.m(); 32 | d.m(); 33 | e.m(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/CrossCovariant.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class CrossCovariant { 4 | public interface I { 5 | } 6 | 7 | public static class A { 8 | I m() { 9 | return null; 10 | } 11 | } 12 | 13 | public static class B extends A implements I { 14 | @Override 15 | C m() { 16 | return null; 17 | } 18 | } 19 | 20 | public static class C extends A implements I { 21 | @Override 22 | B m() { 23 | return null; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/DefaultVirtualOverride.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | import se.arnetheduck.j2c.test.DefaultVirtual; 4 | import se.arnetheduck.j2c.test.NestedTest; 5 | 6 | public class DefaultVirtualOverride { 7 | public static abstract class S extends DefaultVirtual { 8 | abstract NestedTest.Static m(); 9 | } 10 | 11 | public static class T extends S { 12 | @Override 13 | NestedTest.Static m() { 14 | return null; 15 | } 16 | } 17 | 18 | void m() { 19 | new T().m(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/DiamondImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class DiamondImplements { 4 | public interface I { 5 | int m(); 6 | } 7 | 8 | public interface J extends I { 9 | } 10 | 11 | public interface K extends I { 12 | @Override 13 | int m(); 14 | } 15 | 16 | public class A implements J { 17 | @Override 18 | public int m() { 19 | return 0; 20 | } 21 | } 22 | 23 | public class B extends A implements K, J { 24 | } 25 | 26 | I m() { 27 | new B(); 28 | return new A(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/DoubleImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class DoubleImplements { 4 | public interface I { 5 | int m(); 6 | } 7 | 8 | public interface J { 9 | int m(); 10 | } 11 | 12 | public class A { 13 | public int m() { 14 | return 0; 15 | } 16 | } 17 | 18 | public class B extends A implements I, J { 19 | 20 | } 21 | 22 | I m() { 23 | new A(); 24 | return new B(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/DoubleInheritedImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class DoubleInheritedImplements { 4 | public interface I { 5 | int m(); 6 | } 7 | 8 | public interface J extends I { 9 | @Override 10 | int m(); 11 | } 12 | 13 | public static class A implements I { 14 | @Override 15 | public int m() { 16 | return 0; 17 | } 18 | } 19 | 20 | public static class B extends A implements J { 21 | 22 | } 23 | 24 | I m() { 25 | new B(); 26 | return new A(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/GenericBaseImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class GenericBaseImplements { 4 | public interface X { 5 | } 6 | 7 | public interface A { 8 | void m(); 9 | } 10 | 11 | public interface B extends A { 12 | @Override 13 | void m(); 14 | } 15 | 16 | public static class S implements B { 17 | @Override 18 | public void m() { 19 | } 20 | } 21 | 22 | A m() { 23 | return new S(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/GenericDoubleImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class GenericDoubleImplements { 4 | public interface I { 5 | int m(); 6 | } 7 | 8 | public interface J { 9 | int m(); 10 | } 11 | 12 | public class A { 13 | public int m() { 14 | return 0; 15 | } 16 | } 17 | 18 | public class B extends A implements I, J { 19 | 20 | } 21 | 22 | I m() { 23 | new A(); 24 | return new B(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/Hiding.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class Hiding { 4 | public interface A { 5 | int m(); 6 | } 7 | 8 | public interface B extends A { 9 | 10 | } 11 | 12 | public interface C extends B { 13 | int m(int a); 14 | } 15 | 16 | public abstract class S implements C { 17 | @Override 18 | public abstract int m(int a); 19 | 20 | public int m(int a, int b) { 21 | return a + b; 22 | } 23 | 24 | private int m(int a, int b, int c) { 25 | return m(a, b) + c; 26 | } 27 | } 28 | 29 | public class T extends S { 30 | @Override 31 | public int m() { 32 | return 0; 33 | } 34 | 35 | @Override 36 | public int m(int a) { 37 | return 0; 38 | } 39 | } 40 | 41 | public class U extends Implement.S { 42 | void m(int x) { 43 | } 44 | } 45 | 46 | void m(A a, B b, C c, S s, T t, U u) { 47 | a.m(); 48 | b.m(); 49 | c.m(); 50 | s.m(); 51 | c.m(1); 52 | s.m(1); 53 | s.m(1, 2); 54 | t.m(); 55 | t.m(1); 56 | u.m(null); 57 | u.m(1); 58 | } 59 | } -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/HidingStatic.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class HidingStatic { 4 | public static class A { 5 | public static void m() { 6 | } 7 | } 8 | 9 | public static class B extends A { 10 | public static void m(int x) { 11 | } 12 | } 13 | 14 | void m() { 15 | // In C++, m must be accessed through A as the method overload is 16 | // shadowed by B::m 17 | B.m(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/Implement.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class Implement { 4 | public interface I { 5 | void m(Object t); 6 | 7 | Object m2(); 8 | } 9 | 10 | public static class S implements I { 11 | @Override 12 | public void m(Object t) { 13 | } 14 | 15 | @Override 16 | public Object m2() { 17 | return null; 18 | } 19 | 20 | private void m() { // Private unhiding check (Hiding.java) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/ImplementOverloads.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class ImplementOverloads { 4 | public interface A { 5 | void m(int i); 6 | } 7 | 8 | public class S implements A { 9 | @Override 10 | public void m(int i) { 11 | } 12 | 13 | public void m(int i, int j) { 14 | } 15 | } 16 | 17 | public class T extends S implements A { 18 | void x() { 19 | m(1, 2); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/ImportStaticCall.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | 4 | public class ImportStaticCall { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/InheritedCovariant.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class InheritedCovariant { 4 | 5 | public interface I { 6 | } 7 | 8 | public class A { 9 | I m() { 10 | return null; 11 | } 12 | } 13 | 14 | public class B extends A implements I { 15 | @Override 16 | C m() { 17 | return null; 18 | } 19 | } 20 | 21 | public class C extends B { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/Overrides.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class Overrides { 4 | public interface A { 5 | int add(); 6 | } 7 | 8 | public interface B extends A { 9 | int add(int a); 10 | } 11 | 12 | public interface C extends B { 13 | int add(int a, int b); 14 | } 15 | 16 | int m(C c) { 17 | return c.add() + c.add(1) + c.add(1, 2); 18 | } 19 | 20 | public static class S { 21 | private void a() { 22 | } 23 | 24 | public void a(int a, int b) { 25 | } 26 | } 27 | 28 | public static class T extends S { 29 | public void a(int b) { 30 | } 31 | } 32 | 33 | public static class U extends S { 34 | private void a(int b) { 35 | } 36 | } 37 | 38 | void m(T t) { 39 | t.a(0); 40 | t.a(0, 4); 41 | } 42 | 43 | void m(U s) { 44 | s.a(0, 4); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/SimpleImplements.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class SimpleImplements { 4 | public interface I { 5 | void b(byte x); 6 | } 7 | 8 | public static class A { 9 | public void b(byte x) { 10 | } 11 | } 12 | 13 | public static class B extends A implements I { 14 | } 15 | 16 | I m() { 17 | return new B(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/StaticInvokes.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | import static se.arnetheduck.j2c.test.enums.AnonymousConstants.BLUE; 4 | 5 | public class StaticInvokes { 6 | static class A { 7 | static A s() { 8 | return null; 9 | } 10 | 11 | A m() { 12 | return null; 13 | } 14 | } 15 | 16 | void m(A a) { 17 | A.s(); // Static invoke 18 | a.s(); // Static invoke through instance 19 | A.s().s(); // Static invoke through returned instance 20 | 21 | a.m(); // Invoke through instance 22 | a.m().m(); // Invoke through returned instance 23 | 24 | BLUE.c.i(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/UnrelatedCovariant.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class UnrelatedCovariant { 4 | public interface I { 5 | Object m(); 6 | } 7 | 8 | public class A implements I { 9 | @Override 10 | public A m() { 11 | return null; 12 | } 13 | } 14 | 15 | public class B implements I { 16 | // A has a covariant return that shouldn't affect this covariance 17 | @Override 18 | public A m() { 19 | return null; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/methods/Using.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.methods; 2 | 3 | public class Using { 4 | interface A { 5 | void m(); 6 | } 7 | 8 | interface B extends A { 9 | void m(int a); 10 | } 11 | 12 | public static abstract class T implements A, B { 13 | public void m(int a, int b) { 14 | m(1); 15 | } 16 | 17 | @Override 18 | public abstract void m(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/Annot.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | import java.lang.annotation.Inherited; 4 | 5 | public class Annot { 6 | @Inherited 7 | public @interface X { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/ClosureInInitializer.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class ClosureInInitializer { 4 | public static Object m(final int x) { 5 | return new Object() { 6 | private final Object action = new Object() { 7 | public void run() { 8 | if (x == 0) { 9 | } 10 | } 11 | }; 12 | }; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/ClosureNames.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class ClosureNames { 4 | Object m() { 5 | final int x = 1; 6 | return new Object() { 7 | public int x() { 8 | return x; // same name as closed variable 9 | } 10 | }; 11 | } 12 | 13 | public static class X { 14 | public X(int o) { 15 | } 16 | } 17 | 18 | public static X n(final Object o) { 19 | return new X(1) { 20 | public int m() { 21 | // closure and generated constructor parameter for local type 22 | // have same name (param gets name from X.X(int o)) 23 | return o.hashCode(); 24 | } 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/Deep.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class Deep { 4 | void m() { 5 | class A { 6 | void m2() { 7 | class B { 8 | class C { 9 | } 10 | } 11 | } 12 | } 13 | } 14 | 15 | interface Y { 16 | } 17 | 18 | class X implements Y { 19 | } 20 | 21 | class A { 22 | class B extends X { 23 | class C { 24 | public Y get() { 25 | return B.this; 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/DeepSiblings.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class DeepSiblings { 4 | int a; 5 | 6 | class A { 7 | int x; 8 | 9 | A(int x) { 10 | this.x = x; 11 | } 12 | 13 | B m() { 14 | return new B(a); 15 | } 16 | } 17 | 18 | class B { 19 | int x; 20 | 21 | public B(int x) { 22 | this.x = x; 23 | } 24 | 25 | Object m() { 26 | return new Object() { 27 | A x() { 28 | return new A(a); 29 | } 30 | }; 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/DoubleAnon.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class DoubleAnon { 4 | public Object n() { 5 | return new Object() { 6 | final Object i = null; 7 | 8 | public Object next() { 9 | return new Object() { 10 | String k = i.toString(); 11 | }; 12 | } 13 | }; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/FieldInit.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class FieldInit { 4 | static int x = 5; 5 | 6 | static Object m() { 7 | return new Object() { 8 | final int y = x; 9 | }; 10 | } 11 | 12 | static Object closure(final int z) { 13 | return new Object() { 14 | final int y = z; 15 | }; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/GenericQualifiedThis.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | // Check that A.this works even when top level is generic 4 | public class GenericQualifiedThis { 5 | public class A { 6 | public class B { 7 | public A map() { 8 | return A.this; 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/LocalNamed.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class LocalNamed { 6 | Empty m() { 7 | class S extends Empty { 8 | } 9 | 10 | return new S(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/LocalNested.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | /** Nested type used as base for a local type */ 4 | public class LocalNested { 5 | public class A { 6 | } 7 | 8 | Object m() { 9 | return new A() { 10 | }; 11 | } 12 | 13 | Object n() { 14 | return new LocalPrivateCtor.A(2) { 15 | }; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/LocalOverload.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class LocalOverload { 4 | 5 | void m() { 6 | class C { 7 | void n() { 8 | } 9 | } 10 | new C().n(); 11 | } 12 | 13 | void m(int x) { 14 | class C { 15 | void o() { 16 | } 17 | } 18 | new C().o(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/LocalPrivateCtor.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class LocalPrivateCtor { 4 | public static class A { 5 | private A() { 6 | } 7 | 8 | public A(int m) { 9 | this(); 10 | } 11 | 12 | private A(int m, int n) { 13 | } 14 | } 15 | 16 | public static class B extends A { 17 | // Here, the private constructors should be accessible 18 | B() { 19 | super(); 20 | } 21 | 22 | B(int m, int n) { 23 | super(m, n); 24 | } 25 | } 26 | 27 | A m() { 28 | return new A(5) { 29 | }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/MethodParam.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class MethodParam { 4 | int a; 5 | 6 | public class A { 7 | void m(int x) { 8 | } 9 | 10 | void m2() { 11 | m(a); 12 | } 13 | 14 | void m3() { 15 | A b = new A(); 16 | b.m(a); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/NewPrimary.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class NewPrimary { 4 | public class A { 5 | } 6 | 7 | static A m(NewPrimary np) { 8 | return np.new A(); // Should become new A(np), not new A(this) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/OuterSubclass.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class OuterSubclass { 4 | int y; 5 | 6 | class A { 7 | int x; 8 | 9 | class B { 10 | } 11 | } 12 | 13 | class C extends A { 14 | class D extends B { 15 | int m() { 16 | return x + y; 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/QualifiedThisSuper.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class QualifiedThisSuper { 4 | public static class S { 5 | int n; 6 | 7 | int m() { 8 | int ret = n; 9 | ret += n; 10 | ret += n; 11 | ret += S.this.n; 12 | return ret; 13 | } 14 | 15 | public class Inner { 16 | int n; 17 | 18 | int m() { 19 | int ret = n; 20 | ret += n; 21 | ret += S.this.n; 22 | ret += S.this.m(); 23 | return ret; 24 | } 25 | } 26 | } 27 | 28 | public static class T extends S { 29 | int n; 30 | 31 | @Override 32 | int m() { 33 | int ret = n; 34 | ret += n; 35 | ret += T.this.n; 36 | ret += super.n; 37 | ret += T.super.n; 38 | ret += super.m(); 39 | ret += T.super.m(); 40 | return ret; 41 | } 42 | 43 | public class Inner extends S.Inner { 44 | int n; 45 | 46 | @Override 47 | int m() { 48 | int ret = n; 49 | ret += n; 50 | ret += T.this.n; 51 | ret += super.n; 52 | ret += T.super.n; 53 | ret += super.m(); 54 | ret += T.this.m(); 55 | ret += T.super.m(); 56 | return ret; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/SameName.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class SameName { 4 | static int m() { 5 | return 42; 6 | } 7 | 8 | int n() { 9 | return 42; 10 | } 11 | 12 | public class S { 13 | void x() { 14 | int n = n(); 15 | } 16 | } 17 | 18 | public static class T { 19 | void x() { 20 | int m = m(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/Siblings.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class Siblings { 4 | int a; 5 | 6 | class A { 7 | int x; 8 | 9 | A(int x) { 10 | this.x = x; 11 | } 12 | 13 | B m() { 14 | return new B(a); 15 | } 16 | } 17 | 18 | class B { 19 | int x; 20 | 21 | public B(int x) { 22 | this.x = x; 23 | } 24 | 25 | A m() { 26 | return new A(a); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/StaticNonStatic.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class StaticNonStatic { 4 | public static class A { 5 | int x; 6 | 7 | public class B { 8 | int m() { 9 | return x; 10 | } 11 | } 12 | } 13 | 14 | void m() { 15 | new A().new B().m(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/nesting/Subclass.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.nesting; 2 | 3 | public class Subclass { 4 | int x; 5 | 6 | class A { 7 | 8 | } 9 | 10 | class C { 11 | int y; 12 | 13 | class B extends A { 14 | int m() { 15 | return x + y; 16 | } 17 | } 18 | 19 | class D extends B { 20 | 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/switchx/Empty.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.switchx; 2 | 3 | public class Empty { 4 | public void empty(int x) { 5 | switch (x) { 6 | } 7 | } 8 | 9 | public void emptyDefault(int x) { 10 | switch (x) { 11 | default: 12 | } 13 | } 14 | 15 | public void emptyCase(int x) { 16 | switch (x) { 17 | case 1: 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/switchx/InterfaceValues.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.switchx; 2 | 3 | public class InterfaceValues { 4 | public interface I { 5 | int X = 1; 6 | int Y = 2; 7 | } 8 | 9 | public class S implements I { 10 | void m(int i) { 11 | switch (i) { 12 | case X: // check that we can reference field in interface correctly 13 | return; 14 | } 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/switchx/NestedEnumSwitch.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.switchx; 2 | 3 | import se.arnetheduck.j2c.test.enums.SimpleEnum; 4 | 5 | public class NestedEnumSwitch { 6 | protected int m(SimpleEnum e, SimpleEnum e2, SimpleEnum e3) { 7 | switch (e) { 8 | case BLUE: 9 | break; 10 | case RED: 11 | switch (e2) { 12 | case RED: 13 | switch (e3) { 14 | } 15 | } 16 | } 17 | 18 | switch (e) { 19 | case BLUE: 20 | break; 21 | case RED: 22 | switch (e2) { 23 | case RED: 24 | switch (e3) { 25 | } 26 | } 27 | } 28 | return 5; 29 | } 30 | } -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/switchx/SwitchEnum.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.switchx; 2 | 3 | import se.arnetheduck.j2c.test.enums.SimpleEnum; 4 | 5 | public class SwitchEnum { 6 | public int m(SimpleEnum et) { 7 | int v = 0; // Same name as fake switch var 8 | switch (et) { 9 | case RED: 10 | case GREEN: 11 | v = 1; 12 | return 0; 13 | case BLUE: 14 | break; 15 | default: 16 | return 5; 17 | 18 | } 19 | 20 | return v; 21 | } 22 | 23 | public int x(SimpleEnum et) { 24 | switch (et) { 25 | case RED: 26 | return 0; 27 | case BLUE: 28 | default: 29 | return 5; 30 | } 31 | } 32 | 33 | public int y(SimpleEnum et, int i) { 34 | switch (et) { 35 | case RED: 36 | if (i == 5) { 37 | break; 38 | } 39 | 40 | return 0; 41 | } 42 | 43 | return i; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/src/se/arnetheduck/j2c/test/switchx/SwitchTest.java: -------------------------------------------------------------------------------- 1 | package se.arnetheduck.j2c.test.switchx; 2 | 3 | import se.arnetheduck.j2c.test.Empty; 4 | 5 | public class SwitchTest { 6 | public int simple(int i) { 7 | switch (i) { 8 | case 1: 9 | case 2: 10 | return 0; 11 | case 3: 12 | i = i * 2; 13 | break; 14 | case 4: { 15 | i *= 4; 16 | } 17 | case 5: 18 | default: 19 | i = 4; 20 | } 21 | return i; 22 | } 23 | 24 | public int vars(int i) { 25 | switch (i) { 26 | case 1: 27 | int x = i; 28 | i = x * 2; 29 | case 2: 30 | x = 5; 31 | i = x; 32 | break; 33 | } 34 | 35 | return i; 36 | } 37 | 38 | public int multi(int i) { 39 | switch (i) { 40 | case 1: { 41 | Empty[] x, y[] = null; 42 | x = y[0]; 43 | return i; 44 | } 45 | } 46 | return 0; 47 | } 48 | } 49 | --------------------------------------------------------------------------------