| | 438 | |
|---|
| | 439 | public static Iterable<? extends StaticError> analyze(FortressRepository _repository, |
|---|
| | 440 | GlobalEnvironment env, |
|---|
| | 441 | Iterable<Api> apis, |
|---|
| | 442 | Iterable<Component> components, |
|---|
| | 443 | long lastModified) { |
|---|
| | 444 | String phase = ""; |
|---|
| | 445 | |
|---|
| | 446 | // Build ApiIndices before disambiguating to allow circular references. |
|---|
| | 447 | // An IndexBuilder.ApiResult contains a map of strings (names) to |
|---|
| | 448 | // ApiIndices. |
|---|
| | 449 | IndexBuilder.ApiResult rawApiIR = IndexBuilder.buildApis(apis, lastModified); |
|---|
| | 450 | if (!rawApiIR.isSuccessful()) { return rawApiIR.errors(); } |
|---|
| | 451 | |
|---|
| | 452 | // Build ComponentIndices before disambiguating to allow circular references. |
|---|
| | 453 | // An IndexBuilder.ComponentResult contains a map of strings (names) to |
|---|
| | 454 | // ComponentIndices. |
|---|
| | 455 | IndexBuilder.ComponentResult rawComponentIR = |
|---|
| | 456 | IndexBuilder.buildComponents(components, lastModified); |
|---|
| | 457 | if (!rawComponentIR.isSuccessful()) { return rawComponentIR.errors(); } |
|---|
| | 458 | |
|---|
| | 459 | // Build a new GlobalEnvironment consisting of all APIs in a global |
|---|
| | 460 | // repository combined with all APIs that have been processed in the previous |
|---|
| | 461 | // step. For now, we are implementing pure static linking, so there is |
|---|
| | 462 | // no global repository. |
|---|
| | 463 | GlobalEnvironment rawApiEnv = |
|---|
| | 464 | new GlobalEnvironment.FromMap(CollectUtil.union(_repository.apis(), |
|---|
| | 465 | rawApiIR.apis())); |
|---|
| | 466 | |
|---|
| | 467 | // Rewrite all API ASTs so they include only fully qualified names, relying |
|---|
| | 468 | // on the rawApiEnv constructed in the previous step. Note that, after this |
|---|
| | 469 | // step, the rawApiEnv is stale and needs to be rebuilt with the new API ASTs. |
|---|
| | 470 | Disambiguator.ApiResult apiDR = |
|---|
| | 471 | Disambiguator.disambiguateApis(apis, rawApiEnv); |
|---|
| | 472 | if (!apiDR.isSuccessful()) { return apiDR.errors(); } |
|---|
| | 473 | |
|---|
| | 474 | Disambiguator.ComponentResult componentDR = |
|---|
| | 475 | Disambiguator.disambiguateComponents(components, env, |
|---|
| | 476 | rawComponentIR.components()); |
|---|
| | 477 | if (!componentDR.isSuccessful()) { return componentDR.errors(); } |
|---|
| | 478 | |
|---|
| | 479 | if (phase.equals("disambiguate")) |
|---|
| | 480 | return IterUtil.empty(); |
|---|
| | 481 | |
|---|
| | 482 | // Rebuild ApiIndices. |
|---|
| | 483 | IndexBuilder.ApiResult apiIR = |
|---|
| | 484 | IndexBuilder.buildApis(apiDR.apis(), System.currentTimeMillis()); |
|---|
| | 485 | if (!apiIR.isSuccessful()) { return apiIR.errors(); } |
|---|
| | 486 | |
|---|
| | 487 | // Rebuild ComponentIndices. |
|---|
| | 488 | IndexBuilder.ComponentResult componentIR = |
|---|
| | 489 | IndexBuilder.buildComponents(componentDR.components(), |
|---|
| | 490 | System.currentTimeMillis()); |
|---|
| | 491 | if (!componentIR.isSuccessful()) { return componentIR.errors(); } |
|---|
| | 492 | |
|---|
| | 493 | // Rebuild GlobalEnvironment. |
|---|
| | 494 | GlobalEnvironment apiEnv = |
|---|
| | 495 | new GlobalEnvironment.FromMap(CollectUtil.union(_repository.apis(), |
|---|
| | 496 | apiIR.apis())); |
|---|
| | 497 | |
|---|
| | 498 | // Rewrite grammars, see GrammarRewriter for more details. |
|---|
| | 499 | GrammarRewriter.ApiResult apiID = GrammarRewriter.rewriteApis(apiIR.apis(), apiEnv); |
|---|
| | 500 | if (!apiID.isSuccessful()) { return apiID.errors(); } |
|---|
| | 501 | |
|---|
| | 502 | // Rebuild ApiIndices. |
|---|
| | 503 | apiIR = IndexBuilder.buildApis(apiID.apis(), System.currentTimeMillis()); |
|---|
| | 504 | if (!apiIR.isSuccessful()) { return apiIR.errors(); } |
|---|
| | 505 | |
|---|
| | 506 | // Rebuild GlobalEnvironment. |
|---|
| | 507 | apiEnv = |
|---|
| | 508 | new GlobalEnvironment.FromMap(CollectUtil.union(_repository.apis(), |
|---|
| | 509 | apiIR.apis())); |
|---|
| | 510 | |
|---|
| | 511 | // Do all type checking and other static checks on APIs. |
|---|
| | 512 | StaticChecker.ApiResult apiSR = |
|---|
| | 513 | StaticChecker.checkApis(apiIR.apis(), apiEnv); |
|---|
| | 514 | if (!apiSR.isSuccessful()) { return apiSR.errors(); } |
|---|
| | 515 | |
|---|
| | 516 | StaticChecker.ComponentResult componentSR = |
|---|
| | 517 | StaticChecker.checkComponents(componentIR.components(), env); |
|---|
| | 518 | if (!componentSR.isSuccessful()) { return componentSR.errors(); } |
|---|
| | 519 | |
|---|
| | 520 | if (phase.equals("compile")) |
|---|
| | 521 | return IterUtil.empty(); |
|---|
| | 522 | |
|---|
| | 523 | Desugarer.ApiResult apiDSR = |
|---|
| | 524 | Desugarer.desugarApis(apiSR.apis(), apiEnv); |
|---|
| | 525 | |
|---|
| | 526 | // Generate top-level byte code environments |
|---|
| | 527 | TopLevelEnvGen.ComponentResult componentGR = |
|---|
| | 528 | TopLevelEnvGen.generate(componentSR.components(), env); |
|---|
| | 529 | if(!componentGR.isSuccessful()) { return componentGR.errors(); } |
|---|
| | 530 | |
|---|
| | 531 | // Generate code. Code is stored in the _repository object. |
|---|
| | 532 | // In an implementation with pure static linking, we would have to write |
|---|
| | 533 | // this code back out to a file. |
|---|
| | 534 | // In an implementation with fortresses, |
|---|
| | 535 | // we would write this code into the resident fortress. |
|---|
| | 536 | for (Map.Entry<APIName, ApiIndex> newApi : apiDSR.apis().entrySet()) { |
|---|
| | 537 | if ( compiledApi( newApi.getKey(), apis ) ){ |
|---|
| | 538 | Debug.debug( 2, "Analyzed api " + newApi.getKey() ); |
|---|
| | 539 | _repository.addApi(newApi.getKey(), newApi.getValue()); |
|---|
| | 540 | } |
|---|
| | 541 | } |
|---|
| | 542 | |
|---|
| | 543 | // Additional optimization phases can be inserted here |
|---|
| | 544 | |
|---|
| | 545 | for (Map.Entry<APIName, ComponentIndex> newComponent :componentSR.components().entrySet()) { |
|---|
| | 546 | _repository.addComponent(newComponent.getKey(), newComponent.getValue()); |
|---|
| | 547 | } |
|---|
| | 548 | |
|---|
| | 549 | Debug.debug( 2, "Done with analyzing apis " + apis + ", components " + components ); |
|---|
| | 550 | |
|---|
| | 551 | return IterUtil.empty(); |
|---|
| | 552 | } |
|---|
| | 553 | |
|---|
| | 554 | private static boolean compiledApi( APIName name, Iterable<Api> apis ){ |
|---|
| | 555 | for ( Api api : apis ){ |
|---|
| | 556 | if ( api.getName().equals(name) ){ |
|---|
| | 557 | return true; |
|---|
| | 558 | } |
|---|
| | 559 | } |
|---|
| | 560 | return false; |
|---|
| | 561 | } |
|---|