├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── README.zh_CN.md ├── antlr ├── .gitignore ├── KalangLexer.g4 ├── KalangParser.g4 ├── TestInput.kl ├── TestScript │ ├── Base.kl │ ├── InterpolationTest.kl │ └── ScriptTest.kl ├── build.bat ├── compile.bat ├── genjava.bat ├── lib │ └── antlr-4.7.2-complete.jar ├── release.bat ├── test.bat └── testInput.bat ├── build.gradle ├── docs └── syntax.md ├── gradle ├── docs.gradle ├── maven-publish.gradle ├── version.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kalang-runtime ├── build.gradle └── src │ ├── main │ ├── java │ │ └── kalang │ │ │ ├── annotation │ │ │ ├── MixinMethod.java │ │ │ ├── Nonnull.java │ │ │ └── Nullable.java │ │ │ ├── coroutine │ │ │ ├── AsyncHelper.java │ │ │ ├── AsyncRunner.java │ │ │ ├── ExecuteContext.java │ │ │ ├── GeneratorImpl.java │ │ │ └── NextExecutor.java │ │ │ ├── helper │ │ │ └── PrintHelper.java │ │ │ ├── io │ │ │ ├── AsyncChannelReader.java │ │ │ ├── AsyncChannelWriter.java │ │ │ ├── AsyncCloseable.java │ │ │ ├── AsyncFileChannel.java │ │ │ ├── AsyncReadChannel.java │ │ │ ├── AsyncReader.java │ │ │ ├── AsyncWriteChannel.java │ │ │ ├── AsyncWriter.java │ │ │ └── FileIO.java │ │ │ ├── lang │ │ │ ├── AsyncCallable.java │ │ │ ├── AsyncRunnable.java │ │ │ ├── AsyncTaskExecutor.java │ │ │ ├── AsyncThread.java │ │ │ ├── Completable.java │ │ │ ├── DefaultStaticMembers.java │ │ │ ├── Generator.java │ │ │ ├── KalangRuntime.java │ │ │ ├── Ref.java │ │ │ ├── Script.java │ │ │ └── TaskExecutor.java │ │ │ ├── mixin │ │ │ ├── CollectionMixin.java │ │ │ ├── DataMixin.java │ │ │ ├── DigestMixin.java │ │ │ ├── HexMixin.java │ │ │ ├── IOMixin.java │ │ │ ├── MapMixin.java │ │ │ ├── ObjectMixin.java │ │ │ ├── PropertiesMixin.java │ │ │ └── StringMixin.java │ │ │ ├── runtime │ │ │ ├── dynamic │ │ │ │ ├── FieldVisitor.java │ │ │ │ ├── MethodAmbiguousException.java │ │ │ │ └── MethodDispatcher.java │ │ │ └── util │ │ │ │ ├── MethodResolver.java │ │ │ │ └── MethodSelector.java │ │ │ ├── type │ │ │ ├── Function.java │ │ │ ├── Function0.java │ │ │ ├── Function1.java │ │ │ ├── Function2.java │ │ │ ├── Function3.java │ │ │ ├── Function4.java │ │ │ ├── Function5.java │ │ │ ├── Function6.java │ │ │ ├── Function7.java │ │ │ ├── Function8.java │ │ │ └── FunctionClasses.java │ │ │ └── util │ │ │ └── DateTime.java │ └── resources │ │ └── kalang │ │ └── lang │ │ └── runtime.properties │ └── test │ └── java │ └── test │ └── kalang │ └── runtime │ ├── AsyncRunnerTest.java │ ├── CollectionMixinTest.java │ ├── DigestPluginTest.java │ ├── DigesterTest.java │ ├── FieldVisitorTest.java │ ├── MethodDispatcherTest.java │ └── StringMixinTest.java ├── settings.gradle ├── snapshot └── kalang-editor.png ├── src ├── main │ └── java │ │ └── kalang │ │ └── compiler │ │ ├── antlr │ │ ├── KalangLexer.interp │ │ ├── KalangLexer.java │ │ ├── KalangLexer.tokens │ │ ├── KalangParser.interp │ │ ├── KalangParser.java │ │ ├── KalangParser.tokens │ │ ├── KalangParserBaseListener.java │ │ ├── KalangParserBaseVisitor.java │ │ ├── KalangParserListener.java │ │ ├── KalangParserVisitor.java │ │ └── SLLErrorStrategy.java │ │ ├── ast │ │ ├── AbstractAstVisitor.java │ │ ├── AnnotationNode.java │ │ ├── Annotationable.java │ │ ├── ArithmeticBinaryExpr.java │ │ ├── ArrayLengthExpr.java │ │ ├── AssignExpr.java │ │ ├── AssignableExpr.java │ │ ├── AssignableObject.java │ │ ├── AstNode.java │ │ ├── AstVisitor.java │ │ ├── AwaitExpr.java │ │ ├── BinaryExpr.java │ │ ├── BitwiseBinaryExpr.java │ │ ├── BlockStmt.java │ │ ├── BreakStmt.java │ │ ├── CastExpr.java │ │ ├── CatchBlock.java │ │ ├── ChildUpdater.java │ │ ├── ClassNode.java │ │ ├── ClassReference.java │ │ ├── CompareBinaryExpr.java │ │ ├── ConstExpr.java │ │ ├── ContinueStmt.java │ │ ├── ElementExpr.java │ │ ├── ErrorousExpr.java │ │ ├── ExprNode.java │ │ ├── ExprStmt.java │ │ ├── FieldExpr.java │ │ ├── FieldNode.java │ │ ├── FinallyBlock.java │ │ ├── IAstVisitor.java │ │ ├── IfStmt.java │ │ ├── IncExpr.java │ │ ├── InstanceOfExpr.java │ │ ├── InvocationExpr.java │ │ ├── LambdaExpr.java │ │ ├── LocalVarNode.java │ │ ├── LogicBinaryExpr.java │ │ ├── LoopStmt.java │ │ ├── MethodNode.java │ │ ├── MultiStmt.java │ │ ├── MultiStmtExpr.java │ │ ├── NewArrayExpr.java │ │ ├── NewObjectExpr.java │ │ ├── ObjectFieldExpr.java │ │ ├── ObjectInvokeExpr.java │ │ ├── ParameterNode.java │ │ ├── PrimitiveCastExpr.java │ │ ├── ReturnStmt.java │ │ ├── Statement.java │ │ ├── StaticFieldExpr.java │ │ ├── StaticInvokeExpr.java │ │ ├── SuperExpr.java │ │ ├── ThisExpr.java │ │ ├── ThrowStmt.java │ │ ├── TryStmt.java │ │ ├── UnaryExpr.java │ │ ├── UnknownFieldExpr.java │ │ ├── UnknownInvocationExpr.java │ │ ├── VarDeclStmt.java │ │ ├── VarExpr.java │ │ ├── VarObject.java │ │ └── YieldStmt.java │ │ ├── compile │ │ ├── ClassNodeLoader.java │ │ ├── ClassNodeNotFoundException.java │ │ ├── CodeGenerator.java │ │ ├── CompilationUnit.java │ │ ├── CompilationUnitController.java │ │ ├── CompileContext.java │ │ ├── CompilePhase.java │ │ ├── CompilePhaseManager.java │ │ ├── Configuration.java │ │ ├── DefaultClassNodeLoader.java │ │ ├── Diagnosis.java │ │ ├── DiagnosisHandler.java │ │ ├── FileKalangSource.java │ │ ├── InMemoryKalangSource.java │ │ ├── KalangCompiler.java │ │ ├── KalangSource.java │ │ ├── OffsetRange.java │ │ ├── PhaseProcessor.java │ │ ├── SemanticAnalyzer.java │ │ ├── SourceLoader.java │ │ ├── StandardCompilePhases.java │ │ ├── TypeNameResolver.java │ │ ├── codegen │ │ │ ├── Ast2Class.java │ │ │ ├── Ast2JavaStub.java │ │ │ ├── CatchContext.java │ │ │ ├── CodeGenerationException.java │ │ │ ├── analyse │ │ │ │ └── StackUtil.java │ │ │ ├── op │ │ │ │ ├── Attribute.java │ │ │ │ ├── CatchAttr.java │ │ │ │ ├── DefaultOpcodeOptimizer.java │ │ │ │ ├── FieldInsnOp.java │ │ │ │ ├── IincOp.java │ │ │ │ ├── InsnOp.java │ │ │ │ ├── IntInsnOp.java │ │ │ │ ├── InvokeDynamicInsnOp.java │ │ │ │ ├── JumpInsnOp.java │ │ │ │ ├── LabelOp.java │ │ │ │ ├── LdcInsnOp.java │ │ │ │ ├── LineNumberAttr.java │ │ │ │ ├── LocalVariableAttr.java │ │ │ │ ├── MethodInsnOp.java │ │ │ │ ├── MultiANewArrayInsnOp.java │ │ │ │ ├── OpBase.java │ │ │ │ ├── OpCollector.java │ │ │ │ ├── OpcodeOptimizer.java │ │ │ │ ├── TypeInsnOp.java │ │ │ │ ├── VarInsnOp.java │ │ │ │ └── YieldOp.java │ │ │ └── util │ │ │ │ └── OpcodeUtil.java │ │ ├── jvm │ │ │ ├── JvmClassNode.java │ │ │ └── JvmClassNodeLoader.java │ │ ├── semantic │ │ │ ├── AmbiguousMethodException.java │ │ │ ├── AstBuilder.java │ │ │ ├── AstBuilderBase.java │ │ │ ├── AstNodeMaker.java │ │ │ ├── AstVerifier.java │ │ │ ├── ClassNodeInitializer.java │ │ │ ├── ClassNodeStructureBuilder.java │ │ │ ├── DefaultSemanticAnalyzer.java │ │ │ ├── FieldNotFoundException.java │ │ │ ├── InvocationResolver.java │ │ │ ├── MalformedAstException.java │ │ │ ├── MethodContext.java │ │ │ ├── MethodNotFoundException.java │ │ │ ├── MissingParamMethodInfo.java │ │ │ ├── NodeException.java │ │ │ ├── StatementSupplier.java │ │ │ └── analyzer │ │ │ │ ├── AssignmentAnalyzer.java │ │ │ │ ├── AstNodeCollector.java │ │ │ │ ├── FieldUsageAnalyzer.java │ │ │ │ ├── MethodDeclarationAnalyzer.java │ │ │ │ ├── ParentAnalyzer.java │ │ │ │ ├── StatementAnalyzer.java │ │ │ │ └── TerminalStatementAnalyzer.java │ │ └── util │ │ │ ├── DefaultCompileContext.java │ │ │ ├── DiagnosisReporter.java │ │ │ └── StandardDiagnosisHandler.java │ │ ├── core │ │ ├── ArrayType.java │ │ ├── ClassType.java │ │ ├── ExtendModifiers.java │ │ ├── FieldDescriptor.java │ │ ├── GenericType.java │ │ ├── LambdaType.java │ │ ├── MethodDescriptor.java │ │ ├── ModifierConstant.java │ │ ├── NullableKind.java │ │ ├── ObjectType.java │ │ ├── ParameterDescriptor.java │ │ ├── PrimitiveType.java │ │ ├── Type.java │ │ ├── Types.java │ │ ├── Values.java │ │ ├── VarTable.java │ │ ├── WildcardType.java │ │ └── impl │ │ │ ├── StandardFieldDescriptor.java │ │ │ ├── StandardMethodDescriptor.java │ │ │ └── StandardParameterDescriptor.java │ │ ├── dependency │ │ ├── Artifact.java │ │ ├── DependenciesCache.java │ │ ├── DependencyResolver.java │ │ ├── ExtendURLHandler.java │ │ ├── NoMessageLogger.java │ │ ├── ResolveException.java │ │ └── ResolveResult.java │ │ ├── gui │ │ ├── Editor.form │ │ └── Editor.java │ │ ├── java │ │ ├── FileSystemFileManager.java │ │ ├── MemoryCompiler.java │ │ ├── MemoryFileManager.java │ │ ├── MemoryJavaSource.java │ │ ├── StringJavaSource.java │ │ └── StringJavaSourceBase.java │ │ ├── profile │ │ ├── Invocation.java │ │ ├── Profiler.java │ │ ├── Span.java │ │ └── SpanFormatter.java │ │ ├── shell │ │ ├── Constant.java │ │ ├── KalangOption.java │ │ ├── Kalangc.java │ │ ├── Kalangeditor.java │ │ ├── Kalangsh.java │ │ └── ShellBase.java │ │ ├── tool │ │ ├── CachedClassNodeLoader.java │ │ ├── CachedSourceLoader.java │ │ ├── ClassWriter.java │ │ ├── CompileException.java │ │ ├── FileSystemCompiler.java │ │ ├── FileSystemOutputManager.java │ │ ├── FileSystemSourceLoader.java │ │ ├── KalangClassLoader.java │ │ ├── KalangShell.java │ │ ├── MemoryOutputManager.java │ │ ├── NonScriptFileException.java │ │ └── OutputManager.java │ │ └── util │ │ ├── AccessUtil.java │ │ ├── AntlrErrorString.java │ │ ├── AstOutputUtil.java │ │ ├── AstUtil.java │ │ ├── AsyncUtil.java │ │ ├── BoxUtil.java │ │ ├── ClassExecutor.java │ │ ├── ClassNameUtil.java │ │ ├── ClassPathUtil.java │ │ ├── CollectionsUtil.java │ │ ├── ConstExprUtil.java │ │ ├── DiagnosisUtil.java │ │ ├── Exceptions.java │ │ ├── FilePathUtil.java │ │ ├── ImplementationUtil.java │ │ ├── InheritanceUtil.java │ │ ├── InvalidModifierException.java │ │ ├── KalangSourceUtil.java │ │ ├── LambdaUtil.java │ │ ├── LexerFactory.java │ │ ├── MathType.java │ │ ├── MethodUtil.java │ │ ├── ModifierUtil.java │ │ ├── NameUtil.java │ │ ├── OffsetRangeHelper.java │ │ ├── OpUtil.java │ │ ├── OverrideUtil.java │ │ ├── ParameterizedUtil.java │ │ ├── Parameters.java │ │ ├── ParseTreeNavigator.java │ │ ├── StringLiteralUtil.java │ │ ├── StringUtil.java │ │ ├── TokenNavigator.java │ │ ├── TokenStreamFactory.java │ │ ├── TypeUtil.java │ │ └── TypeValidator.java └── test │ ├── java │ └── test │ │ └── kalang │ │ └── compiler │ │ ├── AsmTest.java │ │ ├── ClassLoaderTest.java │ │ ├── ClassTypeTest.java │ │ ├── CompilantUnitTest.java │ │ ├── CompilerTestCase.java │ │ ├── DebugTest.java │ │ ├── ErrorRecoverTest.java │ │ ├── FilePathUtilTest.java │ │ ├── KalangCompilerTest.java │ │ ├── ParameterizedTypeTest.java │ │ ├── StringLiteralUtilTest.java │ │ ├── TokenUtilTest.java │ │ ├── automation │ │ ├── ErrorReportTest.java │ │ └── SnippetsTest.java │ │ ├── core │ │ ├── ClassTypeTest.java │ │ ├── GenericTest.java │ │ ├── ObjectTypeTest.java │ │ └── TypeCompareTest.java │ │ ├── helper │ │ ├── DataPluginTest.java │ │ └── DigestPluginTest.java │ │ ├── tool │ │ ├── KalangShellTest.java │ │ └── KalangcTest.java │ │ └── util │ │ ├── AntlrTest.java │ │ ├── LambdaUtilTest.java │ │ └── TypeUtilTest.java │ └── kalang-snippets │ ├── automation │ ├── ArrayElementAssign.kl │ ├── ArrayTest.kls │ ├── AsyncFileTest.kl │ ├── AsyncTest.kl │ ├── AutoCast.kls │ ├── BitOperator.kls │ ├── CollectionMixin.kls │ ├── Compare.kls │ ├── CompoundAssign.kl │ ├── ConstTest.kls │ ├── DefaultParam.kls │ ├── DefaultStaticImport.kls │ ├── DestructingVariablesDecl.kls │ ├── FieldAccess.kl │ ├── FieldAssign.kl │ ├── FieldInitialization.kl │ ├── FieldOperator.kl │ ├── ForIn.kls │ ├── ForceCast.kls │ ├── Foreach.kls │ ├── GeneratorTest.kls │ ├── GenericConstructor.kls │ ├── GenericMapTest.kls │ ├── GenericMethod.kls │ ├── GenericTypeCast.kls │ ├── HashTest.kls │ ├── HelloKalang.kl │ ├── HelloScript.kls │ ├── IfStmt.kls │ ├── ImportStat.kls │ ├── IncrAndDecrOperator.kls │ ├── Initialization.kls │ ├── InnerClasses.kls │ ├── InstanceOfTest.kl │ ├── InterfaceField.kls │ ├── InvokeMember.kls │ ├── InvokeMostPrecise.kls │ ├── InvokeOperator.kl │ ├── InvokeStatic.kls │ ├── LambdaTest.kls │ ├── LiteralExpr.kls │ ├── MapMixin.kls │ ├── MapTest.kls │ ├── MethodRef.kls │ ├── MethodSelect.kl │ ├── NewExpr.kls │ ├── NullCheck.kls │ ├── NullDefaultExpr.kl │ ├── Operator.kls │ ├── PrimitiveCast.kls │ ├── PrivateConstructor.kl │ ├── PropertyAccess.kl │ ├── QuestionExpr.kls │ ├── StringLiteral.kls │ ├── TryCatchFinallyTest.kls │ ├── TryWithResource.kl │ ├── UsingAnnotation.kl │ ├── Varargs.kls │ ├── WithExpr.kls │ ├── algorithm │ │ ├── Md5.kl │ │ └── Sha1.kl │ └── model │ │ └── ClassA.kl │ ├── error │ ├── AbstractMethodCheck.kl │ ├── AssignCheck.kls │ ├── AssignFinalField.kl │ ├── BreakError.kls │ ├── ContinueError.kls │ ├── DefaultParamCheck.kls │ ├── ExtraneousToken.kls │ ├── GenericInferConflict.kls │ ├── GenericInferNullable.kls │ ├── GenericTypeInferring.kls │ ├── InitializationCheck.kls │ ├── LambdaInitError.kls │ ├── LambdaParamNameConflict.kls │ ├── OverrideCheck.kl │ ├── OverrideReturnTypeCheck.kls │ ├── ParamNameRepeat.kls │ └── UnreachableCheck.kls │ ├── examples │ ├── EnumTest.kls │ ├── GenericAssignTest.kls │ ├── GenericMapTest.kls │ ├── GenericMethodTest.kls │ ├── Implementation.kl │ ├── InitializationCheck.kls │ ├── InnerClassInClass.kl │ ├── InnerClassInScript.kls │ ├── InterfaceCallTest.kls │ ├── InterfaceTest.kl │ ├── Interpolation.kls │ ├── LambdaTest.kls │ ├── MapExpr.kls │ ├── Math.kls │ ├── MethodSelectionTest.kls │ ├── NewFullNameClassTest.kls │ ├── NullCheckTest.kls │ ├── OverrideTest.kl │ ├── StringExpr.kls │ ├── SuperCall.kls │ └── innerClass │ │ ├── Main.kls │ │ └── Model.kl │ └── projects │ └── colorful-console │ ├── App.kls │ └── jansi-1.14.jar └── version.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | /build/ 3 | /debug/ 4 | /nbproject/ 5 | /.idea/ 6 | /.nb-gradle/ 7 | /out/ 8 | /kalang-runtime/build/ 9 | /kalang-runtime/out/ 10 | /gen/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | before_install: 3 | - chmod +x gradlew 4 | script: 5 | - ./gradlew check 6 | - ./gradlew jacocoTestReport 7 | after_success: 8 | - bash <(curl -s https://codecov.io/bash) 9 | jdk: 10 | - openjdk8 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Kason 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /antlr/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /gen/ 3 | -------------------------------------------------------------------------------- /antlr/TestInput.kl: -------------------------------------------------------------------------------- 1 | import \java\lang\*; 2 | import \java\util\List; 3 | import java\util\LinkedList; 4 | class{ 5 | static String msg = "Hello,world"; 6 | constructor(String m){ 7 | msg = m; 8 | } 9 | static void main(String[] args){ 10 | System.out.println(msg); 11 | } 12 | void decl(){ 13 | int i = 1; 14 | if(i==0) return; 15 | var l = i; 16 | var emptyMap = []; 17 | var map = [name:"kalang"]; 18 | var emptyList = []; 19 | var list = ["item"]; 20 | } 21 | void method(int p,long q){ 22 | for(int i=0;i<100;i++){ 23 | method(p,q); 24 | } 25 | &String() func0 = null; 26 | &String(String) func1 = null; 27 | &String(String,String) func2 = null; 28 | run0({return 0;}); 29 | run1({a=>return a;}); 30 | run2({a,b=>return a+b;}); 31 | } 32 | int methodWithReturn(int p){} 33 | } -------------------------------------------------------------------------------- /antlr/TestScript/InterpolationTest.kl: -------------------------------------------------------------------------------- 1 | var name = "kalang"; 2 | println("hello,${name}!"); 3 | -------------------------------------------------------------------------------- /antlr/TestScript/ScriptTest.kl: -------------------------------------------------------------------------------- 1 | #script kalang.compiler.script.ShellScript 2 | String hello(String name){ 3 | var str = "hello" + name; 4 | return str; 5 | } 6 | //println(hello("kalang")); -------------------------------------------------------------------------------- /antlr/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | genjava.bat && compile.bat && test.bat -------------------------------------------------------------------------------- /antlr/compile.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | javac -cp %~dp0/lib/antlr-4.7.2-complete.jar -d build build/*.java -------------------------------------------------------------------------------- /antlr/genjava.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | java -cp %~dp0/lib/antlr-4.7.2-complete.jar org.antlr.v4.Tool %* KalangLexer.g4 -o build 3 | java -cp %~dp0/lib/antlr-4.7.2-complete.jar org.antlr.v4.Tool %* KalangParser.g4 -o build -lib build 4 | -------------------------------------------------------------------------------- /antlr/lib/antlr-4.7.2-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kasonyang/kalang/d3ceaadf25342147cb47109dda3dd4faccc1be37/antlr/lib/antlr-4.7.2-complete.jar -------------------------------------------------------------------------------- /antlr/release.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | java -cp %~dp0/lib/antlr-4.7.2-complete.jar org.antlr.v4.Tool KalangLexer.g4 -o %~dp0/../src/main/java/kalang/compiler/antlr -package kalang.compiler.antlr 3 | java -cp %~dp0/lib/antlr-4.7.2-complete.jar org.antlr.v4.Tool KalangParser.g4 -o %~dp0/../src/main/java/kalang/compiler/antlr -package kalang.compiler.antlr -visitor 4 | -------------------------------------------------------------------------------- /antlr/test.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | java -cp %~dp0/build;%~dp0/lib/antlr-4.7.2-complete.jar org.antlr.v4.gui.TestRig Kalang compilationUnit %* TestScript/* TestInput.kl -------------------------------------------------------------------------------- /antlr/testInput.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | java -cp %~dp0/build;%~dp0/lib/antlr-4.7.2-complete.jar org.antlr.v4.gui.TestRig Kalang compilationUnit %* -------------------------------------------------------------------------------- /gradle/docs.gradle: -------------------------------------------------------------------------------- 1 | import java.text.SimpleDateFormat 2 | 3 | task processDocsSource(type:Copy) { 4 | from("docs"){ 5 | exclude("**/*.mdt") 6 | } 7 | from("docs"){ 8 | include("**/*.mdt") 9 | rename(/(.*?)\.mdt/, '$1.md') 10 | expand version: project.version, 11 | buildtime: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) 12 | } 13 | into "${buildDir}/docs-jbake" 14 | } 15 | 16 | jbake{ 17 | version='2.5.1' 18 | } 19 | bake{ 20 | input = file("${buildDir}/docs-jbake") 21 | output = file("${buildDir}/docs-html") 22 | } 23 | 24 | bake.dependsOn processDocsSource -------------------------------------------------------------------------------- /gradle/version.gradle: -------------------------------------------------------------------------------- 1 | import java.text.SimpleDateFormat; 2 | def version = "0.0.0" 3 | new File(project.projectDir,"version.txt").withReader { reader -> 4 | def versionExpr = reader.readLine(); 5 | def now = new Date(); 6 | if (versionExpr){ 7 | versionExpr = versionExpr 8 | .replace("{{DATE}}",new SimpleDateFormat("yyyyMMdd").format(now)) 9 | .replace("{{TIME}}",new SimpleDateFormat("HHmmss").format(now)) 10 | ; 11 | } 12 | version = versionExpr; 13 | } 14 | project.version = version; 15 | subprojects { p-> 16 | p.version = version; 17 | } 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kasonyang/kalang/d3ceaadf25342147cb47109dda3dd4faccc1be37/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kalang-runtime/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin:'java' 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | compileOnly 'org.projectlombok:lombok:1.18.8' 7 | annotationProcessor 'org.projectlombok:lombok:1.18.8' 8 | testCompile 'junit:junit:4.12' 9 | testCompile 'commons-codec:commons-codec:1.10' 10 | } 11 | 12 | apply from:"../gradle/maven-publish.gradle" 13 | 14 | processResources { 15 | from("src/main/resources"){ 16 | include 'kalang/lang/runtime.properties' 17 | expand version: project.version, 18 | buildtime: new Date().getTime() 19 | } 20 | } 21 | 22 | tasks.withType(JavaCompile) { 23 | options.compilerArgs << '-parameters' 24 | } 25 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/annotation/MixinMethod.java: -------------------------------------------------------------------------------- 1 | package kalang.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | @Documented 8 | @Retention(RetentionPolicy.RUNTIME) 9 | public @interface MixinMethod { 10 | } 11 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/annotation/Nonnull.java: -------------------------------------------------------------------------------- 1 | package kalang.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface Nonnull { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/annotation/Nullable.java: -------------------------------------------------------------------------------- 1 | package kalang.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface Nullable { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/coroutine/AsyncHelper.java: -------------------------------------------------------------------------------- 1 | package kalang.coroutine; 2 | 3 | import kalang.lang.AsyncTaskExecutor; 4 | import kalang.lang.Completable; 5 | 6 | /** 7 | * @author KasonYang 8 | */ 9 | public class AsyncHelper { 10 | 11 | public static Completable submit(ExecuteContext context, NextExecutor executor, String name) { 12 | Thread thread = Thread.currentThread(); 13 | if (!(thread instanceof AsyncTaskExecutor)) { 14 | throw new IllegalStateException("async methods is allow to invoke in the thread implemented AsyncTaskExecutor"); 15 | } 16 | AsyncTaskExecutor at = (AsyncTaskExecutor) thread; 17 | GeneratorImpl> generator = GeneratorImpl.create(context, executor, name); 18 | return at.submitAsyncTask(generator); 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/coroutine/ExecuteContext.java: -------------------------------------------------------------------------------- 1 | package kalang.coroutine; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public class ExecuteContext { 7 | 8 | public boolean isDone; 9 | 10 | public Object result; 11 | 12 | public Object[] vars; 13 | 14 | public Object[] stack; 15 | 16 | public int next; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/coroutine/GeneratorImpl.java: -------------------------------------------------------------------------------- 1 | package kalang.coroutine; 2 | 3 | import kalang.lang.Generator; 4 | 5 | import java.util.Objects; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class GeneratorImpl implements Generator { 11 | 12 | private String name; 13 | 14 | private ExecuteContext context; 15 | 16 | private NextExecutor executor; 17 | 18 | private GeneratorImpl(ExecuteContext context, NextExecutor executor, String name) { 19 | this.executor = executor; 20 | this.context = context; 21 | this.name = name; 22 | } 23 | 24 | public static GeneratorImpl create(ExecuteContext context, NextExecutor executor, String name) { 25 | return new GeneratorImpl<>(context, executor, name); 26 | } 27 | 28 | @Override 29 | public T next() { 30 | executor.executeNext(context); 31 | return (T) context.result; 32 | } 33 | 34 | @Override 35 | public boolean isDone() { 36 | return context.isDone; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return Objects.toString(name); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/coroutine/NextExecutor.java: -------------------------------------------------------------------------------- 1 | package kalang.coroutine; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface NextExecutor { 7 | 8 | void executeNext(ExecuteContext context); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/io/AsyncChannelReader.java: -------------------------------------------------------------------------------- 1 | package kalang.io; 2 | 3 | import kalang.lang.Completable; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class AsyncChannelReader extends AsyncReader { 11 | 12 | private final AsyncReadChannel readChannel; 13 | 14 | private long position; 15 | 16 | public AsyncChannelReader(AsyncReadChannel readChannel) { 17 | this.readChannel = readChannel; 18 | } 19 | 20 | @Override 21 | protected Completable handleRead(byte[] buffer, int offset, int length) { 22 | if (length <= 0) { 23 | throw new IllegalArgumentException("positive length is required"); 24 | } 25 | return readChannel.read(position, buffer, offset, length) 26 | .onCompleted(len -> { 27 | position += length; 28 | return Completable.resolve(len); 29 | }); 30 | } 31 | 32 | 33 | @Override 34 | public Completable close() { 35 | try { 36 | readChannel.close(); 37 | return Completable.resolve(null); 38 | } catch (IOException e) { 39 | return Completable.reject(e); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/io/AsyncChannelWriter.java: -------------------------------------------------------------------------------- 1 | package kalang.io; 2 | 3 | import kalang.lang.Completable; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class AsyncChannelWriter extends AsyncWriter { 11 | 12 | private final AsyncWriteChannel writeChannel; 13 | 14 | private long position; 15 | 16 | public AsyncChannelWriter(AsyncWriteChannel writeChannel) { 17 | this.writeChannel = writeChannel; 18 | } 19 | 20 | @Override 21 | protected Completable handleWrite(byte[] buffer, int offset, int length) { 22 | return writeChannel.write(position, buffer, offset, length) 23 | .onCompleted(len -> { 24 | position += len; 25 | return Completable.resolve(len); 26 | }); 27 | } 28 | 29 | @Override 30 | public Completable close() { 31 | try { 32 | writeChannel.close(); 33 | return Completable.resolve(null); 34 | } catch (IOException e) { 35 | return Completable.reject(e); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/io/AsyncCloseable.java: -------------------------------------------------------------------------------- 1 | package kalang.io; 2 | 3 | import kalang.lang.Completable; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public interface AsyncCloseable { 9 | 10 | Completable close(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/AsyncCallable.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface AsyncCallable { 7 | 8 | Completable call(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/AsyncRunnable.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface AsyncRunnable { 7 | 8 | Completable run(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/AsyncTaskExecutor.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface AsyncTaskExecutor { 7 | 8 | Completable submitAsyncTask(Generator> task); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/DefaultStaticMembers.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | @Deprecated 4 | public class DefaultStaticMembers { 5 | 6 | public static void println(Object msg) { 7 | System.out.println(msg); 8 | } 9 | 10 | public static void print(Object msg) { 11 | System.out.print(msg); 12 | } 13 | 14 | public static void printf(String format,Object... args) { 15 | System.out.printf(format,args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/Generator.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface Generator { 7 | 8 | R next(); 9 | 10 | boolean isDone(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/Ref.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public class Ref { 7 | 8 | private T value; 9 | 10 | public Ref() { 11 | } 12 | 13 | public Ref(T value) { 14 | this.value = value; 15 | } 16 | 17 | public T get() { 18 | return value; 19 | } 20 | 21 | public void set(T value) { 22 | this.value = value; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/Script.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | import kalang.annotation.Nullable; 4 | 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public abstract class Script { 10 | 11 | public final static int SUCCESS = 0; 12 | 13 | private String[] arguments = new String[0]; 14 | 15 | protected abstract int execute(); 16 | 17 | public int run() throws Throwable { 18 | try{ 19 | return execute(); 20 | }catch(Throwable e) { 21 | return handleException(e); 22 | } 23 | } 24 | 25 | public int run(@Nullable String[] arguments) throws Throwable { 26 | if (arguments != null) { 27 | this.arguments = arguments; 28 | } 29 | return run(); 30 | } 31 | 32 | protected String[] arguments(){ 33 | return this.arguments; 34 | } 35 | 36 | protected String argument(int index,@Nullable String defaultValue) { 37 | return arguments.length > index ? arguments[index] : defaultValue; 38 | } 39 | 40 | protected int handleException(Throwable e) throws Throwable{ 41 | throw e; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/lang/TaskExecutor.java: -------------------------------------------------------------------------------- 1 | package kalang.lang; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface TaskExecutor { 7 | 8 | void submitTask(Runnable task); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/mixin/HexMixin.java: -------------------------------------------------------------------------------- 1 | package kalang.mixin; 2 | 3 | import kalang.annotation.MixinMethod; 4 | 5 | public class HexMixin { 6 | 7 | private static char[] DIGITS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 8 | 9 | @MixinMethod 10 | public static String toHexString(byte[] bytes) { 11 | return toHexString(bytes, 0, bytes.length); 12 | } 13 | 14 | @MixinMethod 15 | public static String toHexString(byte[] bytes, int offset, int len) { 16 | char[] chars = new char[len << 1]; 17 | int ci = 0; 18 | int end = offset + len; 19 | for (int i = offset; i < end; i++) { 20 | byte b = bytes[i]; 21 | chars[ci++] = DIGITS[(b & 0xF0) >>> 4]; 22 | chars[ci++] = DIGITS[b & 0xF]; 23 | } 24 | return new String(chars); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/mixin/ObjectMixin.java: -------------------------------------------------------------------------------- 1 | package kalang.mixin; 2 | 3 | import kalang.annotation.MixinMethod; 4 | import kalang.type.Function1; 5 | 6 | /** 7 | * @author KasonYang 8 | */ 9 | public class ObjectMixin { 10 | 11 | @MixinMethod 12 | public static R cast(T obj, Function1 handler) { 13 | return handler.call(obj); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/mixin/PropertiesMixin.java: -------------------------------------------------------------------------------- 1 | package kalang.mixin; 2 | 3 | 4 | import java.io.*; 5 | import java.util.Properties; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class PropertiesMixin { 11 | 12 | public static Properties loadProperties(InputStream inputStream) throws IOException { 13 | Properties props = new Properties(); 14 | props.load(inputStream); 15 | return props; 16 | } 17 | 18 | public static Properties loadProperties(File file) throws IOException { 19 | try (FileInputStream fis = new FileInputStream(file)) { 20 | return loadProperties(fis); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/runtime/dynamic/FieldVisitor.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.runtime.dynamic; 3 | 4 | import java.lang.reflect.Field; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class FieldVisitor { 11 | public static Object get(Object obj,String name) throws NoSuchFieldException, IllegalAccessException{ 12 | Field field = obj.getClass().getField(name); 13 | return field.get(obj); 14 | } 15 | 16 | public static void set(Object obj,String name,Object value) throws IllegalAccessException, NoSuchFieldException{ 17 | Field field = obj.getClass().getField(name); 18 | field.set(obj, value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/runtime/dynamic/MethodAmbiguousException.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.runtime.dynamic; 3 | 4 | import java.lang.reflect.Method; 5 | import java.util.Arrays; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class MethodAmbiguousException extends Exception{ 12 | 13 | protected Method[] ambiguousMethods; 14 | 15 | public MethodAmbiguousException(Method[] ambiguousMethods) { 16 | this.ambiguousMethods = ambiguousMethods; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "method is ambiguous:" + Arrays.toString(ambiguousMethods); 22 | } 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public interface Function { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function0.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function0 extends Function { 8 | 9 | R call(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function1.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function1 extends Function { 8 | 9 | R call(P arg); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function2.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function2 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function3.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function3 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2, P3 arg3); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function4.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function4 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2, P3 arg3, P4 arg4); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function5.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function5 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function6.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function6 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function7.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function7 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6, P7 arg7); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/Function8.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Function8 extends Function { 8 | 9 | R call(P1 arg1, P2 arg2, P3 arg3, P4 arg4, P5 arg5, P6 arg6, P7 arg7, P8 arg8); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/java/kalang/type/FunctionClasses.java: -------------------------------------------------------------------------------- 1 | package kalang.type; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public class FunctionClasses { 8 | 9 | public final static Class[] CLASSES = new Class[]{ 10 | Function0.class, Function1.class, Function2.class, Function3.class, 11 | Function4.class, Function5.class, Function6.class, Function7.class, 12 | Function8.class 13 | }; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /kalang-runtime/src/main/resources/kalang/lang/runtime.properties: -------------------------------------------------------------------------------- 1 | version=${version} 2 | build-time=${buildtime} -------------------------------------------------------------------------------- /kalang-runtime/src/test/java/test/kalang/runtime/AsyncRunnerTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.runtime; 2 | 3 | import kalang.lang.*; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class AsyncRunnerTest { 11 | 12 | @Test(timeout = 1000) 13 | public void test() throws InterruptedException { 14 | Ref obj = new Ref<>(false); 15 | AsyncThread.create((asyncThread) -> { 16 | TestGenerator testGenerator = new TestGenerator(); 17 | asyncThread.submitAsyncTask(testGenerator).onCompleted(value -> { 18 | Assert.assertEquals(6, testGenerator.i); 19 | Assert.assertEquals(5, (int) value); 20 | obj.set(true); 21 | asyncThread.interrupt(); 22 | return null; 23 | }, error -> { 24 | obj.set(false); 25 | asyncThread.interrupt(); 26 | return null; 27 | }); 28 | }).join(); 29 | Assert.assertTrue(obj.get()); 30 | } 31 | 32 | private static class TestGenerator implements Generator> { 33 | 34 | public int i = 0; 35 | 36 | @Override 37 | public Completable next() { 38 | return Completable.resolve(i++); 39 | } 40 | 41 | @Override 42 | public boolean isDone() { 43 | return i == 6; 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /kalang-runtime/src/test/java/test/kalang/runtime/DigestPluginTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.runtime; 2 | 3 | import kalang.mixin.DigestMixin; 4 | import kalang.mixin.HexMixin; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import java.security.NoSuchAlgorithmException; 9 | 10 | public class DigestPluginTest { 11 | 12 | @Test 13 | public void testDigest() throws NoSuchAlgorithmException { 14 | Assert.assertEquals("098f6bcd4621d373cade4e832627b4f6", HexMixin.toHexString(DigestMixin.md5("test"))); 15 | Assert.assertEquals("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", HexMixin.toHexString(DigestMixin.sha1("test"))); 16 | Assert.assertEquals("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", HexMixin.toHexString(DigestMixin.sha256("test"))); 17 | Assert.assertEquals("ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff", HexMixin.toHexString(DigestMixin.sha512("test"))); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /kalang-runtime/src/test/java/test/kalang/runtime/FieldVisitorTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.runtime; 2 | 3 | import kalang.runtime.dynamic.FieldVisitor; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | /** 9 | * 10 | * @author Kason Yang 11 | */ 12 | public class FieldVisitorTest { 13 | public String name = "test"; 14 | @Test 15 | public void test() throws Exception{ 16 | FieldVisitorTest test = new FieldVisitorTest(); 17 | assertEquals(FieldVisitor.get(test, "name"), "test"); 18 | FieldVisitor.set(test, "name", "hello"); 19 | assertEquals(FieldVisitor.get(test, "name"), "hello"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /kalang-runtime/src/test/java/test/kalang/runtime/StringMixinTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.runtime; 2 | 3 | import kalang.mixin.StringMixin; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | /** 9 | * @author KasonYang 10 | */ 11 | public class StringMixinTest { 12 | 13 | @Test 14 | public void testSearch() { 15 | assertEquals("kalang", StringMixin.searchFirst("Hello, kalang!", "k[a-z]+")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'kalang-compiler' 2 | include 'kalang-runtime' -------------------------------------------------------------------------------- /snapshot/kalang-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kasonyang/kalang/d3ceaadf25342147cb47109dda3dd4faccc1be37/snapshot/kalang-editor.png -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/antlr/SLLErrorStrategy.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.antlr; 2 | 3 | import kalang.compiler.compile.CompilationUnit; 4 | import org.antlr.v4.runtime.*; 5 | 6 | import java.util.logging.Logger; 7 | 8 | /** 9 | * @author KasonYang 10 | */ 11 | public class SLLErrorStrategy extends BailErrorStrategy { 12 | 13 | private final static Logger LOG = Logger.getLogger(SLLErrorStrategy.class.getName()); 14 | 15 | private final CompilationUnit compilationUnit; 16 | 17 | public SLLErrorStrategy(CompilationUnit compilationUnit) { 18 | this.compilationUnit = compilationUnit; 19 | } 20 | 21 | @Override 22 | public void recover(Parser recognizer, RecognitionException e) { 23 | logSLLFailed(e.getOffendingToken()); 24 | super.recover(recognizer, e); 25 | } 26 | 27 | @Override 28 | public Token recoverInline(Parser recognizer) throws RecognitionException { 29 | ParserRuleContext ctx = recognizer.getContext(); 30 | if (ctx != null) { 31 | logSLLFailed(ctx.getStart()); 32 | } 33 | return super.recoverInline(recognizer); 34 | } 35 | 36 | private void logSLLFailed(Token token) { 37 | int line = token.getLine(); 38 | String sourceName = compilationUnit.getSource().getFileName(); 39 | LOG.fine("SLL failed:" + sourceName + ":" + line); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/AnnotationNode.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * 10 | * @author Kason Yang 11 | */ 12 | public class AnnotationNode extends AstNode{ 13 | 14 | protected ClassNode annotationType; 15 | 16 | public final Map values = new HashMap<>(); 17 | 18 | public AnnotationNode(ClassNode annotationType) { 19 | this.annotationType = annotationType; 20 | } 21 | 22 | public ClassNode getAnnotationType() { 23 | return annotationType; 24 | } 25 | 26 | @Override 27 | public List getChildren() { 28 | return noChildren(); 29 | } 30 | 31 | @Override 32 | public void updateChildren(ChildUpdater childUpdater) { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/Annotationable.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface Annotationable { 8 | 9 | AnnotationNode[] getAnnotations(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ArithmeticBinaryExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | /** 5 | * 6 | * @author Kason Yang 7 | */ 8 | public class ArithmeticBinaryExpr extends BinaryExpr{ 9 | 10 | public ArithmeticBinaryExpr(ExprNode expr1, ExprNode expr2, String operation) { 11 | super(expr1, expr2, operation); 12 | } 13 | 14 | @Override 15 | public Type getType() { 16 | return getType(getExpr1()); 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ArrayLengthExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | import kalang.compiler.core.Type; 5 | import kalang.compiler.core.Types; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.util.List; 9 | import java.util.Objects; 10 | /** 11 | * 12 | * @author Kason Yang 13 | */ 14 | public class ArrayLengthExpr extends ExprNode{ 15 | 16 | @Nonnull 17 | protected ExprNode arrayExpr; 18 | 19 | public ArrayLengthExpr(@Nonnull ExprNode arrayExpr) { 20 | this.arrayExpr = arrayExpr; 21 | } 22 | 23 | @Override 24 | public Type getType() { 25 | return Types.INT_TYPE; 26 | } 27 | 28 | /** 29 | * @return the arrayExpr 30 | */ 31 | public ExprNode getArrayExpr() { 32 | return arrayExpr; 33 | } 34 | 35 | /** 36 | * @param arrayExpr the arrayExpr to set 37 | */ 38 | public void setArrayExpr(@Nonnull ExprNode arrayExpr) { 39 | Objects.requireNonNull(arrayExpr); 40 | this.arrayExpr = arrayExpr; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return arrayExpr + ".length"; 46 | } 47 | 48 | @Override 49 | public List getChildren() { 50 | return noNullChildren(arrayExpr); 51 | } 52 | 53 | @Override 54 | public void updateChildren(ChildUpdater childUpdater) { 55 | arrayExpr = doUpdateChild(arrayExpr, childUpdater); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/AssignableExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | /** 5 | * 6 | * @author Kason Yang 7 | */ 8 | public abstract class AssignableExpr extends ExprNode{ 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/AssignableObject.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.Type; 4 | import kalang.compiler.core.Types; 5 | public abstract class AssignableObject extends AstNode{ 6 | 7 | private int modifier; 8 | 9 | private int extendModifier; 10 | 11 | private final Type type; 12 | 13 | private final String name; 14 | 15 | protected AssignableObject(int modifier, Type type, String name){ 16 | this.modifier = modifier; 17 | this.type = type; 18 | this.name = name; 19 | } 20 | 21 | public Type getType(){ 22 | if(type!=null) return type; 23 | return Types.getRootType(); 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return name==null ? "[temp]" : name; 33 | } 34 | 35 | public int getModifier() { 36 | return modifier; 37 | } 38 | 39 | public void setModifier(int modifier) { 40 | this.modifier = modifier; 41 | } 42 | 43 | public void setExtendModifier(int extendModifier) { 44 | this.extendModifier = extendModifier; 45 | } 46 | 47 | public int getExtendModifier() { 48 | return extendModifier; 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/AwaitExpr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.Type; 4 | import kalang.compiler.util.AsyncUtil; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.util.List; 8 | 9 | /** 10 | * @author KasonYang 11 | */ 12 | public class AwaitExpr extends ExprNode { 13 | 14 | private ExprNode expr; 15 | 16 | public AwaitExpr(ExprNode expr) { 17 | this.expr = expr; 18 | } 19 | 20 | @Nonnull 21 | @Override 22 | public Type getType() { 23 | Type exprType = expr.getType(); 24 | return AsyncUtil.getAsyncResultType(exprType); 25 | } 26 | 27 | public ExprNode getExpr() { 28 | return expr; 29 | } 30 | 31 | public void setExpr(ExprNode expr) { 32 | this.expr = expr; 33 | } 34 | 35 | @Override 36 | public List getChildren() { 37 | return noNullChildren(expr); 38 | } 39 | 40 | @Override 41 | public void updateChildren(ChildUpdater childUpdater) { 42 | expr = doUpdateChild(expr, childUpdater); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/BitwiseBinaryExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class BitwiseBinaryExpr extends BinaryExpr{ 10 | 11 | public BitwiseBinaryExpr(ExprNode expr1, ExprNode expr2, String operation) { 12 | super(expr1, expr2, operation); 13 | } 14 | 15 | @Override 16 | public Type getType() { 17 | return getType(getExpr1()); 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/BlockStmt.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | package kalang.compiler.ast; 5 | 6 | import java.util.Arrays; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | public class BlockStmt extends Statement{ 10 | 11 | public List statements = new LinkedList<>(); 12 | protected final List vars = new LinkedList(); 13 | 14 | public BlockStmt(){ 15 | } 16 | 17 | public BlockStmt(Statement[] stmts){ 18 | statements.addAll(Arrays.asList(stmts)); 19 | } 20 | 21 | @Override 22 | public List getChildren(){ 23 | List ls = new LinkedList(); 24 | addChild(ls,statements); 25 | return ls; 26 | } 27 | 28 | @Override 29 | public void updateChildren(ChildUpdater childMapper) { 30 | doUpdateChildren(statements, childMapper); 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/BreakStmt.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | package kalang.compiler.ast; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | public class BreakStmt extends Statement{ 10 | 11 | @Override 12 | public String toString() { 13 | return "break"; 14 | } 15 | 16 | @Override 17 | public List getChildren() { 18 | return Collections.emptyList(); 19 | } 20 | 21 | @Override 22 | public void updateChildren(ChildUpdater childMapper) { 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/CastExpr.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | package kalang.compiler.ast; 5 | 6 | import kalang.compiler.core.Type; 7 | 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | public class CastExpr extends ExprNode{ 11 | 12 | protected Type toType; 13 | 14 | protected ExprNode expr; 15 | 16 | public CastExpr(Type type,ExprNode expr){ 17 | this.toType = type; 18 | this.expr = expr; 19 | } 20 | 21 | public List getChildren(){ 22 | List ls = new LinkedList(); 23 | addChild(ls, expr); 24 | return ls; 25 | } 26 | 27 | @Override 28 | public void updateChildren(ChildUpdater childMapper) { 29 | expr = doUpdateChild(expr, childMapper); 30 | } 31 | 32 | @Override 33 | public Type getType() { 34 | return getToType(); 35 | } 36 | 37 | /** 38 | * @return the toType 39 | */ 40 | public Type getToType() { 41 | return toType; 42 | } 43 | 44 | /** 45 | * @return the expr 46 | */ 47 | public ExprNode getExpr() { 48 | return expr; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "(" + toType + ")" + expr; 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/CatchBlock.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class CatchBlock extends AstNode { 7 | 8 | public LocalVarNode catchVar; 9 | 10 | public BlockStmt execStmt; 11 | 12 | public CatchBlock(LocalVarNode catchVar, BlockStmt execStmt) { 13 | this.catchVar = catchVar; 14 | this.execStmt = execStmt; 15 | } 16 | 17 | @Override 18 | public List getChildren() { 19 | List ls = new LinkedList(); 20 | addChild(ls, catchVar); 21 | addChild(ls, execStmt); 22 | return ls; 23 | } 24 | 25 | @Override 26 | public void updateChildren(ChildUpdater childMapper) { 27 | catchVar = doUpdateChild(catchVar, childMapper); 28 | execStmt = doUpdateChild(execStmt, childMapper); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ChildUpdater.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface ChildUpdater { 7 | 8 | T update(T child); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ClassReference.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | import java.util.Objects; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class ClassReference extends AstNode{ 11 | 12 | private ClassNode referencedClassNode; 13 | 14 | public ClassReference(ClassNode referencedClassNode) { 15 | this.referencedClassNode = referencedClassNode; 16 | } 17 | 18 | public ClassNode getReferencedClassNode() { 19 | return referencedClassNode; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return Objects.toString(referencedClassNode); 25 | } 26 | 27 | @Override 28 | public void updateChildren(ChildUpdater childMapper) { 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/CompareBinaryExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | import kalang.compiler.core.Types; 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class CompareBinaryExpr extends BinaryExpr{ 10 | 11 | public CompareBinaryExpr(ExprNode expr1, ExprNode expr2, String operation) { 12 | super(expr1, expr2, operation); 13 | } 14 | 15 | @Override 16 | public Type getType() { 17 | return Types.BOOLEAN_TYPE; 18 | } 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ContinueStmt.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | package kalang.compiler.ast; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | public class ContinueStmt extends Statement{ 10 | 11 | @Override 12 | public String toString() { 13 | return "continue"; 14 | } 15 | 16 | @Override 17 | public List getChildren() { 18 | return Collections.emptyList(); 19 | } 20 | 21 | @Override 22 | public void updateChildren(ChildUpdater childMapper) { 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ErrorousExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | import kalang.compiler.core.Type; 5 | import kalang.compiler.core.Types; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | /** 10 | * 11 | * @author Kason Yang 12 | */ 13 | public class ErrorousExpr extends ExprNode{ 14 | 15 | private AstNode[] children; 16 | 17 | public ErrorousExpr(AstNode... children) { 18 | this.children = children; 19 | } 20 | 21 | @Override 22 | public List getChildren() { 23 | return Arrays.asList(children); 24 | } 25 | 26 | @Override 27 | public void updateChildren(ChildUpdater childMapper) { 28 | doUpdateChildren(children, childMapper); 29 | } 30 | 31 | @Override 32 | public Type getType() { 33 | return Types.getRootType(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ExprNode.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.Type; 4 | import kalang.compiler.core.Types; 5 | 6 | import javax.annotation.Nonnull; 7 | /** 8 | * The base class of expression node 9 | * 10 | * @author Kason Yang 11 | */ 12 | public abstract class ExprNode extends AstNode{ 13 | /** 14 | * The type of the expression 15 | */ 16 | //protected Type type; 17 | 18 | /** 19 | * @return the type 20 | */ 21 | @Nonnull 22 | public abstract Type getType(); 23 | 24 | protected static Type getType(ExprNode expr){ 25 | if(expr==null) return Types.VOID_TYPE; 26 | return expr.getType(); 27 | } 28 | 29 | /** 30 | * @param type the type to set 31 | */ 32 | // public void setType(Type type) { 33 | // this.type = type; 34 | // } 35 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ExprStmt.java: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | package kalang.compiler.ast; 5 | 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Objects; 9 | public class ExprStmt extends Statement{ 10 | 11 | protected ExprNode expr; 12 | 13 | public ExprStmt(ExprNode expr){ 14 | this.expr = expr; 15 | offset = expr.offset; 16 | } 17 | 18 | @Override 19 | public List getChildren(){ 20 | List ls = new LinkedList(); 21 | addChild(ls, expr); 22 | return ls; 23 | } 24 | 25 | @Override 26 | public void updateChildren(ChildUpdater childUpdater) { 27 | expr = doUpdateChild(expr, childUpdater); 28 | } 29 | 30 | /** 31 | * @return the expr 32 | */ 33 | public ExprNode getExpr() { 34 | return expr; 35 | } 36 | 37 | /** 38 | * @param expr the expr to set 39 | */ 40 | public void setExpr(ExprNode expr) { 41 | Objects.requireNonNull(expr); 42 | this.expr = expr; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return Objects.toString(expr); 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/FieldExpr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.compile.semantic.FieldNotFoundException; 4 | import kalang.compiler.core.FieldDescriptor; 5 | import kalang.compiler.core.ObjectType; 6 | import kalang.compiler.core.Type; 7 | 8 | import javax.annotation.Nonnull; 9 | import javax.annotation.Nullable; 10 | import java.util.Objects; 11 | 12 | public abstract class FieldExpr extends AssignableExpr{ 13 | 14 | @Nonnull 15 | private FieldDescriptor field; 16 | 17 | @Nonnull 18 | protected static FieldDescriptor getField(ObjectType type, String fieldName, @Nullable ClassNode caller) throws FieldNotFoundException{ 19 | FieldDescriptor field = type.getFieldDescriptor(caller,fieldName); 20 | if(field==null){ 21 | throw new FieldNotFoundException(fieldName); 22 | } 23 | return field; 24 | } 25 | 26 | public FieldExpr(@Nonnull FieldDescriptor field){ 27 | this.field = field; 28 | } 29 | 30 | @Override 31 | public Type getType() { 32 | return field.getType(); 33 | } 34 | 35 | @Nonnull 36 | public FieldDescriptor getField(){ 37 | return field; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return Objects.toString(field); 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/FieldNode.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.FieldDescriptor; 4 | import kalang.compiler.core.Type; 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class FieldNode extends AssignableObject implements FieldDescriptor{ 10 | 11 | private final ClassNode classNode; 12 | 13 | protected FieldNode(ClassNode classNode,Type type,String name,int modifier) { 14 | super(modifier,type,name); 15 | this.classNode = classNode; 16 | } 17 | 18 | @Override 19 | public FieldNode getFieldNode() { 20 | return this; 21 | } 22 | 23 | public ClassNode getClassNode() { 24 | return classNode; 25 | } 26 | 27 | @Override 28 | public void updateChildren(ChildUpdater childUpdater) { 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/FinallyBlock.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | /** 7 | * @author KasonYang 8 | */ 9 | public class FinallyBlock extends AstNode { 10 | 11 | private BlockStmt execStmt; 12 | 13 | public FinallyBlock(BlockStmt execStmt) { 14 | this.execStmt = execStmt; 15 | } 16 | 17 | public BlockStmt getExecStmt() { 18 | return execStmt; 19 | } 20 | 21 | 22 | @Override 23 | public List getChildren() { 24 | return Collections.singletonList(execStmt); 25 | } 26 | 27 | @Override 28 | public void updateChildren(ChildUpdater childUpdater) { 29 | execStmt = doUpdateChild(execStmt, childUpdater); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/IncExpr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.Type; 4 | 5 | import javax.annotation.Nonnull; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | /** 10 | * @author KasonYang 11 | */ 12 | public class IncExpr extends ExprNode { 13 | 14 | private VarObject var; 15 | 16 | private ExprNode increment; 17 | 18 | private boolean isOperatorPrefixed; 19 | 20 | public IncExpr(VarObject varObject, ExprNode increment, boolean isPrefixedOperator) { 21 | this.var = varObject; 22 | this.increment = increment; 23 | this.isOperatorPrefixed = isPrefixedOperator; 24 | } 25 | 26 | public VarObject getVar() { 27 | return var; 28 | } 29 | 30 | public ExprNode getIncrement() { 31 | return increment; 32 | } 33 | 34 | public boolean isOperatorPrefixed() { 35 | return isOperatorPrefixed; 36 | } 37 | 38 | @Nonnull 39 | @Override 40 | public Type getType() { 41 | return var.getType(); 42 | } 43 | 44 | @Override 45 | public List getChildren() { 46 | return Collections.singletonList(increment); 47 | } 48 | 49 | @Override 50 | public void updateChildren(ChildUpdater childUpdater) { 51 | increment = doUpdateChild(increment, childUpdater); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/InstanceOfExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | import kalang.compiler.core.Types; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | /** 10 | * 11 | * @author Kason Yang 12 | */ 13 | public class InstanceOfExpr extends ExprNode{ 14 | 15 | protected ClassReference target; 16 | 17 | protected ExprNode expr; 18 | 19 | public InstanceOfExpr(ExprNode expr, ClassReference target) { 20 | this.target = target; 21 | this.expr = expr; 22 | } 23 | 24 | @Override 25 | public Type getType() { 26 | return Types.BOOLEAN_TYPE; 27 | } 28 | 29 | public ClassReference getTarget() { 30 | return target; 31 | } 32 | 33 | public ExprNode getExpr() { 34 | return expr; 35 | } 36 | 37 | @Override 38 | public List getChildren() { 39 | return Collections.singletonList(expr); 40 | } 41 | 42 | @Override 43 | public void updateChildren(ChildUpdater childUpdater) { 44 | expr = doUpdateChild(expr, childUpdater); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/LocalVarNode.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | import kalang.compiler.core.Type; 5 | 6 | import javax.annotation.Nullable; 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class LocalVarNode extends VarObject { 12 | 13 | public LocalVarNode(Type type,@Nullable String name){ 14 | this(type,name,0); 15 | } 16 | 17 | public LocalVarNode(Type type, String name,int modifier) { 18 | super(modifier, type, name); 19 | } 20 | 21 | @Override 22 | public void updateChildren(ChildUpdater childUpdater) { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/LogicBinaryExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | import kalang.compiler.core.Types; 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class LogicBinaryExpr extends BinaryExpr{ 10 | 11 | public LogicBinaryExpr(ExprNode expr1, ExprNode expr2, String operation) { 12 | super(expr1, expr2, operation); 13 | } 14 | 15 | @Override 16 | public Type getType() { 17 | return Types.BOOLEAN_TYPE; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/MultiStmt.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | public class MultiStmt extends Statement{ 6 | 7 | public final List statements = new LinkedList<>(); 8 | 9 | public MultiStmt(){ 10 | 11 | } 12 | 13 | public MultiStmt(List stmts) { 14 | statements.addAll(stmts); 15 | } 16 | 17 | @Override 18 | public List getChildren(){ 19 | List ls = new LinkedList(); 20 | addChild(ls,statements); 21 | return ls; 22 | } 23 | 24 | @Override 25 | public void updateChildren(ChildUpdater childUpdater) { 26 | doUpdateChildren(statements, childUpdater); 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ParameterNode.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | /** 5 | * 6 | * @author Kason Yang 7 | */ 8 | public class ParameterNode extends VarObject { 9 | 10 | private final MethodNode method; 11 | 12 | protected ParameterNode(MethodNode method,Type type,String name) { 13 | this(method,0,type,name); 14 | } 15 | 16 | protected ParameterNode(MethodNode method,int modifier,Type type ,String name) { 17 | super(modifier,type,name); 18 | this.method = method; 19 | } 20 | 21 | public MethodNode getMethod() { 22 | return method; 23 | } 24 | 25 | @Override 26 | public void updateChildren(ChildUpdater childUpdater) { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ReturnStmt.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | public class ReturnStmt extends Statement{ 6 | 7 | private ExprNode expr = null; 8 | 9 | 10 | public ReturnStmt(){ 11 | 12 | } 13 | 14 | public ReturnStmt(ExprNode expr){ 15 | this.expr = expr; 16 | } 17 | 18 | @Override 19 | public List getChildren(){ 20 | List ls = new LinkedList(); 21 | if(expr!=null){ 22 | addChild(ls,expr); 23 | } 24 | return ls; 25 | } 26 | 27 | @Override 28 | public void updateChildren(ChildUpdater childUpdater) { 29 | expr = doUpdateChild(expr, childUpdater); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "return " + (expr == null ? "" : expr); 35 | } 36 | 37 | public ExprNode getExpr() { 38 | return expr; 39 | } 40 | 41 | public void setExpr(ExprNode expr) { 42 | this.expr = expr; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/Statement.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | /** 4 | * The base class of any statement node 5 | * @author Kason Yang 6 | */ 7 | public abstract class Statement extends AstNode{ 8 | 9 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/SuperExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | import kalang.compiler.core.Type; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | /** 9 | * 10 | * @author Kason Yang 11 | */ 12 | public class SuperExpr extends ExprNode{ 13 | 14 | private ClassNode classNode; 15 | 16 | public SuperExpr(ClassNode callerClassNode) { 17 | this.classNode = callerClassNode; 18 | } 19 | 20 | @Override 21 | public Type getType() { 22 | if(classNode.getSuperType()==null){ 23 | return null; 24 | } 25 | return classNode.getSuperType(); 26 | } 27 | 28 | public ClassNode getClassNode() { 29 | return classNode; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "super"; 35 | } 36 | 37 | @Override 38 | public List getChildren() { 39 | return Collections.emptyList(); 40 | } 41 | 42 | @Override 43 | public void updateChildren(ChildUpdater childUpdater) { 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ThisExpr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.ObjectType; 4 | import kalang.compiler.core.Type; 5 | import kalang.compiler.core.Types; 6 | 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class ThisExpr extends ExprNode{ 11 | 12 | private final ObjectType classType; 13 | 14 | public ThisExpr(ObjectType classType){ 15 | this.classType = classType; 16 | } 17 | 18 | public ThisExpr(ClassNode classNode){ 19 | this(Types.getClassType(classNode)); 20 | } 21 | 22 | @Override 23 | public Type getType() { 24 | return classType; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "this"; 30 | } 31 | 32 | @Override 33 | public List getChildren() { 34 | return Collections.emptyList(); 35 | } 36 | 37 | @Override 38 | public void updateChildren(ChildUpdater childUpdater) { 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/ThrowStmt.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | public class ThrowStmt extends Statement{ 6 | 7 | private ExprNode expr; 8 | 9 | public ThrowStmt(ExprNode expr){ 10 | this.expr = expr; 11 | } 12 | 13 | public List getChildren(){ 14 | List ls = new LinkedList(); 15 | addChild(ls,expr); 16 | return ls; 17 | } 18 | 19 | @Override 20 | public void updateChildren(ChildUpdater childUpdater) { 21 | expr = doUpdateChild(expr, childUpdater); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "throw " + expr; 27 | } 28 | 29 | public ExprNode getExpr() { 30 | return expr; 31 | } 32 | 33 | public void setExpr(ExprNode expr) { 34 | this.expr = expr; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/UnknownFieldExpr.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.ast; 3 | 4 | import kalang.compiler.core.Type; 5 | import kalang.compiler.core.Types; 6 | 7 | import java.util.Collections; 8 | import java.util.List; 9 | /** 10 | * 11 | * @author Kason Yang 12 | */ 13 | public class UnknownFieldExpr extends AssignableExpr{ 14 | 15 | private AstNode target; 16 | 17 | private String fieldName; 18 | 19 | private ClassNode specialClass; 20 | 21 | public UnknownFieldExpr(AstNode target,ClassNode specialClass, String fieldName) { 22 | this.target = target; 23 | this.fieldName = fieldName; 24 | this.specialClass = specialClass; 25 | } 26 | 27 | public AstNode getTarget() { 28 | return target; 29 | } 30 | 31 | public String getFieldName() { 32 | return fieldName; 33 | } 34 | 35 | @Override 36 | public Type getType() { 37 | return Types.getRootType(); 38 | } 39 | 40 | @Override 41 | public List getChildren() { 42 | return Collections.singletonList(target); 43 | } 44 | 45 | @Override 46 | public void updateChildren(ChildUpdater childUpdater) { 47 | target = doUpdateChild(target, childUpdater); 48 | } 49 | 50 | public ClassNode getSpecialClass() { 51 | return specialClass; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/VarDeclStmt.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.mixin.CollectionMixin; 4 | 5 | import java.util.Collections; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | public class VarDeclStmt extends Statement{ 9 | 10 | public final List vars = new LinkedList<>(); 11 | 12 | public VarDeclStmt(LocalVarNode var){ 13 | this(Collections.singletonList(var)); 14 | } 15 | 16 | public VarDeclStmt(List var){ 17 | this.vars.addAll(var); 18 | } 19 | 20 | 21 | @Override 22 | public List getChildren(){ 23 | return new LinkedList<>(vars); 24 | } 25 | 26 | @Override 27 | public void updateChildren(ChildUpdater childUpdater) { 28 | doUpdateChildren(vars, childUpdater); 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | List vs = CollectionMixin.map(vars, (v) -> v.getType() + " " + v.getName()); 34 | return String.join(",", vs); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/VarExpr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.Type; 4 | 5 | import javax.annotation.Nullable; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class VarExpr extends AssignableExpr{ 11 | 12 | protected final VarObject var; 13 | 14 | @Nullable 15 | protected Type overrideType; 16 | 17 | public VarExpr(VarObject var){ 18 | this.var = var; 19 | } 20 | 21 | public VarExpr(VarObject var, @Nullable Type overrideType) { 22 | this.var = var; 23 | this.overrideType = overrideType; 24 | } 25 | 26 | @Override 27 | public Type getType() { 28 | return overrideType !=null ? overrideType : var.getType(); 29 | } 30 | 31 | /** 32 | * @return the var 33 | */ 34 | public VarObject getVar() { 35 | return var; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return Objects.toString(var); 41 | } 42 | 43 | public void overrideType(Type newType) { 44 | overrideType = newType; 45 | } 46 | 47 | public void removeOverrideType(){ 48 | overrideType = null; 49 | } 50 | 51 | @Override 52 | public List getChildren() { 53 | return Collections.emptyList(); 54 | } 55 | 56 | @Override 57 | public void updateChildren(ChildUpdater childUpdater) { 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/VarObject.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import kalang.compiler.core.Type; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public abstract class VarObject extends AssignableObject { 9 | 10 | protected VarObject(int modifier, Type type, String name) { 11 | super(modifier, type, name); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/ast/YieldStmt.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.ast; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | /** 7 | * @author KasonYang 8 | */ 9 | public class YieldStmt extends Statement { 10 | 11 | private ExprNode expr; 12 | 13 | public YieldStmt(ExprNode expr) { 14 | this.expr = expr; 15 | } 16 | 17 | public ExprNode getExpr() { 18 | return expr; 19 | } 20 | 21 | @Override 22 | public List getChildren() { 23 | return Collections.singletonList(expr); 24 | } 25 | 26 | @Override 27 | public void updateChildren(ChildUpdater childUpdater) { 28 | expr = doUpdateChild(expr, childUpdater); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/ClassNodeLoader.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | import kalang.compiler.ast.ClassNode; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public interface ClassNodeLoader { 9 | 10 | default ClassNode loadClassNode(String className) { 11 | ClassNode cn = getClassNode(className); 12 | if (cn == null) { 13 | throw new ClassNodeNotFoundException(className); 14 | } 15 | return cn; 16 | } 17 | 18 | ClassNode getClassNode(String className); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/ClassNodeNotFoundException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | public class ClassNodeNotFoundException extends RuntimeException { 4 | 5 | public ClassNodeNotFoundException(String clsName) { 6 | super(clsName); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile; 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public interface CodeGenerator { 8 | 9 | void generateCode(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/CompilationUnitController.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | import kalang.compiler.profile.Profiler; 4 | import kalang.compiler.profile.Span; 5 | 6 | /** 7 | * @author KasonYang 8 | */ 9 | public class CompilationUnitController { 10 | 11 | private CompilationUnit compilationUnit; 12 | 13 | private CompilePhase currentPhase; 14 | 15 | public CompilationUnitController(CompilationUnit compilationUnit, CompilePhase startPhase) { 16 | this.compilationUnit = compilationUnit; 17 | this.currentPhase = startPhase; 18 | } 19 | 20 | public CompilationUnit getCompilationUnit() { 21 | return compilationUnit; 22 | } 23 | 24 | public void compileToPhase(CompilePhase stopPhase) { 25 | while (!currentPhase.isLastPhase() && currentPhase.isBefore(stopPhase)) { 26 | currentPhase = currentPhase.nextPhase(); 27 | Span span = Profiler.getInstance().beginSpan("compilationPhase@" + currentPhase.getId()); 28 | currentPhase.process(compilationUnit); 29 | Profiler.getInstance().endSpan(span); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/CompileContext.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile; 3 | import kalang.compiler.antlr.KalangLexer; 4 | import kalang.compiler.antlr.KalangParser; 5 | import kalang.compiler.compile.semantic.AstBuilder; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public interface CompileContext { 12 | 13 | KalangLexer createLexer(CompilationUnit compilationUnit,String source); 14 | 15 | KalangParser createParser(CompilationUnit compilationUnit,KalangLexer lexer); 16 | 17 | AstBuilder createAstBuilder(CompilationUnit compilationUnit, KalangParser parser); 18 | 19 | SemanticAnalyzer createSemanticAnalyzer(CompilationUnit compilationUnit); 20 | 21 | CodeGenerator createCodeGenerator(CompilationUnit compilationUnit); 22 | 23 | ClassNodeLoader getClassNodeLoader(); 24 | 25 | SourceLoader getSourceLoader(); 26 | 27 | DiagnosisHandler getDiagnosisHandler(); 28 | 29 | void stopCompile(String stopPhaseId); 30 | 31 | CompilePhase getCompilingPhase(); 32 | 33 | Configuration getConfiguration(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/CompilePhase.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile; 3 | 4 | /** 5 | * @author Kason Yang 6 | */ 7 | public interface CompilePhase { 8 | 9 | String getId(); 10 | 11 | boolean isBefore(CompilePhase other); 12 | 13 | CompilePhase nextPhase(); 14 | 15 | boolean isLastPhase(); 16 | 17 | void process(CompilationUnit compilationUnit); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/Configuration.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | import kalang.compiler.compile.jvm.JvmClassNodeLoader; 4 | import kalang.lang.Script; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class Configuration { 11 | 12 | private String scriptBaseClass = Script.class.getName(); 13 | 14 | private String encoding = "utf8"; 15 | 16 | private ClassNodeLoader classNodeLoader = new JvmClassNodeLoader(); 17 | 18 | public static Configuration copy(Configuration other) { 19 | Configuration conf = new Configuration(); 20 | conf.scriptBaseClass = other.scriptBaseClass; 21 | conf.encoding = other.encoding; 22 | conf.classNodeLoader = other.classNodeLoader; 23 | return conf; 24 | } 25 | 26 | public String getScriptBaseClass() { 27 | return scriptBaseClass; 28 | } 29 | 30 | public void setScriptBaseClass(String scriptBaseClass) { 31 | this.scriptBaseClass = scriptBaseClass; 32 | } 33 | 34 | public String getEncoding() { 35 | return encoding; 36 | } 37 | 38 | public void setEncoding(String encoding) { 39 | this.encoding = encoding; 40 | } 41 | 42 | public ClassNodeLoader getClassNodeLoader() { 43 | return classNodeLoader; 44 | } 45 | 46 | public void setClassNodeLoader(ClassNodeLoader classNodeLoader) { 47 | this.classNodeLoader = classNodeLoader; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/DiagnosisHandler.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public interface DiagnosisHandler { 7 | 8 | void handleDiagnosis(Diagnosis diagnosis); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/FileKalangSource.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | import java.io.*; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public class FileKalangSource implements KalangSource { 9 | 10 | private String className; 11 | 12 | private File file; 13 | 14 | private boolean isScript; 15 | 16 | public FileKalangSource(String className, File file, boolean isScript) { 17 | this.className = className; 18 | this.file = file; 19 | this.isScript = isScript; 20 | } 21 | 22 | @Override 23 | public String getClassName() { 24 | return className; 25 | } 26 | 27 | @Override 28 | public InputStream createInputStream() throws IOException { 29 | return new FileInputStream(file); 30 | } 31 | 32 | @Override 33 | public String getFileName() { 34 | return file.getAbsolutePath(); 35 | } 36 | 37 | @Override 38 | public boolean isScript() { 39 | return isScript; 40 | } 41 | 42 | public File getFile() { 43 | return file; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/InMemoryKalangSource.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile; 3 | 4 | import java.io.ByteArrayInputStream; 5 | import java.io.InputStream; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class InMemoryKalangSource implements KalangSource { 12 | 13 | 14 | private String className; 15 | 16 | private byte[] content; 17 | 18 | private String fileName; 19 | 20 | private boolean script; 21 | 22 | public InMemoryKalangSource(String className, byte[] content, String fileName, boolean script) { 23 | this.className = className; 24 | this.content = content; 25 | this.fileName = fileName; 26 | this.script = script; 27 | } 28 | 29 | @Override 30 | public String getClassName() { 31 | return className; 32 | } 33 | 34 | @Override 35 | public InputStream createInputStream() { 36 | return new ByteArrayInputStream(content); 37 | } 38 | 39 | @Override 40 | public String getFileName() { 41 | return fileName; 42 | } 43 | 44 | @Override 45 | public boolean isScript() { 46 | return script; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/KalangSource.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile; 3 | 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public interface KalangSource { 12 | 13 | String[] EXTENSION_STANDARD = new String[] {"kl", "kalang"}; 14 | 15 | String[] EXTENSION_SCRIPT = new String[] {"kls"}; 16 | 17 | 18 | String getClassName(); 19 | 20 | InputStream createInputStream() throws IOException; 21 | 22 | String getFileName(); 23 | 24 | boolean isScript(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/OffsetRange.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public class OffsetRange { 8 | 9 | public int 10 | startOffset, 11 | stopOffset, 12 | startLine, 13 | startLineColumn, 14 | stopLine, 15 | stopLineColumn; 16 | 17 | public final static OffsetRange NONE = new OffsetRange(); 18 | 19 | public OffsetRange(int startOffset, int stopOffset, int startLine, int startLineColumn, int stopLine, int stopLineColumn) { 20 | this.startOffset = startOffset; 21 | this.stopOffset = stopOffset; 22 | this.startLine = startLine; 23 | this.startLineColumn = startLineColumn; 24 | this.stopLine = stopLine; 25 | this.stopLineColumn = stopLineColumn; 26 | } 27 | 28 | public OffsetRange() { 29 | startOffset = -1; 30 | stopOffset =-1; 31 | startLine = -1; 32 | startLineColumn = -1; 33 | stopLine = -1; 34 | stopLineColumn = -1; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return String.format("(%d,%d)",startOffset,stopOffset); 40 | } 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/PhaseProcessor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | 4 | /** 5 | * @author KasonYang 6 | */ 7 | public interface PhaseProcessor { 8 | 9 | void process(CompilationUnit compilationUnit); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/SemanticAnalyzer.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface SemanticAnalyzer { 7 | 8 | void semanticAnalyze(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/SourceLoader.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile; 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.Nullable; 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public interface SourceLoader { 10 | 11 | @Nullable 12 | KalangSource loadSource(@Nonnull String className); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/StandardCompilePhases.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public final class StandardCompilePhases { 7 | 8 | public final static String PARSE_DECLARATION = "PARSE_DECLARATION"; 9 | public final static String BUILD_DEFAULT_MEMBERS = "BUILD_DEFAULT_MEMBERS"; 10 | public final static String PARSE_BODY = "PARSE_BODY"; 11 | public final static String ANALYZE_SEMANTIC = "ANALYZE_SEMANTIC"; 12 | public final static String GENERATE_CODE = "GENERATE_CODE"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/CatchContext.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen; 2 | 3 | import kalang.compiler.compile.codegen.op.LabelOp; 4 | 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | public class CatchContext { 9 | 10 | private final LabelOp startLabel,stopLabel; 11 | 12 | private final List excludeLabels = new LinkedList<>(); 13 | 14 | public CatchContext(LabelOp startLabel, LabelOp stopLabel) { 15 | this.startLabel = startLabel; 16 | this.stopLabel = stopLabel; 17 | } 18 | 19 | public void addExclude(LabelOp startLabel, LabelOp stopLabel) { 20 | excludeLabels.add(startLabel); 21 | excludeLabels.add(stopLabel); 22 | } 23 | 24 | public LabelOp[] getCatchLabels() { 25 | int size = excludeLabels.size(); 26 | LabelOp[] labels = new LabelOp[size+2]; 27 | for(int i=1;i successors = new LinkedList<>(); 17 | 18 | private List predecessors = new LinkedList<>(); 19 | 20 | public LabelOp() { 21 | this.id = labelIdCounter ++; 22 | } 23 | 24 | @Override 25 | public String[][] getIoTypes() { 26 | return noTypes(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "Label_" + id; 32 | } 33 | 34 | public void addSuccessor(LabelOp successor) { 35 | successors.add(successor); 36 | successor.predecessors.add(this); 37 | } 38 | 39 | public Collection getSuccessors() { 40 | return successors; 41 | } 42 | 43 | public Collection getPredecessors() { 44 | return predecessors; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/LdcInsnOp.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | import kalang.compiler.util.Exceptions; 4 | 5 | import static org.objectweb.asm.Opcodes.LDC; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class LdcInsnOp extends OpBase { 11 | 12 | public Object value; 13 | 14 | public LdcInsnOp(Object value) { 15 | this.opcode = LDC; 16 | this.value = value; 17 | } 18 | 19 | @Override 20 | public String[][] getIoTypes() { 21 | if (value instanceof Integer){ 22 | return outTypes(ST_INT); 23 | } else if (value instanceof Byte){ 24 | return outTypes(ST_BYTE); 25 | } else if (value instanceof Short){ 26 | return outTypes(ST_SHORT); 27 | } else if (value instanceof Boolean) { 28 | return outTypes(ST_BOOLEAN); 29 | } else if (value instanceof Long) { 30 | return outTypes(ST_LONG); 31 | } else if (value instanceof Float) { 32 | return outTypes(ST_FLOAT); 33 | } else if (value instanceof Double) { 34 | return outTypes(ST_DOUBLE); 35 | } else if (value instanceof String) { 36 | return outTypes(ST_STRING); 37 | } else { 38 | throw Exceptions.unsupportedTypeException(value); 39 | } 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return "LDC " + value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/LineNumberAttr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public class LineNumberAttr extends Attribute { 7 | 8 | public int lineNum; 9 | public LabelOp label; 10 | 11 | public LineNumberAttr(int lineNum, LabelOp label) { 12 | this.lineNum = lineNum; 13 | this.label = label; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/LocalVariableAttr.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public class LocalVariableAttr extends Attribute { 7 | public String name; 8 | public String descriptor; 9 | public String signature; 10 | public LabelOp start; 11 | public LabelOp end; 12 | public int index; 13 | 14 | public LocalVariableAttr(String name, String descriptor, String signature, LabelOp start, LabelOp end, int index) { 15 | this.name = name; 16 | this.descriptor = descriptor; 17 | this.signature = signature; 18 | this.start = start; 19 | this.end = end; 20 | this.index = index; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/MethodInsnOp.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public class MethodInsnOp extends OpBase { 9 | 10 | public String owner; 11 | public String name; 12 | public String descriptor; 13 | public boolean isInterface; 14 | 15 | public MethodInsnOp(int opcode, String owner, String name, String descriptor, boolean isInterface) { 16 | this.opcode = opcode; 17 | this.owner = owner; 18 | this.name = name; 19 | this.descriptor = descriptor; 20 | this.isInterface = isInterface; 21 | } 22 | 23 | @Override 24 | public String[][] getIoTypes() { 25 | return getIoTypesByMethodDescriptor(descriptor, opcode == Opcodes.INVOKESTATIC ? null : owner); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return String.format("%s %s.%s[%s]", OPC_DESC[opcode], owner, name, descriptor); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/MultiANewArrayInsnOp.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | import java.util.Arrays; 4 | 5 | import static org.objectweb.asm.Opcodes.MULTIANEWARRAY; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class MultiANewArrayInsnOp extends OpBase { 11 | 12 | public String descriptor; 13 | public int numDimensions; 14 | 15 | public MultiANewArrayInsnOp(String descriptor, int numDimensions) { 16 | this.opcode = MULTIANEWARRAY; 17 | this.descriptor = descriptor; 18 | this.numDimensions = numDimensions; 19 | } 20 | 21 | @Override 22 | public String[][] getIoTypes() { 23 | String[] inTypes = new String[numDimensions]; 24 | Arrays.fill(inTypes, ST_INT); 25 | return ioTypes(inTypes, types(ST_ANY)); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "MultiANewArray " + numDimensions; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/OpcodeOptimizer.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public interface OpcodeOptimizer { 9 | 10 | void optimize(List opcodes, List attributes); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/TypeInsnOp.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | 4 | import static org.objectweb.asm.Opcodes.*; 5 | 6 | /** 7 | * @author KasonYang 8 | */ 9 | public class TypeInsnOp extends OpBase { 10 | public String type; 11 | public TypeInsnOp(int opcode, String type) { 12 | this.opcode = opcode; 13 | this.type = type; 14 | } 15 | 16 | @Override 17 | public String[][] getIoTypes() { 18 | switch (opcode) { 19 | case CHECKCAST: 20 | return ioTypes(ST_ANY, "L" + type + ";"); 21 | case NEW: 22 | return outTypes("L" + type + ";"); 23 | case INSTANCEOF: 24 | return ioTypes(type, ST_INT); 25 | case ANEWARRAY: 26 | return ioTypes(ST_INT, "L" + type + ";"); 27 | default: 28 | throw unsupportedOpcode(opcode); 29 | } 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return OPC_DESC[opcode] + " " + type; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/VarInsnOp.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | import static org.objectweb.asm.Opcodes.*; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public class VarInsnOp extends OpBase { 9 | 10 | public int var; 11 | 12 | public VarInsnOp(int opcode, int var) { 13 | this.opcode = opcode; 14 | this.var = var; 15 | } 16 | 17 | @Override 18 | public String[][] getIoTypes() { 19 | switch (opcode) { 20 | case ILOAD: 21 | return outTypes(ST_INT); 22 | case LLOAD: 23 | return outTypes(ST_LONG); 24 | case FLOAD: 25 | return outTypes(ST_FLOAT); 26 | case DLOAD: 27 | return outTypes(ST_DOUBLE); 28 | case ALOAD: 29 | return outTypes(ST_ANY); 30 | case ISTORE: 31 | return inTypes(ST_INT); 32 | case LSTORE: 33 | return inTypes(ST_LONG); 34 | case FSTORE: 35 | return inTypes(ST_FLOAT); 36 | case DSTORE: 37 | return inTypes(ST_DOUBLE); 38 | case ASTORE: 39 | return inTypes(ST_ANY); 40 | default: 41 | throw unsupportedOpcode(opcode); 42 | } 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return OPC_DESC[opcode] + " " + var; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/codegen/op/YieldOp.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.codegen.op; 2 | 3 | import kalang.compiler.ast.VarObject; 4 | 5 | import java.util.LinkedHashMap; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class YieldOp extends OpBase { 11 | 12 | private int contextVarId; 13 | 14 | private int nextVarId; 15 | 16 | private LinkedHashMap vars; 17 | 18 | private LabelOp label = new LabelOp(); 19 | 20 | public YieldOp(int contextVarId, LinkedHashMap vars, int nextVarId) { 21 | this.opcode = TEMP_OP_YIELD; 22 | this.contextVarId = contextVarId; 23 | this.nextVarId = nextVarId; 24 | this.vars = vars; 25 | } 26 | 27 | public int getContextVarId() { 28 | return contextVarId; 29 | } 30 | 31 | public int getNextVarId() { 32 | return nextVarId; 33 | } 34 | 35 | public LinkedHashMap getVars() { 36 | return vars; 37 | } 38 | 39 | @Override 40 | public String[][] getIoTypes() { 41 | return noTypes(); 42 | } 43 | 44 | public LabelOp getLabel() { 45 | return label; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/AmbiguousMethodException.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile.semantic; 3 | 4 | import kalang.compiler.core.MethodDescriptor; 5 | 6 | import java.util.Collection; 7 | 8 | /** 9 | * 10 | * @author Kason Yang 11 | */ 12 | public class AmbiguousMethodException extends RuntimeException{ 13 | 14 | public AmbiguousMethodException(Collection methods){ 15 | this(methods.toArray(new MethodDescriptor[0])); 16 | } 17 | 18 | public static String[] getMethodDescriptorStrings(MethodDescriptor... methods){ 19 | String[] strs = new String[methods.length]; 20 | for(int i=0;i { 9 | 10 | T make(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/DefaultSemanticAnalyzer.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic; 2 | 3 | import kalang.compiler.compile.*; 4 | import kalang.compiler.compile.semantic.analyzer.AssignmentAnalyzer; 5 | import kalang.compiler.compile.semantic.analyzer.MethodDeclarationAnalyzer; 6 | import kalang.compiler.compile.util.DiagnosisReporter; 7 | 8 | /** 9 | * @author KasonYang 10 | */ 11 | public class DefaultSemanticAnalyzer implements SemanticAnalyzer { 12 | 13 | private CompilationUnit compilationUnit; 14 | 15 | public DefaultSemanticAnalyzer(CompilationUnit compilationUnit) { 16 | this.compilationUnit = compilationUnit; 17 | } 18 | 19 | @Override 20 | public void semanticAnalyze() { 21 | DiagnosisReporter dnReporter = new DiagnosisReporter(compilationUnit); 22 | new MethodDeclarationAnalyzer().analyze(compilationUnit); 23 | new AssignmentAnalyzer().analyze(compilationUnit); 24 | try { 25 | new AstVerifier().visit(compilationUnit.getAst()); 26 | } catch (MalformedAstException ex) { 27 | dnReporter.report(Diagnosis.Kind.ERROR, ex.getMessage(), ex.getMalformedNode().offset); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/FieldNotFoundException.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile.semantic; 3 | 4 | /** 5 | * 6 | * @author Kason Yang 7 | */ 8 | public class FieldNotFoundException extends RuntimeException{ 9 | 10 | public FieldNotFoundException(String message) { 11 | super(message); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/MalformedAstException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic; 2 | 3 | import kalang.compiler.ast.AstNode; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public class MalformedAstException extends RuntimeException { 9 | 10 | private AstNode malformedNode; 11 | 12 | public MalformedAstException(String message, AstNode malformedNode) { 13 | super(message); 14 | this.malformedNode = malformedNode; 15 | } 16 | 17 | public AstNode getMalformedNode() { 18 | return malformedNode; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/MethodNotFoundException.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.compile.semantic; 3 | import kalang.compiler.core.ObjectType; 4 | /** 5 | * 6 | * @author Kason Yang 7 | */ 8 | public class MethodNotFoundException extends RuntimeException{ 9 | 10 | public MethodNotFoundException(String message) { 11 | super(message); 12 | } 13 | 14 | public MethodNotFoundException(ObjectType type,String methodName) { 15 | super("method not found:" + type + "." + methodName); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/MissingParamMethodInfo.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic; 2 | 3 | import kalang.compiler.antlr.KalangParser; 4 | import kalang.compiler.ast.MethodNode; 5 | import lombok.Getter; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | @Getter 11 | public class MissingParamMethodInfo { 12 | 13 | private MethodNode missingParamMethod; 14 | 15 | private MethodNode originMethod; 16 | 17 | private KalangParser.MethodDeclContext methodDeclContext; 18 | 19 | public MissingParamMethodInfo(MethodNode missingParamMethod, MethodNode originMethod, KalangParser.MethodDeclContext methodDeclContext) { 20 | this.missingParamMethod = missingParamMethod; 21 | this.originMethod = originMethod; 22 | this.methodDeclContext = methodDeclContext; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/NodeException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic; 2 | 3 | import kalang.compiler.compile.OffsetRange; 4 | 5 | /** 6 | * @author KasonYang 7 | */ 8 | public class NodeException extends RuntimeException { 9 | 10 | private OffsetRange offsetRange; 11 | 12 | public NodeException(String message, OffsetRange offsetRange) { 13 | super(message); 14 | this.offsetRange = offsetRange; 15 | } 16 | 17 | public OffsetRange getOffsetRange() { 18 | return offsetRange; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/StatementSupplier.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic; 2 | 3 | import kalang.compiler.ast.Statement; 4 | 5 | public interface StatementSupplier { 6 | 7 | Statement get(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/analyzer/AstNodeCollector.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic.analyzer; 2 | 3 | import kalang.compiler.ast.AstNode; 4 | import kalang.compiler.ast.AstVisitor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | 10 | /** 11 | * @author KasonYang 12 | */ 13 | public class AstNodeCollector extends AstVisitor { 14 | 15 | private List collectList; 16 | 17 | private Class collectClass; 18 | 19 | public List collect(AstNode node, Class clazz) { 20 | collectList = new LinkedList(); 21 | collectClass = clazz; 22 | visit(node); 23 | return new ArrayList(collectList); 24 | } 25 | 26 | @Override 27 | public Object visit(AstNode node) { 28 | if (collectClass.isAssignableFrom(node.getClass())) { 29 | collectList.add(node); 30 | } 31 | return super.visit(node); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/semantic/analyzer/FieldUsageAnalyzer.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.semantic.analyzer; 2 | 3 | import kalang.compiler.ast.AstVisitor; 4 | import kalang.compiler.ast.ClassNode; 5 | import kalang.compiler.ast.FieldExpr; 6 | import kalang.compiler.ast.FieldNode; 7 | 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | 12 | /** 13 | * @author lbqh 14 | */ 15 | public class FieldUsageAnalyzer extends AstVisitor { 16 | 17 | 18 | private Set usedFields; 19 | 20 | public void analyzer(ClassNode classNode){ 21 | this.usedFields = new HashSet<>(); 22 | visit(classNode); 23 | } 24 | 25 | public Set getUsedFields() { 26 | return new HashSet<>(usedFields); 27 | } 28 | 29 | @Override 30 | public Object visitFieldExpr(FieldExpr node) { 31 | FieldNode fn = node.getField().getFieldNode(); 32 | usedFields.add(fn); 33 | return super.visitFieldExpr(node); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/util/DiagnosisReporter.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.util; 2 | 3 | import kalang.compiler.compile.*; 4 | 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class DiagnosisReporter { 10 | 11 | private final CompileContext compilationUnit; 12 | 13 | private final KalangSource kalangSource; 14 | 15 | public DiagnosisReporter(CompilationUnit compilationUnit) { 16 | this.compilationUnit = compilationUnit.getCompileContext(); 17 | this.kalangSource = compilationUnit.getSource(); 18 | } 19 | 20 | public void report(Diagnosis.Kind kind, String message, OffsetRange offset){ 21 | Diagnosis diagnosis = new Diagnosis(compilationUnit, kind, offset, message, kalangSource); 22 | compilationUnit.getDiagnosisHandler().handleDiagnosis(diagnosis); 23 | } 24 | 25 | public void error(String message, OffsetRange offsetRange) { 26 | report(Diagnosis.Kind.ERROR, message, offsetRange); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/compile/util/StandardDiagnosisHandler.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.compile.util; 2 | 3 | import kalang.compiler.compile.CompileContext; 4 | import kalang.compiler.compile.Diagnosis; 5 | import kalang.compiler.compile.DiagnosisHandler; 6 | import kalang.compiler.util.DiagnosisUtil; 7 | 8 | import java.io.PrintStream; 9 | 10 | /** 11 | * 12 | * @author Kason Yang 13 | */ 14 | public class StandardDiagnosisHandler implements DiagnosisHandler { 15 | 16 | private final PrintStream errOut; 17 | 18 | private final PrintStream stdOut; 19 | 20 | private boolean hasError = false; 21 | 22 | public StandardDiagnosisHandler() { 23 | this(System.out, System.err); 24 | } 25 | 26 | public StandardDiagnosisHandler(PrintStream stdOut, PrintStream errOut) { 27 | this.stdOut = stdOut; 28 | this.errOut = errOut; 29 | } 30 | 31 | @Override 32 | public void handleDiagnosis(Diagnosis diagnosis) { 33 | boolean isError = diagnosis.getKind().isError(); 34 | if (isError) { 35 | this.hasError = true; 36 | CompileContext ctx = diagnosis.getContext(); 37 | ctx.stopCompile(ctx.getCompilingPhase().getId()); 38 | } 39 | PrintStream o = isError ? errOut : stdOut; 40 | o.println(DiagnosisUtil.toPrintString(diagnosis)); 41 | } 42 | 43 | public boolean hasError() { 44 | return hasError; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/ExtendModifiers.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public class ExtendModifiers { 7 | 8 | public static final int GENERATOR = 1; 9 | 10 | public static final int ASYNC = 2; 11 | 12 | public static final int REF = 1 << 2; 13 | 14 | public static boolean isGenerator(int extendModifier) { 15 | return (GENERATOR & extendModifier) != 0; 16 | } 17 | 18 | public static boolean isAsync(int extendModifier) { 19 | return (ASYNC & extendModifier) != 0; 20 | } 21 | 22 | public static boolean isRef(int extendModifier) { 23 | return (REF & extendModifier) != 0; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/FieldDescriptor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | 3 | import kalang.compiler.ast.FieldNode; 4 | 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public interface FieldDescriptor { 10 | 11 | String getName(); 12 | 13 | Type getType(); 14 | 15 | int getModifier() ; 16 | 17 | FieldNode getFieldNode() ; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/MethodDescriptor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | 3 | import kalang.annotation.Nullable; 4 | import kalang.compiler.ast.ClassNode; 5 | import kalang.compiler.ast.MethodNode; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * @author KasonYang 11 | */ 12 | public interface MethodDescriptor { 13 | 14 | MethodDescriptor toParameterized(Map genericTypeMap, @Nullable Type[] actualArgumentTypes); 15 | 16 | Type[] getParameterTypes(); 17 | 18 | int getModifier(); 19 | 20 | MethodNode getMethodNode(); 21 | 22 | ParameterDescriptor[] getParameterDescriptors(); 23 | 24 | String getName(); 25 | 26 | String getDeclarationKey(); 27 | 28 | Type getReturnType(); 29 | 30 | //TODO exception type should be object type 31 | Type[] getExceptionTypes(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/ModifierConstant.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public class ModifierConstant { 7 | public static final int SYNTHETIC = 0x00001000; 8 | public static final int VARARGS = 0x0080; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/NullableKind.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public enum NullableKind { 7 | 8 | UNKNOWN,NULLABLE,NONNULL 9 | ; 10 | 11 | public boolean isAssignableFrom(NullableKind other){ 12 | if(this==NONNULL && other==NULLABLE) return false; 13 | return true; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/ParameterDescriptor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | 3 | /** 4 | * @author KasonYang 5 | */ 6 | public interface ParameterDescriptor { 7 | 8 | String getName(); 9 | 10 | Type getType(); 11 | 12 | int getModifier(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/PrimitiveType.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.core; 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public class PrimitiveType extends Type{ 8 | 9 | private String name; 10 | 11 | public PrimitiveType(String name) { 12 | this.name = name; 13 | } 14 | 15 | @Override 16 | public String getName(boolean simple) { 17 | return name; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/Type.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public abstract class Type { 7 | 8 | 9 | public String getName() { 10 | return getName(false); 11 | } 12 | 13 | public abstract String getName(boolean simple); 14 | 15 | public boolean isAssignableFrom(Type type){ 16 | return equals(type); 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return getName(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/impl/StandardFieldDescriptor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core.impl; 2 | 3 | import kalang.compiler.ast.FieldNode; 4 | import kalang.compiler.core.FieldDescriptor; 5 | import kalang.compiler.core.Type; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class StandardFieldDescriptor implements FieldDescriptor { 12 | 13 | private FieldNode field; 14 | 15 | private Type type; 16 | 17 | public StandardFieldDescriptor(FieldNode field, Type type) { 18 | this.field = field; 19 | this.type = type; 20 | } 21 | 22 | public StandardFieldDescriptor(FieldNode field) { 23 | this.field = field; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return field.getName(); 29 | } 30 | 31 | @Override 32 | public Type getType() { 33 | return type == null ? field.getType() : type ; 34 | } 35 | 36 | @Override 37 | public int getModifier() { 38 | return field.getModifier(); 39 | } 40 | 41 | @Override 42 | public FieldNode getFieldNode() { 43 | return field; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return getName(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/core/impl/StandardParameterDescriptor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.core.impl; 2 | 3 | import kalang.compiler.core.ParameterDescriptor; 4 | import kalang.compiler.core.Type; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class StandardParameterDescriptor implements ParameterDescriptor { 11 | 12 | private String name; 13 | 14 | private Type type; 15 | 16 | private int modifier; 17 | 18 | public StandardParameterDescriptor(String name, Type type,int modifier) { 19 | this.name = name; 20 | this.type = type; 21 | this.modifier = modifier; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | @Override 30 | public Type getType() { 31 | return type; 32 | } 33 | 34 | @Override 35 | public int getModifier() { 36 | return modifier; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/dependency/Artifact.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.dependency; 2 | 3 | public class Artifact { 4 | 5 | private String group; 6 | 7 | private String name; 8 | 9 | private String version; 10 | 11 | public Artifact(String group, String name, String version) { 12 | this.group = group; 13 | this.name = name; 14 | this.version = version; 15 | } 16 | 17 | public String getGroup() { 18 | return group; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public String getVersion() { 26 | return version; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return String.format("%s:%s:%s",group,name,version); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/dependency/NoMessageLogger.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.dependency; 2 | 3 | import org.apache.ivy.util.AbstractMessageLogger; 4 | 5 | public class NoMessageLogger extends AbstractMessageLogger { 6 | @Override 7 | protected void doProgress() { 8 | 9 | } 10 | 11 | @Override 12 | protected void doEndProgress(String msg) { 13 | 14 | } 15 | 16 | @Override 17 | public void log(String msg, int level) { 18 | 19 | } 20 | 21 | @Override 22 | public void rawlog(String msg, int level) { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/dependency/ResolveException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.dependency; 2 | 3 | public class ResolveException extends RuntimeException { 4 | 5 | public ResolveException() { 6 | } 7 | 8 | public ResolveException(String message) { 9 | super(message); 10 | } 11 | 12 | public ResolveException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | 16 | public ResolveException(Throwable cause) { 17 | super(cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/dependency/ResolveResult.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.dependency; 2 | 3 | import java.io.File; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class ResolveResult { 8 | 9 | private final List localFiles = new LinkedList<>(); 10 | 11 | public void addLocalFile(File file){ 12 | localFiles.add(file); 13 | } 14 | 15 | public File[] getLocalFiles(){ 16 | return localFiles.toArray(new File[0]); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/java/MemoryJavaSource.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.java; 2 | 3 | import javax.tools.SimpleJavaFileObject; 4 | import java.net.URI; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public abstract class MemoryJavaSource extends SimpleJavaFileObject{ 11 | 12 | protected final String className; 13 | 14 | public MemoryJavaSource(URI uri, Kind kind,String className) { 15 | super(uri, kind); 16 | this.className = className; 17 | } 18 | 19 | public String getClassName() { 20 | return className; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/java/StringJavaSource.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.java; 2 | 3 | import kalang.compiler.util.ClassNameUtil; 4 | import org.apache.commons.io.FileUtils; 5 | 6 | import javax.tools.JavaFileObject; 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.net.URI; 10 | 11 | /** 12 | * 13 | * @author Kason Yang 14 | */ 15 | public class StringJavaSource extends MemoryJavaSource { 16 | 17 | private final String content; 18 | 19 | public StringJavaSource(String className, String content) { 20 | super(URI.create(className.replace(".", "/") + ".java"), JavaFileObject.Kind.SOURCE,className); 21 | this.content = content; 22 | } 23 | 24 | @Override 25 | public CharSequence getCharContent(boolean ignoreEncodingErrors) { 26 | return content; 27 | } 28 | 29 | public static StringJavaSource loadFromFile(File root,File file) throws IOException{ 30 | String clsName = ClassNameUtil.getClassName(root, file); 31 | return new StringJavaSource(clsName, FileUtils.readFileToString(file, "utf-8")); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/java/StringJavaSourceBase.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.java; 2 | 3 | import javax.tools.JavaFileObject; 4 | import java.net.URI; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public abstract class StringJavaSourceBase extends MemoryJavaSource{ 11 | 12 | public StringJavaSourceBase(String className) { 13 | super(URI.create(className.replace('.', '/') + ".java"), JavaFileObject.Kind.SOURCE, className); 14 | } 15 | 16 | @Override 17 | public CharSequence getCharContent(boolean ignoreEncodingErrors) { 18 | return getContent(); 19 | } 20 | 21 | protected abstract CharSequence getContent(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/profile/Invocation.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.profile; 2 | 3 | public class Invocation { 4 | 5 | private final String name; 6 | 7 | private long totalTime; 8 | 9 | private long startTime; 10 | 11 | private int count; 12 | 13 | private final Span span; 14 | 15 | public Invocation(String name,Span span) { 16 | this.name = name; 17 | this.span = span; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void start() { 25 | startTime = System.currentTimeMillis(); 26 | } 27 | 28 | public void end() { 29 | if (startTime<=0) { 30 | throw new IllegalStateException("invocation is not started"); 31 | } 32 | count ++; 33 | totalTime += (System.currentTimeMillis()-startTime); 34 | startTime = 0; 35 | } 36 | 37 | public Span getSpan() { 38 | return span; 39 | } 40 | 41 | public long getTotalTime() { 42 | return totalTime; 43 | } 44 | 45 | public int getCount() { 46 | return count; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/profile/Span.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.profile; 2 | 3 | import javax.annotation.Nullable; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | 7 | public class Span { 8 | 9 | private String name; 10 | 11 | private long startTime; 12 | 13 | private long stopTime; 14 | 15 | private List childSpans = new LinkedList<>(); 16 | 17 | private Span parentSpan; 18 | 19 | public Span(String name,@Nullable Span parentSpan) { 20 | this.name = name; 21 | this.parentSpan = parentSpan; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public void addChildSpan(Span span) { 29 | childSpans.add(span); 30 | } 31 | 32 | public Span[] getChildSpans() { 33 | return childSpans.toArray(new Span[0]); 34 | } 35 | 36 | @Nullable 37 | public Span getParentSpan() { 38 | return parentSpan; 39 | } 40 | 41 | public void start() { 42 | this.startTime = System.nanoTime(); 43 | } 44 | 45 | public void stop() { 46 | this.stopTime = System.nanoTime(); 47 | } 48 | 49 | public long getElapsedNanoTime() { 50 | return stopTime - startTime; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/shell/Constant.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.shell; 2 | 3 | /** 4 | * 5 | * @author Kason Yang 6 | */ 7 | public class Constant { 8 | 9 | public static final int SUCCESS = 0; 10 | 11 | public static final int ERR_INVALID_ARGUMENTS = 1, 12 | ERR_COMPILE_ERROR = 2, 13 | ERR_IO_EXCEPTION = 3, 14 | ERR_UNKNOWN_EXCEPTION = 4; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/CachedClassNodeLoader.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | import kalang.compiler.ast.ClassNode; 4 | import kalang.compiler.compile.ClassNodeLoader; 5 | import kalang.lang.Ref; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author KasonYang 12 | */ 13 | public class CachedClassNodeLoader implements ClassNodeLoader { 14 | 15 | protected final ClassNodeLoader origin; 16 | 17 | protected final Map> cache = new HashMap<>(); 18 | 19 | public CachedClassNodeLoader(ClassNodeLoader origin) { 20 | this.origin = origin; 21 | } 22 | 23 | @Override 24 | public ClassNode getClassNode(String className) { 25 | Ref ref = cache.computeIfAbsent(className, (k) -> new Ref<>(origin.getClassNode(className))); 26 | return ref.get(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/CachedSourceLoader.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | import kalang.compiler.compile.KalangSource; 4 | import kalang.compiler.compile.SourceLoader; 5 | import kalang.lang.Ref; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author KasonYang 14 | */ 15 | public class CachedSourceLoader implements SourceLoader { 16 | 17 | protected final Map> cache = new HashMap<>(); 18 | 19 | protected final SourceLoader origin; 20 | 21 | public CachedSourceLoader(SourceLoader origin) { 22 | this.origin = origin; 23 | } 24 | 25 | 26 | @Nullable 27 | @Override 28 | public KalangSource loadSource(@Nonnull String className) { 29 | Ref ref = cache.computeIfAbsent(className, k -> new Ref<>(origin.loadSource(className))); 30 | return ref.get(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/ClassWriter.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | import kalang.compiler.compile.ClassNodeLoader; 4 | import kalang.compiler.compile.CodeGenerator; 5 | import kalang.compiler.compile.CompilationUnit; 6 | import kalang.compiler.compile.codegen.Ast2Class; 7 | 8 | /** 9 | * 10 | * @author Kason Yang 11 | */ 12 | public class ClassWriter implements CodeGenerator{ 13 | 14 | private OutputManager outputManager; 15 | 16 | private ClassNodeLoader classNodeLoader; 17 | 18 | private CompilationUnit compilationUnit; 19 | 20 | public ClassWriter(CompilationUnit compilationUnit) { 21 | this.compilationUnit = compilationUnit; 22 | } 23 | 24 | public ClassWriter(OutputManager outputManager, ClassNodeLoader classNodeLoader, CompilationUnit compilationUnit) { 25 | this.outputManager = outputManager; 26 | this.classNodeLoader = classNodeLoader; 27 | this.compilationUnit = compilationUnit; 28 | } 29 | 30 | @Override 31 | public void generateCode() { 32 | if (outputManager != null) { 33 | Ast2Class ast2class = new Ast2Class(outputManager, classNodeLoader, compilationUnit); 34 | ast2class.generateCode(); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/CompileException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | /** 4 | * @author Kason Yang 5 | */ 6 | 7 | public class CompileException extends RuntimeException { 8 | 9 | 10 | private String description; 11 | 12 | private String fileName; 13 | 14 | private int line; 15 | 16 | 17 | public CompileException(String description, String fileName, int line) { 18 | super(formatMsg(description, fileName, line)); 19 | this.description = description; 20 | this.fileName = fileName; 21 | this.line = line; 22 | } 23 | 24 | public String getDescription() { 25 | return description; 26 | } 27 | 28 | public String getFileName() { 29 | return fileName; 30 | } 31 | 32 | public int getLine() { 33 | return line; 34 | } 35 | 36 | private static String formatMsg(String description, String fileName, int line) { 37 | return String.format("%s:%s: Error:%s", fileName, line, description); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/FileSystemOutputManager.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | import kalang.compiler.util.ClassNameUtil; 4 | import org.apache.commons.io.FileUtils; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.io.OutputStream; 9 | 10 | /** 11 | * 12 | * @author Kason Yang 13 | */ 14 | public class FileSystemOutputManager implements OutputManager{ 15 | 16 | File outputDir; 17 | 18 | String extention; 19 | 20 | public FileSystemOutputManager(File outputDir, String extention) { 21 | this.outputDir = outputDir; 22 | this.extention = extention; 23 | } 24 | 25 | @Override 26 | public OutputStream createOutputStream(String className) throws IOException{ 27 | String relativePath = ClassNameUtil.getRelativePathOfClass(className, extention); 28 | File outputFile = new File(outputDir,relativePath); 29 | return FileUtils.openOutputStream(outputFile, false); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/MemoryOutputManager.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | import javax.annotation.Nullable; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.OutputStream; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * 11 | * @author Kason Yang 12 | */ 13 | public class MemoryOutputManager implements OutputManager{ 14 | 15 | final Map oss = new HashMap(); 16 | 17 | @Override 18 | public OutputStream createOutputStream(String className) { 19 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 20 | oss.put(className, os); 21 | return os; 22 | } 23 | 24 | public String[] getClassNames(){ 25 | return oss.keySet().toArray(new String[0]); 26 | } 27 | 28 | @Nullable 29 | public byte [] getBytes(String className) { 30 | ByteArrayOutputStream os = oss.get(className); 31 | if(os==null) return null; 32 | return os.toByteArray(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/NonScriptFileException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public class NonScriptFileException extends RuntimeException { 7 | 8 | public NonScriptFileException() { 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/tool/OutputManager.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.tool; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public interface OutputManager { 11 | 12 | OutputStream createOutputStream(String className) throws IOException; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/AccessUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.compiler.ast.ClassNode; 4 | 5 | import javax.annotation.Nullable; 6 | import java.lang.reflect.Modifier; 7 | import java.util.Objects; 8 | 9 | /** 10 | * 11 | * @author Kason Yang 12 | */ 13 | public class AccessUtil { 14 | 15 | public static boolean isAccessible(int targetModifier, ClassNode targetOwner, @Nullable ClassNode caller) { 16 | Objects.requireNonNull(targetOwner); 17 | if (Modifier.isPublic(targetModifier)) { 18 | return true; 19 | } 20 | if (caller == null) { 21 | return false; 22 | } 23 | if (targetOwner.equals(caller)) { 24 | return true; 25 | } 26 | if (!Modifier.isPrivate(targetModifier)) { 27 | return InheritanceUtil.isInSamePackage(caller, targetOwner) || InheritanceUtil.isSubclassOf(caller, targetOwner); 28 | } 29 | return false; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/AstOutputUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.compiler.ast.AstNode; 4 | 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class AstOutputUtil { 10 | 11 | static final String INDENT = " "; 12 | 13 | static final String LINE_DELIMITER = "\r\n"; 14 | 15 | public static String toString(AstNode node){ 16 | if(node==null) return "[null]"; 17 | String nodeStr = node.toString(); 18 | StringBuilder sb = new StringBuilder(); 19 | sb.append(nodeStr).append(":"); 20 | for(AstNode c:node.getChildren()){ 21 | sb.append(LINE_DELIMITER); 22 | String cStr = toString(c); 23 | sb.append(StringUtil.indentLines(cStr, INDENT,LINE_DELIMITER)); 24 | } 25 | return sb.toString(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/ClassExecutor.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class ClassExecutor { 11 | public static void executeMain(Class clazz,String[] args) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ 12 | Method method = clazz.getMethod("main", String[].class); 13 | method.invoke(null, new Object[]{args}); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/ClassNameUtil.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.util; 3 | 4 | import org.apache.commons.io.FilenameUtils; 5 | 6 | import javax.annotation.Nullable; 7 | import java.io.File; 8 | /** 9 | * 10 | * @author Kason Yang 11 | */ 12 | public class ClassNameUtil { 13 | 14 | public static String getRelativePathOfClass(String className,@Nullable String extention){ 15 | String name = className.replace(".", "/"); 16 | if(extention!=null){ 17 | name += "." + extention; 18 | } 19 | return name; 20 | } 21 | 22 | public static String getClassName(File dir,File file){ 23 | String dirPath = FilenameUtils.normalizeNoEndSeparator(dir.getAbsolutePath()); 24 | String fname =FilenameUtils.normalizeNoEndSeparator(file.getAbsolutePath()); 25 | String ext = FilenameUtils.getExtension(fname); 26 | return fname.substring(dirPath.length() + 1, fname.length() - ext.length()-1).replace(File.separator, "."); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/ClassPathUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import org.apache.commons.io.FileUtils; 4 | 5 | import java.io.File; 6 | import java.net.MalformedURLException; 7 | import java.net.URL; 8 | import java.util.Collection; 9 | import java.util.Set; 10 | 11 | /** 12 | * @author KasonYang 13 | */ 14 | public class ClassPathUtil { 15 | 16 | public static void addClasspathFromLibPath(Set list, File libpath) { 17 | if (!libpath.exists() || !libpath.isDirectory()) { 18 | return; 19 | } 20 | Collection jars = FileUtils.listFiles(libpath, new String[]{"jar"}, false); 21 | for (File j : jars) { 22 | try { 23 | list.add(j.toURI().toURL()); 24 | } catch (MalformedURLException ex) { 25 | throw new RuntimeException(ex); 26 | } 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/CollectionsUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class CollectionsUtil { 11 | 12 | public static Set getIntersection(Set... collections){ 13 | if(collections.length<2) return new HashSet<>(); 14 | Set sets = new HashSet<>(collections[0]); 15 | for(int i=1;i c = new HashSet(sets); 17 | Set c2 = collections[i]; 18 | sets.clear(); 19 | for(T it:c){ 20 | if(c2.contains(it)){ 21 | sets.add(it); 22 | } 23 | } 24 | } 25 | return sets; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/DiagnosisUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.compiler.compile.Diagnosis; 4 | import kalang.compiler.compile.KalangSource; 5 | import kalang.compiler.compile.OffsetRange; 6 | 7 | /** 8 | * @author KasonYang 9 | */ 10 | public class DiagnosisUtil { 11 | 12 | public static String toPrintString(Diagnosis diagnosis) { 13 | KalangSource source = diagnosis.getSource(); 14 | Diagnosis.Kind kind = diagnosis.getKind(); 15 | OffsetRange offset = diagnosis.getOffset(); 16 | String description = diagnosis.getDescription(); 17 | String fileName = source == null ? "UNKNOWN SOURCE" : source.getFileName(); 18 | return String.format("%s:%s :%s :%s",fileName, offset.startLine, kind, description); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/FilePathUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import lombok.SneakyThrows; 4 | import org.apache.commons.io.FilenameUtils; 5 | import org.apache.commons.io.IOCase; 6 | 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.net.URL; 10 | 11 | /** 12 | * 13 | * @author Kason Yang 14 | */ 15 | public class FilePathUtil { 16 | 17 | public static boolean existFile(File srcFile) { 18 | String absPath = srcFile.getAbsolutePath(); 19 | if (srcFile.exists()) { 20 | String canonicalPath; 21 | try { 22 | canonicalPath = srcFile.getCanonicalPath(); 23 | } catch (IOException ex) { 24 | return false; 25 | } 26 | return FilenameUtils.equals(canonicalPath, absPath, true, IOCase.SENSITIVE); 27 | } 28 | return false; 29 | } 30 | 31 | @SneakyThrows 32 | public static URL toURL(File file) { 33 | return file.toURI().toURL(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/InvalidModifierException.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public class InvalidModifierException extends Exception { 7 | 8 | public InvalidModifierException(String msg) { 9 | super(msg); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/KalangSourceUtil.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.util; 3 | 4 | import kalang.annotation.Nullable; 5 | import kalang.compiler.compile.FileKalangSource; 6 | import kalang.compiler.compile.KalangSource; 7 | 8 | import java.io.File; 9 | /** 10 | * 11 | * @author Kason Yang 12 | */ 13 | public class KalangSourceUtil { 14 | 15 | public static KalangSource create(File dir,File sourceFile) { 16 | String clsName = ClassNameUtil.getClassName(dir, sourceFile); 17 | boolean script = isScriptFile(sourceFile.getName()); 18 | return new FileKalangSource(clsName,sourceFile, script); 19 | } 20 | 21 | public static boolean isScriptFile(@Nullable String fileName) { 22 | if (fileName == null) { 23 | return false; 24 | } 25 | for (String ext : KalangSource.EXTENSION_SCRIPT) { 26 | if (fileName.endsWith("." + ext)) { 27 | return true; 28 | } 29 | } 30 | return false; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/LambdaUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.annotation.Nullable; 4 | import kalang.compiler.core.ClassType; 5 | import kalang.compiler.core.MethodDescriptor; 6 | 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | 10 | /** 11 | * 12 | * @author Kason Yang 13 | */ 14 | public class LambdaUtil { 15 | 16 | @Nullable 17 | public static MethodDescriptor getFunctionalMethod(ClassType classType) { 18 | if (!ModifierUtil.isInterface(classType.getModifier())) { 19 | return null; 20 | } 21 | List mustImplMethods = new LinkedList<>(); 22 | MethodDescriptor[] methods = classType.getMethodDescriptors(null, true, true); 23 | for(MethodDescriptor m:methods) { 24 | if (!ModifierUtil.isDefault(m.getModifier())) { 25 | mustImplMethods.add(m); 26 | } 27 | } 28 | if (mustImplMethods.size()!=1) { 29 | return null; 30 | } 31 | return mustImplMethods.get(0); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/LexerFactory.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.util; 3 | import kalang.compiler.antlr.KalangLexer; 4 | import org.antlr.v4.runtime.ANTLRInputStream; 5 | import org.antlr.v4.runtime.CharStream; 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class LexerFactory { 11 | 12 | public static KalangLexer createLexer(CharStream input){ 13 | return new KalangLexer(input); 14 | } 15 | 16 | public static KalangLexer createLexer(String source){ 17 | return createLexer(new ANTLRInputStream(source)); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/MathType.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.annotation.Nullable; 4 | import kalang.compiler.core.PrimitiveType; 5 | import kalang.compiler.core.Types; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class MathType { 11 | 12 | private static List supportedTypes = Arrays.asList( 13 | Types.DOUBLE_TYPE, 14 | Types.FLOAT_TYPE, 15 | Types.LONG_TYPE, 16 | Types.INT_TYPE, 17 | Types.SHORT_TYPE, 18 | Types.BYTE_TYPE, 19 | Types.CHAR_TYPE 20 | ); 21 | 22 | public static boolean isSupportedType(@Nullable PrimitiveType type) { 23 | return supportedTypes.contains(type); 24 | } 25 | 26 | public static PrimitiveType getType(PrimitiveType type1, PrimitiveType type2) { 27 | if (Types.DOUBLE_TYPE.equals(type1) || Types.DOUBLE_TYPE.equals(type2)) { 28 | return Types.DOUBLE_TYPE; 29 | } else if (Types.FLOAT_TYPE.equals(type1) || Types.FLOAT_TYPE.equals(type2)) { 30 | return Types.FLOAT_TYPE; 31 | } else if (Types.LONG_TYPE.equals(type1) || Types.LONG_TYPE.equals(type2)) { 32 | return Types.LONG_TYPE; 33 | } else { 34 | return Types.INT_TYPE; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/NameUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | /** 6 | * 7 | * @author Kason Yang 8 | */ 9 | public class NameUtil { 10 | 11 | public static String firstCharToUpperCase(String name){ 12 | if(name.isEmpty()){ 13 | return ""; 14 | }else if(name.length()==1){ 15 | return name.toUpperCase(); 16 | }else{ 17 | return name.substring(0,1).toUpperCase() + name.substring(1); 18 | } 19 | } 20 | 21 | public static String getClassNameWithoutPackage(String name) { 22 | int dotIdx = name.lastIndexOf('.'); 23 | if (dotIdx > 0) { 24 | return name.substring(dotIdx + 1); 25 | } else { 26 | return name; 27 | } 28 | } 29 | 30 | public static String getSimpleClassName(String className){ 31 | String name = getClassNameWithoutPackage(className); 32 | String[] parts = name.split("\\$"); 33 | return parts[parts.length-1]; 34 | } 35 | 36 | @Nullable 37 | public static String getPackageName(String name) { 38 | int dotIdx = name.lastIndexOf('.'); 39 | if (dotIdx > 0) { 40 | return name.substring(0, dotIdx); 41 | } else { 42 | return null; 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/OpUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.compiler.compile.codegen.op.*; 4 | import kalang.compiler.compile.codegen.util.OpcodeUtil; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author KasonYang 10 | */ 11 | public class OpUtil { 12 | 13 | public static String toString(OpCollector opCollector) { 14 | StringBuilder sb = new StringBuilder(); 15 | for (OpBase op: opCollector.getOpcodes()) { 16 | sb.append(op).append("\n"); 17 | } 18 | List attributes = opCollector.getAttributes(); 19 | sb.append("\nException tables:\n"); 20 | List tryCatchBlocks = OpcodeUtil.getAttributes(attributes, CatchAttr.class); 21 | for (CatchAttr tcb : tryCatchBlocks) { 22 | sb.append(tcb.type).append(" ") 23 | .append(tcb.start).append(" ") 24 | .append(tcb.end).append(" ") 25 | .append(tcb.handler).append(" \n"); 26 | } 27 | sb.append("\nVariables:\n"); 28 | List vars = OpcodeUtil.getAttributes(attributes, LocalVariableAttr.class); 29 | for (LocalVariableAttr lv : vars) { 30 | sb.append(lv.name).append(" ").append(lv.start).append(" ").append(lv.end).append(" \n"); 31 | } 32 | return sb.toString(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/OverrideUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.compiler.core.Type; 4 | 5 | import java.lang.reflect.Modifier; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class OverrideUtil { 12 | 13 | private static boolean throwable(Type type,Type[] exceptionTypes){ 14 | for(Type t:exceptionTypes){ 15 | if(t.isAssignableFrom(type)) return true; 16 | } 17 | return false; 18 | } 19 | 20 | public static boolean exceptionTypeCompatible(Type[] newExceptionTypes,Type[] oldExceptionTypes){ 21 | for(Type nt:newExceptionTypes){ 22 | if(!throwable(nt, oldExceptionTypes)) return false; 23 | } 24 | return true; 25 | } 26 | 27 | public static boolean overridingCompatible(int newModifier, int oldModifier) { 28 | return Modifier.isStatic(oldModifier) == Modifier.isStatic(newModifier) && Modifier.isPrivate(oldModifier) == Modifier.isPrivate(newModifier) && Modifier.isProtected(oldModifier) == Modifier.isProtected(newModifier) && Modifier.isPublic(oldModifier) == Modifier.isPublic(newModifier); 29 | } 30 | 31 | public static boolean returnTypeCompatible(Type newType,Type oldType){ 32 | return oldType.isAssignableFrom(newType); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/Parameters.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | /** 3 | * 4 | * @author Kason Yang 5 | */ 6 | public final class Parameters { 7 | 8 | public static void requireNonNull(Object obj){ 9 | requireNonNull(obj, "require non null"); 10 | } 11 | 12 | public static void requireNonNull(Object obj,String msg) { 13 | if(obj==null) throw new IllegalArgumentException(msg); 14 | } 15 | 16 | public static void requireTrue(boolean v) { 17 | if(!v) throw new IllegalArgumentException(); 18 | } 19 | 20 | public static void requireFalse(boolean v){ 21 | if(v) throw new IllegalArgumentException(); 22 | } 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.StringReader; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class StringUtil { 12 | 13 | public static String indentLines(String str,String indent,String newLineDelimiter){ 14 | StringReader sr = new StringReader(str); 15 | BufferedReader br = new BufferedReader(sr); 16 | StringBuilder sb = new StringBuilder(); 17 | String ln; 18 | try { 19 | while((ln=br.readLine())!=null){ 20 | if(sb.length()>0){ 21 | sb.append(newLineDelimiter); 22 | } 23 | sb.append(indent).append(ln); 24 | } 25 | return sb.toString(); 26 | } catch (IOException ex) { 27 | throw new RuntimeException(ex); 28 | } 29 | } 30 | 31 | public static boolean isEmpty(String value) { 32 | return value == null || value.isEmpty(); 33 | } 34 | 35 | public static boolean isNotEmpty(String value) { 36 | return !isEmpty(value); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/TokenStreamFactory.java: -------------------------------------------------------------------------------- 1 | 2 | package kalang.compiler.util; 3 | import org.antlr.v4.runtime.CommonTokenStream; 4 | import org.antlr.v4.runtime.TokenSource; 5 | 6 | /** 7 | * 8 | * @author Kason Yang 9 | */ 10 | public class TokenStreamFactory { 11 | 12 | public static CommonTokenStream createTokenStream(String source) { 13 | return createTokenStream(LexerFactory.createLexer(source)); 14 | } 15 | 16 | public static CommonTokenStream createTokenStream(TokenSource lexer) { 17 | return new CommonTokenStream(lexer); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/kalang/compiler/util/TypeValidator.java: -------------------------------------------------------------------------------- 1 | package kalang.compiler.util; 2 | 3 | import kalang.compiler.ast.ExprNode; 4 | import kalang.compiler.compile.OffsetRange; 5 | import kalang.compiler.compile.semantic.NodeException; 6 | import kalang.compiler.core.Type; 7 | import kalang.compiler.core.Types; 8 | 9 | /** 10 | * @author KasonYang 11 | */ 12 | public class TypeValidator { 13 | 14 | public static void requireNonVoidType(ExprNode expr) { 15 | Type type = expr.getType(); 16 | if (Types.VOID_TYPE.equals(type)) { 17 | throw new NodeException("non-void type expected", expr.offset); 18 | } 19 | } 20 | 21 | public static T requireType(Type type, Class typeClass,String errMsg, OffsetRange offset) { 22 | if (typeClass.isAssignableFrom(type.getClass())) { 23 | return (T) type; 24 | } else { 25 | throw new NodeException(errMsg, offset); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/AsmTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler; 2 | 3 | import org.objectweb.asm.ClassWriter; 4 | import org.objectweb.asm.MethodVisitor; 5 | 6 | import java.lang.reflect.Method; 7 | 8 | import static org.objectweb.asm.Opcodes.*; 9 | 10 | /** 11 | * @author KasonYang 12 | */ 13 | public class AsmTest extends ClassLoader { 14 | 15 | public void main() throws Exception { 16 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 17 | cw.visit(V1_6, ACC_PUBLIC, "demo/HelloWorld", null, "java/lang/Object", null); 18 | MethodVisitor md = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "test", "()I", null, null); 19 | md.visitInsn(LCONST_1); 20 | md.visitInsn(LCONST_1); 21 | md.visitInsn(LADD); 22 | md.visitVarInsn(ISTORE, 0); 23 | md.visitVarInsn(ISTORE, 1); 24 | md.visitVarInsn(ILOAD, 1); 25 | md.visitInsn(IRETURN); 26 | md.visitMaxs(0,0); 27 | md.visitEnd(); 28 | byte[] clazz = cw.toByteArray(); 29 | Class clz = defineClass("demo.HelloWorld", clazz, 0, clazz.length); 30 | Object inst = clz.newInstance(); 31 | Method method = inst.getClass().getMethod("test"); 32 | Object result = method.invoke(inst); 33 | System.out.println("result:" + result); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/ClassLoaderTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler; 2 | 3 | import kalang.compiler.tool.KalangClassLoader; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import static org.junit.Assert.assertNotNull; 10 | 11 | /** 12 | * 13 | * @author Kason Yang 14 | */ 15 | public class ClassLoaderTest { 16 | 17 | public ClassLoaderTest() { 18 | } 19 | 20 | @Test 21 | public void testFiles() throws IOException{ 22 | KalangClassLoader clsLoader = new KalangClassLoader(new File[0],null,null); 23 | Class clazz = clsLoader.parseFile("HelloKalang", new File("src/test/kalang-snippets/automation/HelloKalang.kl")); 24 | assertNotNull(clazz); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/CompilerTestCase.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler; 2 | 3 | import junit.framework.Assert; 4 | import kalang.compiler.compile.DiagnosisHandler; 5 | import kalang.compiler.compile.util.StandardDiagnosisHandler; 6 | import kalang.compiler.tool.FileSystemCompiler; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.Objects; 11 | 12 | /** 13 | * 14 | * @author Kason Yang 15 | */ 16 | public class CompilerTestCase extends FileSystemCompiler { 17 | 18 | public CompilerTestCase() { 19 | super(); 20 | } 21 | 22 | @Override 23 | public void compile() throws IOException { 24 | final DiagnosisHandler oldDiagnosisHandler = new StandardDiagnosisHandler(); 25 | this.setDiagnosisHandler(diagnosis -> { 26 | oldDiagnosisHandler.handleDiagnosis(diagnosis); 27 | if (diagnosis.getKind().isError()) { 28 | Assert.fail(Objects.toString(diagnosis)); 29 | } 30 | }); 31 | this.setOutputDir(new File("build/kalang-test")); 32 | super.compile(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/FilePathUtilTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler; 2 | 3 | import kalang.compiler.util.FilePathUtil; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | 8 | import static org.junit.Assert.assertFalse; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | /** 12 | * 13 | * @author Kason Yang 14 | */ 15 | public class FilePathUtilTest { 16 | 17 | public FilePathUtilTest() { 18 | } 19 | @Test 20 | public void test(){ 21 | File f = new File("SRC"); 22 | File f2 = new File("src"); 23 | assertFalse(FilePathUtil.existFile(f)); 24 | assertTrue(FilePathUtil.existFile(f2)); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/ParameterizedTypeTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler; 2 | 3 | import kalang.compiler.compile.ClassNodeNotFoundException; 4 | import kalang.compiler.core.ClassType; 5 | import kalang.compiler.core.ObjectType; 6 | import kalang.compiler.core.Type; 7 | import kalang.compiler.core.Types; 8 | import org.junit.Test; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | import static org.junit.Assert.assertTrue; 12 | 13 | /** 14 | * 15 | * @author Kason Yang 16 | */ 17 | public class ParameterizedTypeTest { 18 | 19 | @Test 20 | public void test() throws ClassNodeNotFoundException { 21 | //TODO optimize 22 | ClassType pt = Types.getClassType(Types.getClassType("java.util.LinkedList").getClassNode(),new Type[]{Types.getIntClassType()}); 23 | ObjectType supType = pt.getSuperType(); 24 | assertTrue(supType instanceof ClassType); 25 | assertEquals("java.util.AbstractSequentialList", supType.toString()); 26 | //MethodDescriptor[] mds = supType.getMethodDescriptors(null, true,true); 27 | //System.out.print(Arrays.toString(mds)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/TokenUtilTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler; 2 | 3 | import kalang.compiler.util.TokenStreamFactory; 4 | import org.antlr.v4.runtime.CommonTokenStream; 5 | import org.antlr.v4.runtime.IntStream; 6 | import org.antlr.v4.runtime.Token; 7 | import org.junit.Test; 8 | 9 | import java.util.List; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | /** 14 | * 15 | * @author Kason Yang 16 | */ 17 | public class TokenUtilTest { 18 | 19 | public TokenUtilTest() { 20 | } 21 | 22 | @Test 23 | public void test(){ 24 | CommonTokenStream ts = TokenStreamFactory.createTokenStream("class{ }"); 25 | int tokenSize = ts.size(); 26 | assertEquals(0, tokenSize); 27 | List tokens = ts.getTokens(); 28 | assertEquals(0, tokens.size()); 29 | ts.consume(); 30 | ts.consume(); 31 | assertEquals("}", ts.LT(1).getText()); 32 | assertEquals("{", ts.LT(-1).getText()); 33 | assertEquals("class", ts.LT(-2).getText()); 34 | //why is it 4? 35 | assertEquals(4, ts.size()); 36 | int consumeSize = 2; 37 | while(ts.LA(1)!=IntStream.EOF){ 38 | ts.consume(); 39 | consumeSize++; 40 | } 41 | tokens = ts.getTokens(); 42 | assertEquals(5, tokens.size()); 43 | assertEquals(3, consumeSize); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/core/ClassTypeTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.core; 2 | 3 | import kalang.compiler.core.*; 4 | import org.junit.Test; 5 | 6 | import java.util.List; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | /** 11 | * @author KasonYang 12 | */ 13 | public class ClassTypeTest { 14 | 15 | @Test 16 | public void testListMethod() { 17 | ClassType listCls = Types.getClassType(List.class.getName()); 18 | ClassType intListCls = Types.getClassType(listCls.getClassNode(), new Type[]{ Types.getIntClassType() }); 19 | MethodDescriptor[] mds = intListCls.getMethodDescriptors(null, "sort", false, false); 20 | assertEquals(1, mds.length); 21 | Type[] paramTypes = mds[0].getParameterTypes(); 22 | assertEquals(1, paramTypes.length); 23 | ClassType ct = (ClassType) paramTypes[0]; 24 | assertEquals(NullableKind.UNKNOWN, ct.getNullable()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/core/ObjectTypeTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.core; 2 | 3 | import kalang.compiler.compile.ClassNodeNotFoundException; 4 | import kalang.compiler.ast.ClassNode; 5 | import kalang.compiler.core.ClassType; 6 | import kalang.compiler.core.ObjectType; 7 | import kalang.compiler.core.Types; 8 | import org.junit.Test; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * 14 | * @author Kason Yang 15 | */ 16 | public class ObjectTypeTest { 17 | 18 | private int privateField; 19 | 20 | protected int protectedField; 21 | 22 | public int publicField; 23 | 24 | public ObjectTypeTest() { 25 | } 26 | 27 | @Test 28 | public void test() throws ClassNodeNotFoundException { 29 | ClassType type = Types.getClassType(ObjectTypeTest.class.getName()); 30 | ClassNode classNode = type.getClassNode(); 31 | ObjectType rootType = Types.getRootType(); 32 | ClassNode rootClassNode = rootType.getClassNode(); 33 | assertNull(type.getFieldDescriptor(rootClassNode, "privateField")); 34 | assertNull(type.getFieldDescriptor(rootClassNode, "protectedField")); 35 | assertNotEquals(null, type.getFieldDescriptor(rootClassNode, "publicField")); 36 | assertNotEquals(null,type.getFieldDescriptor(classNode, "privateField")); 37 | assertNotEquals(null,type.getFieldDescriptor(classNode, "protectedField")); 38 | assertNotEquals(null, type.getFieldDescriptor(classNode, "publicField")); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/core/TypeCompareTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.core; 2 | 3 | import kalang.compiler.compile.ClassNodeNotFoundException; 4 | import kalang.compiler.ast.ClassNode; 5 | import kalang.compiler.compile.jvm.JvmClassNodeLoader; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | 9 | public class TypeCompareTest { 10 | 11 | @Test 12 | public void testEquals() throws ClassNodeNotFoundException { 13 | JvmClassNodeLoader loader1 = new JvmClassNodeLoader(null,TypeCompareTest.class.getClassLoader()); 14 | JvmClassNodeLoader loader2 = new JvmClassNodeLoader(null, TypeCompareTest.class.getClassLoader().getParent()); 15 | ClassNode t1 = loader1.loadClassNode(String.class.getName()); 16 | ClassNode t2 = loader2.loadClassNode(String.class.getName()); 17 | Assert.assertEquals(t1,t2); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/helper/DigestPluginTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.helper; 2 | 3 | import kalang.mixin.DigestMixin; 4 | import kalang.mixin.HexMixin; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import java.security.NoSuchAlgorithmException; 9 | 10 | public class DigestPluginTest { 11 | 12 | @Test 13 | public void testDigest() throws NoSuchAlgorithmException { 14 | Assert.assertEquals("098f6bcd4621d373cade4e832627b4f6", HexMixin.toHexString(DigestMixin.md5("test"))); 15 | Assert.assertEquals("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", HexMixin.toHexString(DigestMixin.sha1("test"))); 16 | Assert.assertEquals("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", HexMixin.toHexString(DigestMixin.sha256("test"))); 17 | Assert.assertEquals("ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff", HexMixin.toHexString(DigestMixin.sha512("test"))); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/tool/KalangShellTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.tool; 2 | 3 | import kalang.compiler.tool.KalangShell; 4 | import kalang.compiler.util.ClassExecutor; 5 | import org.junit.Test; 6 | 7 | /** 8 | * 9 | * @author Kason Yang 10 | */ 11 | public class KalangShellTest { 12 | 13 | public KalangShellTest() { 14 | } 15 | 16 | @Test 17 | public void test() throws Throwable{ 18 | KalangShell shell = new KalangShell(); 19 | Class script = shell.parse("Test", "println(\"test\");", "Test.kls"); 20 | ClassExecutor.executeMain(script, new String[0]); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/tool/KalangcTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.tool; 2 | 3 | import kalang.compiler.shell.Kalangc; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.io.FileNotFoundException; 9 | 10 | /** 11 | * 12 | * @author Kason Yang 13 | */ 14 | public class KalangcTest { 15 | 16 | public KalangcTest() { 17 | } 18 | 19 | @Test 20 | public void test() { 21 | String[] args = new String[]{ 22 | "-h" 23 | }; 24 | Assert.assertEquals(0, new Kalangc().run(args)); 25 | } 26 | 27 | //@Test 28 | public void testCompile() throws FileNotFoundException { 29 | File projectDir = new File("src/test/kalang-snippets/projects/colorful-console"); 30 | if (!projectDir.exists()) { 31 | throw new FileNotFoundException(projectDir.getAbsolutePath()); 32 | } 33 | String outDir = new File("build/kalang-test/projects").getAbsolutePath(); 34 | String libpath = new File(projectDir,"jansi-1.14.jar").getAbsolutePath(); 35 | String[] args = new String[] { 36 | "--output-dir",outDir,"--classpath",libpath,projectDir.getAbsolutePath() 37 | }; 38 | int result = new Kalangc().run(args); 39 | Assert.assertEquals(0,result); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/util/AntlrTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.util; 2 | 3 | import kalang.compiler.antlr.KalangParser; 4 | import kalang.compiler.util.TokenStreamFactory; 5 | import kalang.mixin.IOMixin; 6 | import org.antlr.v4.runtime.CommonTokenStream; 7 | import org.junit.Test; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | 12 | /** 13 | * 14 | * @author Kason Yang 15 | */ 16 | public class AntlrTest { 17 | 18 | public AntlrTest() { 19 | } 20 | 21 | @Test 22 | public void testLexer() throws IOException{ 23 | this.createTokenStream().getTokens(); 24 | } 25 | 26 | @Test 27 | public void testParser() throws IOException{ 28 | KalangParser parser = new KalangParser(this.createTokenStream()); 29 | parser.standardCompilationUnit(); 30 | } 31 | 32 | private CommonTokenStream createTokenStream() throws IOException{ 33 | File file = new File("src/test/kalang-snippets/automation/HelloKalang.kl"); 34 | String src = IOMixin.readToString(file, "utf8"); 35 | return TokenStreamFactory.createTokenStream(src); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/util/LambdaUtilTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.util; 2 | 3 | import kalang.compiler.core.ClassType; 4 | import kalang.compiler.core.MethodDescriptor; 5 | import kalang.compiler.core.Types; 6 | import kalang.compiler.util.LambdaUtil; 7 | import org.junit.Test; 8 | 9 | import java.util.Comparator; 10 | 11 | /** 12 | * @author KasonYang 13 | */ 14 | public class LambdaUtilTest { 15 | 16 | @Test 17 | public void testFunctionMethod() { 18 | ClassType comparatorClass = Types.getClassType(Comparator.class.getName()); 19 | MethodDescriptor funcMethod = LambdaUtil.getFunctionalMethod(comparatorClass); 20 | assert funcMethod != null; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/test/kalang/compiler/util/TypeUtilTest.java: -------------------------------------------------------------------------------- 1 | package test.kalang.compiler.util; 2 | 3 | import kalang.compiler.core.ClassType; 4 | import kalang.compiler.core.Type; 5 | import kalang.compiler.core.Types; 6 | import kalang.compiler.util.TypeUtil; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | import java.util.AbstractMap; 11 | import java.util.HashMap; 12 | import java.util.TreeMap; 13 | 14 | /** 15 | * @author KasonYang 16 | */ 17 | public class TypeUtilTest { 18 | 19 | @Test 20 | public void testCommonType() { 21 | ClassType hashMapType = Types.getClassType(HashMap.class.getName()); 22 | ClassType treeMapType = Types.getClassType(TreeMap.class.getName()); 23 | Type commonType = TypeUtil.getCommonType(hashMapType, treeMapType); 24 | Assert.assertEquals(AbstractMap.class.getName(), commonType.getName()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/ArrayElementAssign.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | private int index = 0; 4 | 5 | private int[] getBuff(int[] buff) { 6 | index ++ ; 7 | return buff; 8 | } 9 | 10 | boolean run() { 11 | int[] buff = new int[4]; 12 | getBuff(buff)[index++] = index ++; 13 | //println(buff); 14 | return Arrays.equals([0, 2, 0, 0], buff); 15 | } 16 | 17 | boolean byteConstAssign() { 18 | val bytes = new byte[1]; 19 | bytes[0] = - 0x80; 20 | return bytes[0] == -128; 21 | } 22 | 23 | boolean shortConstAssign() { 24 | val arr = new short[1]; 25 | arr[0] = 1; 26 | return arr[0] == 1; 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/ArrayTest.kls: -------------------------------------------------------------------------------- 1 | boolean newArray2D() { 2 | val arr = new int[1][2]; 3 | arr[0][1] = 6; 4 | return arr[0][1] == 6; 5 | } 6 | 7 | boolean newArray2D1() { 8 | val arr = new int[1][]; 9 | arr[0] = [0,1,2]; 10 | return arr[0][2] == 2; 11 | } 12 | 13 | boolean newArray3D() { 14 | val arr = new int[1][2][3]; 15 | arr[0][1][2] = 6; 16 | return arr[0][1][2] == 6; 17 | } 18 | 19 | boolean newArray3D1() { 20 | val arr = new int[1][][]; 21 | arr[0] = new int[2][]; 22 | arr[0][1] = new int[3]; 23 | arr[0][1][2] = 6; 24 | return arr[0][1][2] == 6; 25 | } 26 | 27 | boolean readArrayByInteger() { 28 | val idx = Integer.valueOf(1); 29 | val array = [2,3]; 30 | return array[idx] == 3; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/AsyncFileTest.kl: -------------------------------------------------------------------------------- 1 | import org.junit.Assert; 2 | 3 | class { 4 | 5 | private async Boolean doTestRead() { 6 | val file = new File("gradle/wrapper/gradle-wrapper.jar"); 7 | val fileLen = (int) file.length(); 8 | val bytes = file..readToBytes(); 9 | val buffer = new byte[4096]; 10 | val asyncReader = file..newAsyncReader(); 11 | var r = 0; 12 | var position = 0; 13 | var result = true; 14 | while ((r = await asyncReader.read(buffer)) > 0) { 15 | val arr1 = Arrays.copyOfRange(bytes, position, position + r); 16 | val arr2 = Arrays.copyOfRange(buffer, 0, r); 17 | result = result && Arrays.equals(arr1, arr2); 18 | //println("==> ${result} ${position}"); 19 | position += r; 20 | } 21 | return result && position == fileLen; 22 | } 23 | 24 | boolean testRead() { 25 | return AsyncThread.execute(async() -> await doTestRead()); 26 | } 27 | 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/AsyncTest.kl: -------------------------------------------------------------------------------- 1 | 2 | class { 3 | 4 | private async Integer getValue() { 5 | return 3; 6 | } 7 | 8 | private async Integer awaitValue() { 9 | return await getValue(); 10 | } 11 | 12 | private async Integer awaitSum() { 13 | val v1 = awaitValue(); 14 | val v2 = awaitValue(); 15 | return (await v1) + (await v2); 16 | } 17 | 18 | private async Integer throwError() { 19 | throw new Exception("exception in async method"); 20 | } 21 | 22 | private async Integer catchError() { 23 | try { 24 | await this.throwError(); 25 | return 1; 26 | } catch (Exception ex) { 27 | return 6; 28 | } 29 | } 30 | 31 | 32 | boolean test() { 33 | return AsyncThread.execute(() -> awaitSum()).equals(6); 34 | } 35 | 36 | boolean testEx() { 37 | try { 38 | AsyncThread.execute(() -> throwError()); 39 | return false; 40 | } catch (Throwable ex) { 41 | return ex.getMessage() == "exception in async method"; 42 | } 43 | } 44 | 45 | boolean testCatch() { 46 | return AsyncThread.execute(() -> catchError()).equals(6); 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/AutoCast.kls: -------------------------------------------------------------------------------- 1 | boolean bytePlusByte() { 2 | byte b1 = 127; 3 | byte b2 = 10; 4 | return b1 + b2 == 137; 5 | } 6 | 7 | boolean shortPlusShort() { 8 | short s1 = 32767; 9 | short s2 = 100; 10 | return s1 + s2 == 32867; 11 | } 12 | 13 | boolean integer2int() { 14 | val i as Object = 123; 15 | var j = 456; 16 | j = (Integer) i; 17 | return j == 123; 18 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/BitOperator.kls: -------------------------------------------------------------------------------- 1 | int unsignedRightShift() { 2 | return 0xCFFFFFFF>>>29; 3 | } 4 | 5 | int signedRightShift() { 6 | return (0xCFFFFFFF>>29) + 8; 7 | } 8 | 9 | boolean longLeftShift() { 10 | val x = 6L; 11 | return x << 1 == 12; 12 | } 13 | 14 | boolean byteLeftShift() { 15 | byte b = 1; 16 | return (b << 10) == 1024; 17 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/CollectionMixin.kls: -------------------------------------------------------------------------------- 1 | boolean testSumInt() { 2 | return [1,2,3]..asList()..sumInt() == 6; 3 | } 4 | 5 | boolean testSumLong() { 6 | return [1L,2L,3L]..asList()..sumLong() == 6L; 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/Compare.kls: -------------------------------------------------------------------------------- 1 | int charCompareToInt() { 2 | return 'y' == 1 ? 0 : 6; 3 | } 4 | 5 | int charCompareToChar() { 6 | return 'y' == 'x' ? 0 : 6; 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/CompoundAssign.kl: -------------------------------------------------------------------------------- 1 | class { 2 | private int index = 0; 3 | 4 | private int[] getBuff(int[] buff) { 5 | index ++ ; 6 | return buff; 7 | } 8 | 9 | boolean compoundPlusAssignOfCalculatedArray() { 10 | int[] buff = new int[5]; 11 | getBuff(buff)[index++] += index ++; 12 | getBuff(buff)[index++] += index ++; 13 | return Arrays.equals([0, 2, 0, 0, 5], buff); 14 | } 15 | 16 | boolean compoundPlusAssign() { 17 | var arr = new int[2]; 18 | var i = 0; 19 | arr[i++] += i++; 20 | return Arrays.equals([1, 0], arr) && i == 2; 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/ConstTest.kls: -------------------------------------------------------------------------------- 1 | int classConst(){ 2 | return String.class.getSimpleName().length(); 3 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/DefaultParam.kls: -------------------------------------------------------------------------------- 1 | int methodWithDefParam(int value = 5) { 2 | return value + 1; 3 | } 4 | 5 | boolean testMethodWithDefParam2() { 6 | return test("test") == 5; 7 | } 8 | 9 | boolean testMethodWithDefParam2Full() { 10 | return test("test", 3) == 3; 11 | } 12 | 13 | private static int test(String str, int len = 5) { 14 | return len; 15 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/DefaultStaticImport.kls: -------------------------------------------------------------------------------- 1 | int testPluginFind() { 2 | var list = [3,4,5,6]; 3 | return list..find(it => it == 5) + 1; 4 | } 5 | 6 | int testMap() { 7 | var lens = [123456]..asList()..map(it => String.valueOf(it)); 8 | return lens.get(0).length(); 9 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/DestructingVariablesDecl.kls: -------------------------------------------------------------------------------- 1 | boolean objDestructuring() { 2 | val {length,bytes} = "ABCD"; 3 | return length == 4 && Arrays.equals("ABCD".getBytes(), bytes); 4 | } 5 | 6 | boolean arrayDestructuring() { 7 | val [a,b] = [2,3]; 8 | return a == 2 && b == 3; 9 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/FieldAccess.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | private int value = 3; 4 | 5 | int test() { 6 | val cb as &Integer() = () => { 7 | value += 3; 8 | return value; 9 | }; 10 | return cb(); 11 | } 12 | 13 | boolean usingStrAsName() { 14 | return this."value" == 3; 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/FieldAssign.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | private int index = 0; 4 | 5 | private int value = 0; 6 | 7 | private long longValue = 1; 8 | 9 | boolean run() { 10 | value = 0; 11 | index = 0; 12 | getObj().value = index ++; 13 | return value == 1 && index == 2; 14 | } 15 | 16 | boolean compoundAssign() { 17 | value = 1; 18 | index = 1; 19 | getObj().value += index++ ; 20 | return value == 3 && index == 3; 21 | } 22 | 23 | boolean fieldIncr() { 24 | value = 1; 25 | index = 1; 26 | getObj().value ++ ; 27 | return index == 2 && value == 2; 28 | } 29 | 30 | boolean testAutoCast(){ 31 | return longValue == 1L; 32 | } 33 | 34 | private FieldAssign getObj() { 35 | index ++ ; 36 | return this; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/FieldInitialization.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | private int value = this.getInt(); 4 | 5 | int test() { 6 | return value; 7 | } 8 | 9 | private int getInt() { 10 | return 6; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/FieldOperator.kl: -------------------------------------------------------------------------------- 1 | import test.kalang.compiler.automation.SnippetsTest as ST; 2 | class { 3 | 4 | static class InnerClass{ 5 | int field = 6; 6 | } 7 | 8 | int myField = 6; 9 | 10 | static int myStaticField = 6; 11 | 12 | int dynamicField(){ 13 | val that as Object = new ST(); 14 | that->>testField = 6; 15 | return (Integer)that->>testField; 16 | } 17 | 18 | int fieldTest(){ 19 | return myField; 20 | } 21 | 22 | int fieldStaticTest(){ 23 | return myStaticField; 24 | } 25 | 26 | int fieldGetterTest(){ 27 | return this.getMyField(); 28 | } 29 | 30 | int innerFieldTest(){ 31 | return new InnerClass().getField(); 32 | } 33 | 34 | int iteratingField() { 35 | val arr = [new ST(), new ST()]; 36 | val fields = arr*.testField; 37 | return ( fields[0] + fields[1] ) + 4 ; 38 | } 39 | 40 | int iteratingDynamicField() { 41 | val arr = [new ST(), new ST()]; 42 | val fields = arr*->>testField; 43 | return ( (Integer)fields[0] + (Integer)fields[1] ) + 4 ; 44 | } 45 | 46 | boolean safeFieldNav() { 47 | val st as ST? = null; 48 | return st?.testField == 0; 49 | } 50 | 51 | int safeDynamicNav() { 52 | val st as ST? = null; 53 | return st?->>testField == null ? 6 : 1; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/ForIn.kls: -------------------------------------------------------------------------------- 1 | boolean forInArray(){ 2 | var arr = [4,5,6]; 3 | int ret = 0; 4 | for(a in arr){ 5 | ret = a; 6 | a = 0; 7 | } 8 | return ret == 6 && Arrays.equals([4,5,6], arr); 9 | } 10 | 11 | int forInArrayKey(){ 12 | int ret = 0; 13 | for(v,i in [4,5,6,7]){ 14 | ret += i; 15 | } 16 | return ret; 17 | } 18 | 19 | int forInList(){ 20 | var arr = new ArrayList(3); 21 | arr.add(1); 22 | arr.add(2); 23 | arr.add(3); 24 | int ret = 0; 25 | for(a,i in arr){ 26 | ret += a + i; 27 | } 28 | return ret - 3; 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/ForceCast.kls: -------------------------------------------------------------------------------- 1 | boolean castNull() { 2 | val obj = (String?) null; 3 | return obj == null; 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/Foreach.kls: -------------------------------------------------------------------------------- 1 | boolean foreachArray(){ 2 | var arr = [4,5,6]; 3 | int ret = 0; 4 | foreach(arr as a){ 5 | ret = a; 6 | a = 0; 7 | } 8 | return ret == 6 && Arrays.equals([4,5,6], arr); 9 | } 10 | 11 | int foreachArrayKey(){ 12 | int ret = 0; 13 | foreach([4,5,6,7] as i,v){ 14 | ret += i; 15 | } 16 | return ret; 17 | } 18 | 19 | int foreachList(){ 20 | var arr = new ArrayList(3); 21 | arr.add(1); 22 | arr.add(2); 23 | arr.add(3); 24 | int ret = 0; 25 | foreach(arr as i,a){ 26 | ret += a + i; 27 | } 28 | return ret - 3; 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/GeneratorTest.kls: -------------------------------------------------------------------------------- 1 | private static *Integer staticGenerator() { 2 | int counter = 0; 3 | for (int i = 0; i < 6; i++) { 4 | yield counter++; 5 | } 6 | return counter; 7 | } 8 | 9 | private *Integer nonStaticGenerator() { 10 | int counter = 0; 11 | for (int i = 0; i < 6; i++) { 12 | yield counter++; 13 | } 14 | return counter; 15 | } 16 | 17 | private boolean testGenerator(Generator gn) { 18 | var c = 0; 19 | for (int i = 0; i < 7; i++) { 20 | c += gn.next() == i ? 1 : 0; 21 | } 22 | return c == 7 && gn.isDone(); 23 | } 24 | 25 | boolean testStatic() { 26 | return testGenerator(staticGenerator()); 27 | } 28 | 29 | boolean testNonStatic() { 30 | return testGenerator(nonStaticGenerator()); 31 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/GenericConstructor.kls: -------------------------------------------------------------------------------- 1 | boolean test() { 2 | val ref = new Ref(true); 3 | return ref.get(); 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/GenericMapTest.kls: -------------------------------------------------------------------------------- 1 | boolean testEmptyMap() { 2 | return newEmptyMap().isEmpty(); 3 | } 4 | 5 | protected Map newEmptyMap() { 6 | return Collections.emptyMap(); 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/GenericMethod.kls: -------------------------------------------------------------------------------- 1 | protected Map newMap(K key, V value) { 2 | val map = new HashMap(); 3 | map.put(key, value); 4 | return map; 5 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/GenericTypeCast.kls: -------------------------------------------------------------------------------- 1 | protected void test() { 2 | List list = Collections.emptyList(); 3 | } 4 | 5 | protected void testMap() { 6 | Map map = new HashMap<>(); 7 | } 8 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/HashTest.kls: -------------------------------------------------------------------------------- 1 | import algorithm.Md5; 2 | import algorithm.Sha1; 3 | 4 | boolean testMd5() { 5 | var str = ""; 6 | for (var i = 0; i < 1024; i++) { 7 | if (Md5.md5AsHex(str.getBytes("utf-8")) != str.md5Hex()) { 8 | println("test failed,str=${str}"); 9 | return false; 10 | } 11 | str = str + String.valueOf((char)i); 12 | } 13 | return true; 14 | } 15 | 16 | boolean testSha1() { 17 | var str = ""; 18 | for (var i = 0; i < 1024; i++) { 19 | val hex1 = Sha1.sha1AsHex(str.getBytes("utf-8")); 20 | val hex2 = str.sha1Hex(); 21 | if ( hex1 != hex2) { 22 | println("test failed,i=${i},hex1=${hex1},hex2=${hex2},str=${str}"); 23 | return false; 24 | } 25 | str = str + String.valueOf((char)i); 26 | } 27 | return true; 28 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/HelloScript.kls: -------------------------------------------------------------------------------- 1 | int scriptMethod(){ 2 | return 6; 3 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/IfStmt.kls: -------------------------------------------------------------------------------- 1 | int ifNotBoolean() { 2 | val b = Boolean.valueOf(false); 3 | if (!b) { 4 | return 6; 5 | } 6 | return 1; 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/ImportStat.kls: -------------------------------------------------------------------------------- 1 | import java.util.Map.Entry; 2 | 3 | protected void test() { 4 | val map = new HashMap(); 5 | Set> entries = map.entrySet(); 6 | Set es = entries; 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/IncrAndDecrOperator.kls: -------------------------------------------------------------------------------- 1 | int incrementExpr() { 2 | int i=6; 3 | return i++; 4 | } 5 | 6 | int incrementExpr2() { 7 | int i=5; 8 | return ++i; 9 | } 10 | 11 | int decrementExpr() { 12 | int i = 7; 13 | return --i; 14 | } 15 | 16 | int decrementExpr2() { 17 | int i = 6; 18 | return i--; 19 | } 20 | 21 | int incrValue() { 22 | var i = 1; 23 | var sum = 0; 24 | sum += i++; 25 | sum += i++; 26 | sum += i++; 27 | return sum; 28 | } 29 | 30 | int decrValue() { 31 | var i = 3; 32 | var sum = 0; 33 | sum += i--; 34 | sum += i--; 35 | sum += i--; 36 | return sum; 37 | } 38 | 39 | boolean incrIndex() { 40 | var buff = new int[3]; 41 | var i = 0; 42 | buff[i++] = 0; 43 | buff[i++] = 1; 44 | buff[i++] = 2; 45 | return i == 3; 46 | } 47 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/Initialization.kls: -------------------------------------------------------------------------------- 1 | boolean initializeInIfStmt() { 2 | var text as String; 3 | val num = 2; 4 | if (num == 0) { 5 | text = "zero"; 6 | } else { 7 | text = "noneZero"; 8 | } 9 | return text == "noneZero"; 10 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/InnerClasses.kls: -------------------------------------------------------------------------------- 1 | int testCallB(){ 2 | return new A().callB(); 3 | } 4 | 5 | int testCallSelf(){ 6 | return new A().callSelf(); 7 | } 8 | 9 | 10 | static class A { 11 | //TODO to support calling private constructor from inner class 12 | //private constructor() {} 13 | int callB() { 14 | return new B().run(); 15 | } 16 | int callSelf(){ 17 | return new A().run(); 18 | } 19 | private int run() { 20 | return 6; 21 | } 22 | } 23 | 24 | static class B { 25 | int run() { 26 | return 6; 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/InstanceOfTest.kl: -------------------------------------------------------------------------------- 1 | class { 2 | private int length(Object obj) { 3 | if (obj instanceof String) { 4 | return obj.length(); 5 | } 6 | return 0; 7 | } 8 | 9 | private boolean testInIfCondition(Object obj, int length) { 10 | if (obj instanceof String && obj.length() == length) { 11 | return true; 12 | } 13 | return false; 14 | } 15 | 16 | boolean test() { 17 | return length("test") == 4 && testInIfCondition("test", 4); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/InterfaceField.kls: -------------------------------------------------------------------------------- 1 | interface MyInterface { 2 | String NAME = new String("MyInterface"); 3 | } 4 | 5 | boolean test() { 6 | return "MyInterface" == MyInterface.NAME; 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/InvokeMember.kls: -------------------------------------------------------------------------------- 1 | private static String test() { 2 | return "test-method"; 3 | } 4 | 5 | boolean callPrivateStatic() { 6 | return test() == "test-method"; 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/InvokeMostPrecise.kls: -------------------------------------------------------------------------------- 1 | boolean invoke() { 2 | return test("test") == "test1"; 3 | } 4 | 5 | private String test(Object value) { 6 | return "test1"; 7 | } 8 | 9 | private String test(Object... value) { 10 | return "test2"; 11 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/InvokeStatic.kls: -------------------------------------------------------------------------------- 1 | boolean invokeStatic() { 2 | return Class.forName("java.lang.String") === String.class; 3 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/LiteralExpr.kls: -------------------------------------------------------------------------------- 1 | boolean classLiteral() { 2 | val str = String.class.newInstance(); 3 | return str.length() == 0; 4 | } 5 | 6 | boolean primitiveClassLiteral() { 7 | return int.class.isPrimitive(); 8 | } 9 | 10 | boolean primitiveArrayClassLiteral() { 11 | return int[].class == new int[0].getClass(); 12 | } 13 | 14 | boolean arrayClassLiteral() { 15 | return String[].class == new String[0].getClass(); 16 | } 17 | 18 | boolean intLiteral() { 19 | return 100_000 == 100000; 20 | } 21 | 22 | boolean longLiteral() { 23 | return 100_000L == 100000L; 24 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/MapMixin.kls: -------------------------------------------------------------------------------- 1 | boolean testExclude() { 2 | val map = ["a":1,"b":2]; 3 | return map..exclude("a") == ["b": 2] && map..exclude("b") == ["a" : 1]; 4 | } 5 | 6 | boolean testOnly() { 7 | val map = ["a":1,"b":2]; 8 | return map..only("b") == ["b": 2] && map..only("a") == ["a" : 1]; 9 | } 10 | 11 | boolean testUnion() { 12 | return ["a":1,"b":2] == ["a" : 1]..union(["b":2]); 13 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/MapTest.kls: -------------------------------------------------------------------------------- 1 | int mapExpr(){ 2 | var map = ["a":"a","b":"ab","c":"abc"]; 3 | return map.get("b").length()+4; 4 | } 5 | 6 | int primitiveMapExpr(){ 7 | var map = [1:5,2:6]; 8 | return map.get(2); 9 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/MethodRef.kls: -------------------------------------------------------------------------------- 1 | boolean typeMethodRef() { 2 | val list = [new Date(1), new Date(2), new Date(3)]..asList(); 3 | return list..map(Date::getTime) == [1,2,3]..asList(); 4 | } 5 | 6 | boolean objectMethodRef() { 7 | val list = ["1","2"].asList(); 8 | val testStr = "1"; 9 | return list..map(testStr::equals) == [true,false]..asList(); 10 | } 11 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/MethodSelect.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | interface HelloOne { 4 | String hello(String world); 5 | } 6 | 7 | interface HelloTwo { 8 | String hello(String prefix, String world); 9 | } 10 | 11 | static class Hello { 12 | 13 | String say(HelloOne one) { 14 | return one.hello("hello"); 15 | } 16 | 17 | String say(HelloTwo two) { 18 | return two.hello("hello", "world"); 19 | } 20 | 21 | } 22 | 23 | boolean test() { 24 | val hello = new Hello(); 25 | val one = hello.say( (p) => p ); 26 | val two = hello.say( (p1,p2) => p1 + "," + p2 ); 27 | return one == "hello" && two == "hello,world"; 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/NewExpr.kls: -------------------------------------------------------------------------------- 1 | static class Person { 2 | String id; 3 | String name; 4 | Integer age; 5 | } 6 | 7 | boolean structuringNew() { 8 | val p = new Person({ 9 | id: "p1", 10 | name: "test", 11 | age: 18, 12 | }); 13 | return p.getId() == "p1" && p.getName() == "test" && p.getAge() == 18; 14 | } 15 | 16 | boolean structuringNew2() { 17 | val name = "test"; 18 | val age = 18; 19 | val p = new Person({name, age}); 20 | return p.getName() == "test" && p.getAge() == 18; 21 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/NullCheck.kls: -------------------------------------------------------------------------------- 1 | int andExprCheck() { 2 | val s as String? = "test"; 3 | if(s!=null && !s.isEmpty()) { 4 | return 6; 5 | } 6 | return 1; 7 | } 8 | 9 | boolean continueCheck() { 10 | for (var i = 0; i < 1; i++) { 11 | val s = getNull(); 12 | if (s == null) { 13 | continue; 14 | } 15 | return s.length() == 1; 16 | } 17 | return true; 18 | } 19 | 20 | boolean overrideCheck() { 21 | var name as String? = null; 22 | name = "test"; 23 | return name.length() == 4; 24 | } 25 | 26 | private String? getNull() { 27 | return null; 28 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/NullDefaultExpr.kl: -------------------------------------------------------------------------------- 1 | class { 2 | private int counter = 0; 3 | 4 | boolean nullDefault() { 5 | counter = 0; 6 | val s as String? = null; 7 | return ( s ?? getDefault()).toString() == "test" && counter == 1; 8 | } 9 | 10 | boolean nullDefaultForNonnullExpr() { 11 | counter = 0; 12 | val s as String? = "hello"; 13 | return ( s ?? getDefault() ).toString() == "hello" && counter == 0; 14 | } 15 | 16 | private String getDefault() { 17 | counter++; 18 | return "test"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/Operator.kls: -------------------------------------------------------------------------------- 1 | int equalsObject(){ 2 | var fa = new File("a"); 3 | var fb = new File("a"); 4 | return fa == fb ? 6 : 1; 5 | } 6 | 7 | int sameObject() { 8 | var fa = new File("a"); 9 | var fb = new File("a"); 10 | return fa === fb ? 1 : 6; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/PrimitiveCast.kls: -------------------------------------------------------------------------------- 1 | boolean l2b() { 2 | val l = 0x6L; 3 | val b as byte = (byte) l; 4 | return b == 6; 5 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/PrivateConstructor.kl: -------------------------------------------------------------------------------- 1 | import model.ClassA; 2 | class { 3 | 4 | boolean test() { 5 | return ClassA.getInstance() != null; 6 | } 7 | 8 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/PropertyAccess.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | private static class MyObject { 4 | String name; 5 | } 6 | 7 | boolean setAndGet() { 8 | val mo = new MyObject(); 9 | mo.name = "test"; 10 | return "test" == mo.name && "test" == mo.getName(); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/QuestionExpr.kls: -------------------------------------------------------------------------------- 1 | boolean testQuestion() { 2 | val v1 = true ? 2 : 20; 3 | val v2 = false ? 5 : 50; 4 | return v1 + v2 == 52; 5 | } 6 | 7 | boolean testQuestion2() { 8 | val v = true ? 1 : 2L; 9 | return v == 1L; 10 | } 11 | 12 | Boolean? nullableReturn() { 13 | return true ? true : null; 14 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/StringLiteral.kls: -------------------------------------------------------------------------------- 1 | boolean testUnicode() { 2 | return "\u4f60\u597d" == "你好"; 3 | } 4 | 5 | boolean test() { 6 | return "$".charAt(0) == 36; 7 | } 8 | 9 | boolean testSlashEnd() { 10 | return "a\\".length() == 2; 11 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/TryWithResource.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | static class CloseableObj implements Closeable { 4 | Ref closed; 5 | constructor(Ref closed) { 6 | this.closed = closed; 7 | } 8 | override void close() { 9 | closed.set(true); 10 | } 11 | } 12 | 13 | boolean test() { 14 | var closedInBody = true; 15 | val closed = new Ref(); 16 | try (val co = new CloseableObj(closed)) { 17 | closed.set(false); 18 | closedInBody = closed.get(); 19 | } 20 | return closedInBody == false && closed.get() == true; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/UsingAnnotation.kl: -------------------------------------------------------------------------------- 1 | import javax.annotation.Resource; 2 | 3 | @Resource(name = "test") 4 | class { 5 | 6 | boolean test() { 7 | val r = this.getClass().getAnnotation(Resource.class); 8 | return "test".equals(r.name()); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/Varargs.kls: -------------------------------------------------------------------------------- 1 | boolean varargs() { 2 | return Arrays.asList(1,2,3) == [1,2,3].asList(); 3 | } 4 | 5 | boolean testTypeInference() { 6 | return Arrays.asList("a","ab")..map(it => it.length()) == Arrays.asList(1,2); 7 | } 8 | 9 | boolean testDeclaration() { 10 | return integerList(1,2) == Arrays.asList(1,2); 11 | } 12 | 13 | private List integerList(Integer... args) { 14 | return Arrays.asList(args); 15 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/WithExpr.kls: -------------------------------------------------------------------------------- 1 | boolean withExpr() { 2 | val arr = with(new byte[8]) { 3 | writeIntB(0,0x1234); 4 | writeIntB(4,length); 5 | }; 6 | return arr.readIntB(0) == 0x1234 && arr.readIntB(4) == arr.length; 7 | } 8 | 9 | int withInClosure() { 10 | val num = 6; 11 | val cb as &int[]() = () => { 12 | return with(new int[1]) { 13 | this[0] = num; 14 | }; 15 | }; 16 | return cb()[0]; 17 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/automation/model/ClassA.kl: -------------------------------------------------------------------------------- 1 | class { 2 | 3 | private constructor(String param) {} 4 | 5 | static ClassA getInstance() { 6 | return new ClassA("test"); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/AbstractMethodCheck.kl: -------------------------------------------------------------------------------- 1 | please override abstract method public abstract java.util.Set> entrySet() in java.util.AbstractMap@1 2 | class extends AbstractMap { 3 | 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/AssignCheck.kls: -------------------------------------------------------------------------------- 1 | java.lang.Object cannot be converted to int@2 2 | val iObj as Object = 1; 3 | val i as int = iObj; -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/AssignFinalField.kl: -------------------------------------------------------------------------------- 1 | cannot assign a value to final variable value@5 2 | class { 3 | private final int value = 1; 4 | 5 | constructor() { 6 | value = 2; 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/BreakError.kls: -------------------------------------------------------------------------------- 1 | break outside of loop@2 2 | void test() { 3 | break; 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/ContinueError.kls: -------------------------------------------------------------------------------- 1 | continue outside of loop@2 2 | void test() { 3 | continue; 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/DefaultParamCheck.kls: -------------------------------------------------------------------------------- 1 | missing default value for parameter lastParam@1 2 | int methodWithDefParam(int value = 5, String lastParam) { 3 | return value + 1; 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/ExtraneousToken.kls: -------------------------------------------------------------------------------- 1 | extraneous input 'package'@1 2 | package myname; -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/GenericInferConflict.kls: -------------------------------------------------------------------------------- 1 | method not found:kalang.mixin.CollectionMixin.at(java.util.List,int,java.lang.String)@1 2 | val list = [1,2]..asList()..at(9 , ""); -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/GenericInferNullable.kls: -------------------------------------------------------------------------------- 1 | expression may be null@2 2 | val list = [1,2]..asList()..at(9 , null); 3 | println(list.intValue()); -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/GenericTypeInferring.kls: -------------------------------------------------------------------------------- 1 | java.util.Map cannot be converted to java.util.Map@4 2 | protected Map newMap() { 3 | return new HashMap<>(); 4 | } 5 | Map map = newMap(); -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/InitializationCheck.kls: -------------------------------------------------------------------------------- 1 | num is uninitialized!@5 2 | int num; 3 | if ( "".equals(1) ) { 4 | num = 1; 5 | } 6 | num++; -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/LambdaInitError.kls: -------------------------------------------------------------------------------- 1 | lambda type is not specified@1 2 | val cb = () => { 3 | println("test"); 4 | }; -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/LambdaParamNameConflict.kls: -------------------------------------------------------------------------------- 1 | 'it' is defined in the scope@3 2 | val list = [1]..asList()..map(it => 3 | it..cast( 4 | it => it 5 | ) 6 | ); -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/OverrideCheck.kl: -------------------------------------------------------------------------------- 1 | method OverrideCheck.myNewMethod() does not override or implement a method from a supertype@2 2 | class { 3 | override void myNewMethod() {} 4 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/OverrideReturnTypeCheck.kls: -------------------------------------------------------------------------------- 1 | incompatible return type@1 2 | override Object toString() { 3 | return ""; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/ParamNameRepeat.kls: -------------------------------------------------------------------------------- 1 | 'name' is defined in the scope@3 2 | void test( 3 | String name, 4 | String name 5 | ) { 6 | 7 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/error/UnreachableCheck.kls: -------------------------------------------------------------------------------- 1 | unreachable statement@7 2 | String test(boolean c) { 3 | if (c) { 4 | return "true"; 5 | } else { 6 | return "false"; 7 | } 8 | return "null"; 9 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/EnumTest.kls: -------------------------------------------------------------------------------- 1 | import java.lang.annotation.RetentionPolicy; 2 | var p = RetentionPolicy.SOURCE; 3 | System.out.print(p.name()); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/GenericAssignTest.kls: -------------------------------------------------------------------------------- 1 | List list = new ArrayList(); 2 | List list1 = new ArrayList(); 3 | List list2 = new ArrayList(); 4 | List arrList = new ArrayList(); 5 | List objList = new ArrayList(); 6 | //-list = list1; 7 | //-list = list2; 8 | list1 = list; 9 | list2 = list; 10 | //-list1 = arrList; 11 | list1 = objList; 12 | list1.add(new ArrayList()); 13 | list2 = arrList; -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/GenericMapTest.kls: -------------------------------------------------------------------------------- 1 | var list = new ArrayList(); 2 | var map = new HashMap>(); 3 | map.put("test",list); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/GenericMethodTest.kls: -------------------------------------------------------------------------------- 1 | List list = Collections.singletonList("test"); 2 | list.add("hello"); 3 | String item = list.get(0); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/Implementation.kl: -------------------------------------------------------------------------------- 1 | import kalang.type.Function1; 2 | class implements Function1 { 3 | 4 | override String call(String value) { 5 | return value; 6 | } 7 | 8 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/InitializationCheck.kls: -------------------------------------------------------------------------------- 1 | String str; 2 | try { 3 | str = "hello"; 4 | } catch (Exception ex) { 5 | System.err.println(ex.getMessage()); 6 | return -1; 7 | } 8 | println(str); 9 | 10 | 11 | String name; 12 | if (true) { 13 | return -1; 14 | }else{ 15 | name = "hello"; 16 | } 17 | println(name); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/InnerClassInClass.kl: -------------------------------------------------------------------------------- 1 | class{ 2 | 3 | String name = "test"; 4 | 5 | class InnerClass{ 6 | public String getName(){ 7 | return name; 8 | } 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/InnerClassInScript.kls: -------------------------------------------------------------------------------- 1 | class Inner{ 2 | class InnerInInner{ 3 | public String helloInnerInInner(){ 4 | return "InnerInInner"; 5 | } 6 | } 7 | public String hello(){ 8 | return "Inner"; 9 | } 10 | } 11 | 12 | //TODO test inner class 13 | //var ic = new Inner(); 14 | //ic.hello(); 15 | //var icInIc = new Inner$InnerInInner(); 16 | //icInIc.helloInnerInInner(); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/InterfaceCallTest.kls: -------------------------------------------------------------------------------- 1 | List list = new ArrayList(); 2 | list.toString(); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/InterfaceTest.kl: -------------------------------------------------------------------------------- 1 | interface { 2 | 3 | void run(); 4 | 5 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/Interpolation.kls: -------------------------------------------------------------------------------- 1 | var name = "kalang"; 2 | var nameOnly = "${name}"; 3 | var nameFirst = "${name}!"; 4 | var nameLast = "hello,${name}"; 5 | var nameMid = "hello,${name}!"; 6 | var pathWin = "src\\${name}\\runtime"; 7 | var pathUnix = "src/${name}/runtime"; -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/LambdaTest.kls: -------------------------------------------------------------------------------- 1 | void voidTypeTest() { 2 | val cb as &Void() = () => { 3 | println("test"); 4 | return null; 5 | }; 6 | cb(); 7 | } 8 | 9 | void voidTypeTest2() { 10 | val cb as &Void() = () => { 11 | println("test"); 12 | return; 13 | }; 14 | cb(); 15 | } 16 | 17 | void consumerTest() { 18 | val list = Arrays.asList([1,2,3]); 19 | list.forEach(it => println(it)); 20 | } 21 | 22 | void mapConsumerTest() { 23 | val map = ["a":1,"b":2]; 24 | map.forEach(k => println(k)); 25 | map.forEach((k,v) => {println(k);println(v);}); 26 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/MapExpr.kls: -------------------------------------------------------------------------------- 1 | var objectMap = ["name":"kalang","year":2016];//Map 2 | var stringMap = ["name":"kalang","type":"language"];//Map 3 | var ov = objectMap.get("name");//ov is Object type 4 | var sv = stringMap.get("name");//sv is String type -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/Math.kls: -------------------------------------------------------------------------------- 1 | int i = 1; 2 | long l = 2; 3 | var s = i + l; 4 | 5 | float f = 1.0f; 6 | double d = 2.0; 7 | var ds = f+d; -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/MethodSelectionTest.kls: -------------------------------------------------------------------------------- 1 | Integer i = Integer.valueOf(1); 2 | System.out.println(i); 3 | println(i); 4 | 5 | byte b = 6; 6 | System.out.print(b); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/NewFullNameClassTest.kls: -------------------------------------------------------------------------------- 1 | var file = new java.io.File("."); 2 | println(file); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/NullCheckTest.kls: -------------------------------------------------------------------------------- 1 | String? name = null; 2 | String value = name==null ? "" : name.toString(); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/OverrideTest.kl: -------------------------------------------------------------------------------- 1 | import java.util.function.Consumer; 2 | class implements Iterator{ 3 | override public boolean hasNext(){ 4 | throw new UnsupportedOperationException(); 5 | } 6 | 7 | override public void forEachRemaining(Consumer arg0){ 8 | throw new UnsupportedOperationException(); 9 | } 10 | override public String next(){ 11 | throw new UnsupportedOperationException(); 12 | } 13 | override public void remove(){ 14 | throw new UnsupportedOperationException(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/StringExpr.kls: -------------------------------------------------------------------------------- 1 | var name = "b"; 2 | println("a" + name + this.toString()); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/SuperCall.kls: -------------------------------------------------------------------------------- 1 | class SuperCall{ 2 | constructor(){ 3 | super(); 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/innerClass/Main.kls: -------------------------------------------------------------------------------- 1 | static class MyType implements Model$Type { 2 | 3 | } 4 | var type = new MyType(); 5 | println(type); -------------------------------------------------------------------------------- /src/test/kalang-snippets/examples/innerClass/Model.kl: -------------------------------------------------------------------------------- 1 | class { 2 | interface Type { 3 | 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/kalang-snippets/projects/colorful-console/App.kls: -------------------------------------------------------------------------------- 1 | import org.fusesource.jansi.AnsiConsole; 2 | import org.fusesource.jansi.Ansi; 3 | 4 | println(Ansi.ansi().fg(Ansi$Color.YELLOW).a("hello")); -------------------------------------------------------------------------------- /src/test/kalang-snippets/projects/colorful-console/jansi-1.14.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kasonyang/kalang/d3ceaadf25342147cb47109dda3dd4faccc1be37/src/test/kalang-snippets/projects/colorful-console/jansi-1.14.jar -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | {{DATE}}.{{TIME}}.0 --------------------------------------------------------------------------------